当前位置: 首页 > 后端技术 > Python

蟒盘纪念币系列之二:身份验证码02

时间:2023-03-26 12:19:57 Python

上一期,我们获得了1000张验证码图片。今天我们就来说说如何使用这些图片。读取图片Python有很多读取图片的库,比如OpenCV、PIL等,为了后期方便和个人习惯,这里选择OpenCV。以第一张图片1.jpg为例:importcv2img=cv2.imread('1.jpg',0)cv2.imshow('img',img)cv2.waitKey(0)执行后发现错误:#error:(-215:Assertionfailed)size.width>0&&size.height>0infunction'cv::imshow'为了确定问题出在哪里,换了一张图片运行代码,结果还是同样的错误。图片可以在资源管理器中正常预览,说明图片本身没有问题,也就是我们的代码有问题。于是换成了PIL包,代码如下:fromPILimportImageimg=Image.open('1.jpg')print(img)img.show()执行代码后,图片正常显示,并且控制台输出如下Information:#从字面上看,这张图片可能是GIF格式的,虽然它的扩展名是.jpg(其实.jpg也是上一节在我们自己的设置中)。这就解释了为什么使用OpenCV读取图片会报错。这是因为OpenCV不能直接读取GIF格式的图片,必须像读取视频文件一样逐帧处理。defget_gif_first_frame(gif_path):gif=cv2.VideoCapture(gif_path)_,frame=gif.read()gif.release()returnframe我们定义一个函数来获取验证码文件的第一帧。在这里我想解释一下为什么OpenCV这么麻烦而我们不用PIL库。就是因为我们读取图片后要对获取的图片进行多次处理,而OpenCV处理图片确实方便。字符分割读取图片后,下一步就是将原始图片中的每个字符切割成单独的文件。怎么分开?我脑海中的第一个想法是这样的:图片转为灰度cap=get_gif_first_frame('1.jpg')cap=cv2.cvtColor(cap,cv2.COLOR_BGR2GRAY)图片线条中有很多浅色干扰,并且字符的颜色很亮,所以可以考虑将图片中小于一定数的像素点的像素值全部设置为零,有效减少干扰_,thresh=cv2.threshold(cap,150,255,cv2.THRESH_BINARY)去除干扰后,剩下相对独立的字符。但是因为在上一步去除干扰线的时候字符可能会被截断,所以这里有一个dilation的过程dilate=cv2.dilate(thresh,(7,7),iterations=5)dilation之后,可以搜索所有的轮廓图片中。理想情况下,图中有四个轮廓对应四个字符dilate=cv2.dilate(thresh,(7,7),iterations=5)contours,_=cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)得到根据轮廓的最小外接矩形,作为切割的依据,切割出contours中的每一个字符用于轮廓:x,y,w,h=cv2.boundingRect(contour)area=w*htarget=cap[y-1ify-1>0else0:y+h,x-1ifx-1>0else0:x+w]但是想象很丰满,现实很骨感。下面是这样生成的图块,有些字符被切对了,但有些就没那么幸运了。最后证明这种方式行不通。还有别的办法吗?后记做这个项目的时候我也是边写文章边从头一步一步来的,正好把项目中遇到的问题都暴露出来,有利于整合。对于上面的问题,你有什么好的解决办法吗?欢迎在留言中提出~本系列所有源码都会放在我的github仓库,有需要的可以参考,有问题请指正,谢谢!下期预告:另一种切字方式第一期:蟒盘纪念币系列一:简介第二期:蟒盘纪念币系列二:鉴定验证码01