0%

犬种识别网页开发

前言

原来有一段犬种识别的代码, 在测试集上的准确率有91.63%, 可以识别133个犬的品种, 这里再套个壳子, 做成网页.

完成后的效果如图:

效果图0

效果图1

效果图2

效果图3

Github地址

不懂前端, 前端的很多东西都是现查先做的, Django懂一些但有些也要去查, 整个开发过程中碰到了一些问题, 在这里记录一下.

问题1 - Django的csrf验证和Bootstrap的Fileinput插件

参考了https://stackoverflow.com/questions/40457426/how-do-i-pass-csrf-token-with-this-file-upload, https://www.jianshu.com/p/a178f08d9389

关于Django的csrf验证的介绍在第二篇文章里有, 这里说明怎么添加到Fileinput插件中:

1
2
3
4
5
6
7
8
9
10
11
12
$("#input-1").fileinput({
allowedFileExtensions: ["jpg", "png", "bmp", "jpeg"],
uploadUrl: '{{ upload_img_url }}',
theme: 'fas',
uploadExtraData: {
'csrfmiddlewaretoken': '{{ csrf_token }}', //这里指定了csrf的token
'img_token': img_token
},
fileActionSettings: {
showZoom: false
}
});

通过在uploadExtraData中添加准确的键值对, 即可通过验证.

问题2 - 动态加载图片

参考自https://blog.csdn.net/Moelimoe/article/details/105010709

需要根据用户提供的图片, 返回预测的犬种的图片以及用户提供的图片.

  1. 在setting.py中设置需要返回的图片的根目录

MAIN_MEDIA_ROOT = os.path.join(BASE_DIR, 'static/main_media_root/')

  1. 在APP的urls.py中设置该目录为需要展示图片的页面的文档静态根目录

urlpatterns += static('/main/', document_root=MAIN_MEDIA_ROOT)

  1. 然后就可以在模板中使用
1
{{   }}

引用参数了

1
<img src="media/samples/{{ pred_class_name }}/0.jpg" class="img-thumbnail img-responsive">

问题3 - Django调用Keras

参考了https://github.com/keras-team/keras/issues/13353, https://blog.csdn.net/sinat_41657218/article/details/103730727#20200512__103, http://www.uxys.com/html/PythonDevelopment/20190911/99207.html, https://medium.com/@aoll.motion/integrate-deep-learning-with-keras-in-django-c49611fecb68

在拿到用户提供的图片, 用户点击开始识别后, 从views.py的视图函数调用recognize.py的识别函数时, 总是发生类似于'thread._local' object has no attribute 'value'或者ValueError: Tensor Tensor("Placeholder:0", shape=(3, 3, 1, 32), dtype=float32)的这两种错误.

最后采用的解决办法如下, 在recognize.py中:

1
2
3
model_path = os.path.join(BASE_DIR, 'resources/models/dogImages.augmentation.model.weights.best.1.hdf5')
model = load_model(model_path)
model.predict(np.zeros((1, 512, 512, 3)))

全局加载模型, 并在加载模型后, 立马进行一次预测, 然后就不报错了.

关于发生错误的具体原因, 在keras的一个issue下有解答:

解答0

解答1

以下是我的个人猜测:
django本身是单线程的, 但是在加载模型和进行预测时是多线程的, 于是会导致开启两个不同的session, 然后就出现错误了. 那么就要保持只有一个session, 同时照顾好global graph, 于是先全局加载模型和预测一次, 这样后面再进行预测的时候就不会出错了.

问题4 - 图片缓存刷新

在返回用户上传了的图片时, 有时会发现展示的图片并没有变, 一开始以为是视图函数写错了, 后来发现是因为浏览器缓存的缘故, 因为点进去图片的链接后, 确实是本应该展示的图片.

解决办法: 给图片的链接加一个时间戳的参数, 然后浏览器每次就会刷新缓存了.

1
2
3
4
<img src="" class="img-thumbnail img-responsive" id="your_img">
<script>
$("#your_img").attr('src', 'media/upload_img/{{ your_img }}?t=' + (+new Date()));
</script>
Thank you for your reward !