最近毕业答辩需要做个演示系统(图像去雨),要求将选择图片的去雨图片展示出来与原图进行对比,我决定用网页的形式做个演示系统。原先想着用java调用python脚本运行,但模型的输入和输出都是图片矩阵数据,不好操作,后来就直接用python的flask框架简单的实现了前后端交互。
图片预览:
前端页面用file类型的input选择文件,通过js代码将图片背景方式显示在div内,实现预览。
在 reader.onload中获取的data即为图像的base64编码,其编码本体为‘data:image/jpeg;base64,’后的字符,
onload=function () {
var
fileInput = document.getElementById('test-image-file'),
preview = document.getElementById('test-image-preview');
// 监听change事件:
fileInput.addEventListener('change', function() {
// 检查文件是否选择:
if(!fileInput.value) {
alert('没有选择文件');
return;
}
// 获取File引用:
var file = fileInput.files[0];
//判断文件大小
var size = file.size;
// if(size >= 1*1024*1024){
// alert('文件大于1兆不行!');
// return false;
// }
// 获取File信息:
if(file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
alert('不是有效的图片文件!');
return;
}
// 读取文件:
var reader = new FileReader();
//读取操作成功时调用
reader.onload = function (e) {
var
data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...}'
preview.style.backgroundImage = 'url(' + data + ')';
image=data;
};
// 以DataURL的形式读取文件:
reader.readAsDataURL(file);
//console.log(image);
});
}
css控制背景图自适应div的大小(长或宽),不重复且位于正中间。
le type="text/css">
#test-image-preview {
border: 1px solid white;
height: 400px;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
margin-right: 50px;
}
获得图片的base64编码就可以使用ajax将其传到后台。由于后台处理较久,这里使用了一个loading的div来改善用户的等待体验。
var image="";
function fun()
{
if(image=="")
{
alert("没有选择文件");
return;
}
var ajaxTimeout=$.ajax({
async:true,
url:"/image",
timeout:1000*120,
type:'post',
data:image,
beforeSend:function(){
$("#loading").show()
},
success:function(data){
//alert(data)
image_result=document.getElementById("image_result");
image_result.style.backgroundImage='url(' + 'data:image/jpg;base64,'+data + ')';
$("#loading").hide()
},
complete:function(XMLHttpRequest,status){ //请求完成执行
if(status=='timeout')
{
ajaxTimeout.abort();
alert("超时");
}
}
}
);
}
#loading{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
display: none;
z-index: 999;
opacity: 0.8;
background: url("static/loading.gif");
background-repeat:no-repeat;
background-size: 100% 100%;
-moz-background-size: 100% 100%;
}
后台接收到base64数据后要先解析成opencv能读取的格式。注意接收到的字符要去掉头部‘data:image…base64,’。
(base64–>二进制–>矩阵形式)
imagecode = request.get_data()
# 去除头部data:image...base64,
strlist = str(imagecode).split(',')
b64_img = ''
for i in strlist[1:]:
b64_img += i
img_b = base64.b64decode(b64_img) # 二进制字符
# 注意cv2默认为 BGR顺序,而其他软件一般使用RGB
img = cv2.imdecode(np.frombuffer(img_b, np.uint8), cv2.COLOR_RGB2BGR)
print(img.shape)
# cv2.imshow('', img)
# #必须加这个,不然显示图片时会卡死
# cv2.waitKey()
将数据输入模型后得到的输出数据再编码成base64传到前端。
得到的数据是矩阵形式的res_img(矩阵形式–>二进制–>base64)。
res_b=cv2.imencode('.jpg',res_img)[1].tostring()
res_bs64=base64.b64encode(res_b)
print('返回数据')
return res_bs64
此时返回的base64数据不带头信息‘data:image…base64,’,在前端页面显示时要加上。
image_result.style.backgroundImage='url(' + 'data:image/jpg;base64,'+data + ')';
此次毕业设计选题为图像去雨,在测试时图片稍微大点就爆内存,而且运行过程也很慢,在测试或演示时可尽量将图片裁剪小点,这样会改善许多,同时前端的请求可以将超时时间(timeout)设长点。(最开始用一张张完整的图片测试不是报内存不足就是后台运算时间很久,前端根本接受不到数据,百度查了许多优化办法,要么有些不懂,要么没啥效果,甚至直接又加了4g内存,表现也是差强人意,最后还是直接减少输入图片的大小,简单粗暴,效果也是最明显??)