由于原始caffe使用的demo是基于python2版本的,但是本系统安装的是python3版本,在调试过程出现了好多错误。再次记录下来。
先来一张结果图(分类标签label忘记放哪里了,暂时先用demo中提供的):
首先遇到的最大的问题是python将图像检测完成返回前端图像不显示的问题。
(1)目标原始代码:
原始代码:
def embed_image_html(image):
"""Creates an image embedded in HTML base64 format."""
image_pil = Image.fromarray((255 * image).astype('uint8'))
image_pil = image_pil.resize((256, 256))
string_buf = StringIO.StringIO()
image_pil.save(string_buf, format='png')
data = string_buf.getvalue().encode('base64').replace('\n', '')
return 'data:image/png;base64,' + data
这段代码的目的主要是将图像返回到前端用来展示,但是相比java而言,这里返回的方式有很大的区别,java是返回的图像地址,然后前端读取后段提供的这个图片地址,但是这段代码是通过io流的形式将图片读到内存中,然后通过base64 编码的形式对内存中的图像进行编码,最后将编码结果传递到前端,这个最后的结果是不可读的。最后的结果是下图的src属性对应的值。
(1)上述代码在python3中运行首先出现以下错误。ModuleNotFoundError: No module named 'cStringIO'
Traceback (most recent call last):
File "app.py", line 14, in
import cStringIO as StringIO
ModuleNotFoundError: No module named 'cStringIO'
import cStringIO as StringIO
这是由于python3中已经移除cString模块和StringIO模块,如果要使用该模块需要将上述导入StringIO方式改为从导入io包内的StringIO
import io as StringIO
(2)上述修改后,出现了相关错误:type object '_io.StringIO' has no attribute 'StringIO'
File "/home/scsc/caffe/examples/web_demo/app.py", line 89, in classify_upload
imagesrc=embed_image_html(image,filename_)
File "/home/scsc/caffe/examples/web_demo/app.py", line 98, in embed_image_html
string_buf = StringIO.StringIO()
AttributeError: type object '_io.StringIO' has no attribute 'StringIO'
意思是在io中StringIO 已经没有StringIO属性了,这里查阅度娘后,删除第一个StringIO,变成下面写的即可,同时也可以直接导入io,然后用io调用。
string_buf = StringIO()
# import io
# string_buf = io.StringIO()
(3)接下来又报错 TypeError: string argument expected, got 'bytes'
Traceback (most recent call last):
File "/home/scsc/caffe/examples/web_demo/app.py", line 89, in classify_upload
imagesrc=embed_image_html(image,filename_)
File "/home/scsc/caffe/examples/web_demo/app.py", line 99, in embed_image_html
image_pil.save(string_buf, format='png')
TypeError: string argument expected, got 'bytes'
这里意思是类型错误,将使用的StringIO改成BytesIO()即可。
string_buf = io.BytesIO()
(5)接下来报错: 'bytes' object has no attribute 'encode'
File "/home/scsc/caffe/examples/web_demo/app.py", line 89, in classify_upload
imagesrc=embed_image_html(image,filename_)
File "/home/scsc/caffe/examples/web_demo/app.py", line 100, in embed_image_html
data = string_buf.getvalue().encode('base64').replace('\n', '')
AttributeError: 'bytes' object has no attribute 'encode'
在这里出现了较长时间的停顿,虽然这里也是由于pyton2和python3版本不兼容导致的,但是这个编码问题由于太宽泛,导致在查询资料的时候有各种编码的情况,从此之后走了很多弯路,浪费了很多时间,下面先来说最后如何解决的。
首先这个错误的原因在于将python3中的base64编码不再是按照设置属性来写了,而是通过导入base64包,然后根据包里面的相应编码属性对input 进行编码输出,正确语句为:
import base64
image_pil = Image.fromarray((255 * image).astype('uint8'))
image_pil = image_pil.resize((256, 256))
string_buf = BytesIO()
image_pil.save(string_buf, format='png')
data = string_buf.getvalue();
data = base64.b64encode(data).decode()
return 'data:image/png;base64,' + data
相对于原始代码这里只需要修改编码语句即可完成,最后正确的结果如下
(5)在运行过程中其他的错误 No module named 'cPickle'
Traceback (most recent call last):
File "app.py", line 3, in
import cPickle
ModuleNotFoundError: No module named 'cPickle'
这里python3也没有该模型,因此将cPickle改写成pickle即可成功
import pickle
(6): 'dict' object has no attribute 'iteritems'
Traceback (most recent call last):
File "app.py", line 99, in
class ImagenetClassifier(object):
File "app.py", line 112, in ImagenetClassifier
for key, val in default_args.iteritems():
AttributeError: 'dict' object has no attribute 'iteritems'
这里将iteritems改写成items即可
注:在(4)错误中自己走的弯路
1、在寻找一堆python错误后,想要按照Java前后段交互,python后端向前端传递一个图像路径,然后前端展示页面。因此将上述代码直接删除,直接return保存在服务器项目上的相对路径,这样传递到前端时却打不开图像,显示错误如下:
而且点开img标签的src连接后显示下面错误,目前初步认为还是访问路径的原因,没有真正访问到项目内的图片真正路径。这部分有些时间没有杰出有些忘了。
但是创建一个新的html页面,里面之加入img标签却能展示,如下图所示.
剩下的还有一些在使用caffenet模型中的错误。后面有时间再来更新。