写点代码识别手写数字II - 预处理手写数字图片

举报
黄生 发表于 2021/02/10 15:21:12 2021/02/10
【摘要】 现在从流程的最左边开始,先用手机拍了一张照片,这张照片是在一张A4纸上用铅笔写的数字然后要用opencv打开图片,先要安装并导入opencv库,安装:pip3 install opencv-python安装没有报错,试着导入一下,报错了:>>> import cv2Traceback (most recent call last): File "<stdin>", line 1, in <...

现在从流程的最左边开始,先用手机拍了一张照片,这张照片是在一张A4纸上用铅笔写的数字
然后要用opencv打开图片,先要安装并导入opencv库,
安装:

pip3 install opencv-python

安装没有报错,试着导入一下,报错了:

>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/.local/lib/python3.7/site-packages/cv2/__init__.py", line 5, in <module>
    from .cv2 import *
ImportError: libGL.so.1: cannot open shared object file: No such file or directory

这个库文件 libGL.so.1在ubuntu20.04看了一下,是有的

lrwxrwxrwx 1 root root 14 11月 24 18:55 /usr/lib/x86_64-linux-gnu/libGL.so.1 -> libGL.so.1.7.0

但是cloudide是基于鲲鹏的EulerOS 2.0 (SP8),默认没这个
想自己安装,需要root权限,没有
哎,出师未捷身先死,长使英雄泪满襟啊~
于是提个工单找华为工程师寻找办法,很快有了
原因是默认安装的最新opencv版本,与基于鲲鹏的cloudide有冲突,安装指定版本即可
如此这般:

pip3 uninstall opencv-python
pip3 install opencv-python==4.4.0.46

再 

import cv2

就不报错了~
上面的问题解决后,可以使用opencv库提供的功能将图片读入到内存中
事先用手机拍了一张手写的数字图片num2.jpg
然后我们看一下读入的图像的形状,对象的类型。想展示一下图片报错了,不过无所谓了,反正在cloudide是不能像在本地一样直观的把图片显示出来的

import cv2
img=cv2.imread('num2.jpg')

>>> img.shape
(876, 1200, 3)  #行876 列1200 深度3(RGB图片)
>>> type(img)
<class 'numpy.ndarray'>  #numpy的多维数组
>>> cv2.imshow('pic',img)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
cv2.error: OpenCV(4.4.0) /tmp/pip-install-5bwr2fh8/opencv-python/opencv/modules/highgui/src/window.cpp:651: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'

图片的形状,与用identify查看的图片信息是一致的:

identify num2.jpg 
num2.jpg JPEG 1200x876 1200x876+0+0 8-bit sRGB 294818B 0.000u 0:00.000   #宽/列1200 高/行876

这样就算是将图片打开了,下一步中心切割图片
中心切割图片的目的就是,将长方形图片切割为正方形图片,正方形的边长等于长方形的高
首先图片的数字表示结构是这样的
11n.png
然后我们裁剪为中间的正方形,就是:
行的信息全要
列的信息要居中部分
颜色信息全要
体现到数组上就是[ : , col_start : col_end, :]
如下图
22n.png
代码如下:

img_width=img.shape[1]
img_height=img.shape[0]
col_start=(int)((img_width - img_height)/2)
col_end=(int)(col_start+img_height)
cropped_img=img[:,col_start:col_end,:]  #使用多维数组的slicing进行图片的切片

对图片的处理的解释如图:
33n.png
为了在处理过程中查看的方便,从第2步开始做起,最后再回头做第1步调整大小为28X28,因为如果一开始就调整,尺寸太小了人眼看的不舒服

gray_img=cv2.cvtColor(cropped_img,cv2.COLOR_BGR2GRAY)  #转为灰度图像
(thresh,black_white)=cv2.threshold(gray_img,128,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)  #以一定的阀值转换为黑白二值图像
black_white=cv2.bitwise_not(black_white)  #颠倒黑白 好无耻...
black_white=cv2.resize(black_white,(28,28))  ##设置大小为28X28
cv2.imwrite('num3.jpg',black_white)  ##因为cv2.imshow()看图片报错,这个将图片存入文件num3.jpg,再打开文件查看

在这里发现cloudide的一个小问题,这个问题是因为cloudide是基于浏览器,而浏览器的缓存机制导致的
问题就这样的,cloudide里点开图片文件,可以直接打开预览窗口查看,当你查看这个文件后,比如文件num3.jpg,然后num3.jpg的内容被修改或被覆盖了,再点击num3.jpg,预览窗口仍然显示最开始的图像的样子,猜测这是因为从浏览器缓存里加载,而没取最新的图片内容,哪怕图片的内容刚刚修改。这个缓存机制是有问题的。
到这里图片就处理好了,左边是正方形图像,右边是做了灰度化黑白二值化的图像,中间是28X28的图像
这样处理后的图像,就可以送入模型进行推理了

44n.png

以上学习材料整理来自:MOOC-Python与机器学习初步

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。