使用OpenCV怎么实现滑块验证码?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
公司主营业务:成都网站建设、网站建设、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联建站是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联建站推出澜沧免费做网站回馈大家。首先需要一个python,然后安装opencv的python库,如下:
pip install opencv-python
然后测试一下是否可用,如下:
import cv2 as cv import numpy as np if __name__ == '__main__': img = np.ones((200, 200, 3), np.uint8) * 255 cv.rectangle(img, (50, 50), (150, 150), (0, 0, 255), 2) cv.imshow('test', img) cv.waitKey(0) cv.destroyAllWindows()
正常的话就会如下显示:
OpenCV的使用
相关的API我也是边用边查的,用得也是相当生疏!具体的常用方法大家只好自行百度了,我就不献丑了!
实现原理及方法
腾讯滑块验证
这次搞得目标就是腾讯滑块验证码,调用腾讯滑块这个接口的网站还是挺多的,比如非常好用的在线画图网站ProcessOn
,其中滑块验证部分类似这样子的:
抓个包发现只有滑块图和带缺口的图,如下:
破解滑块验证码最为关键的地方在于找到滑块缺口的位置
,找到缺口位置后就可以利用Selenium
模拟拖动滑块到指定位置实现破解,之前的老办法就是将完整图的像素点和带缺口图的像素点进行比较从而得到缺口位置
,但是现在一般不会将完整图暴露给我们,所以只有在带有缺口的图上进行处理。我这里一共有两种方案进行缺口位置识别,一种是基于模板匹配
的,另一种是基于轮廓检测
的,下面会细讲两种方案的实现方法。
模板匹配识别缺口
具体是实现过程如下:
1.处理滑块的图片
灰度化滑块图片
处理一下滑块图中滑块的外圈
使用inRange二值化滑块图
使用开运算去除白色噪点
运行结果如下所示(左侧为原始滑块,右侧为处理后的滑块):
2.处理带缺口的图片
先来个高斯滤波去噪
灰度化带缺口图
使用阈值二值化该图
运行结果如下所示(左侧为原始图,右侧为处理后的图):
3.进行模板匹配
调用模板匹配API并圈出匹配上的区域,结果如下所示:
警告警告警告
这种方法的缺口识别率在50%
左右,很大一部分原因是滑块图的背景为纯白色,这在匹配时会产生很大的干扰,要是能将滑块图的背景变为透明
,正确的匹配率可以达到90%以上
如果大家有任何将滑块图的背景变为透明的办法,可以留言到评论区,我真的万分感谢!!!
下面是现阶段的实现代码:
# encoding:utf-8 import cv2 as cv import numpy as np # 对滑块进行二值化处理 def handle_img1(image): kernel = np.ones((8, 8), np.uint8) # 去滑块的前景噪声内核 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) width, heigth = gray.shape for h in range(heigth): for w in range(width): if gray[w, h] == 0: gray[w, h] = 96 # cv.imshow('gray', gray) binary = cv.inRange(gray, 96, 96) res = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel) # 开运算去除白色噪点 # cv.imshow('res', res) return res # 模板匹配(用于寻找缺口有点误差) def template_match(img_target, img_template): tpl = handle_img1(img_template) # 误差来源就在于滑块的背景图为白色 blurred = cv.GaussianBlur(img_target, (3, 3), 0) # 目标图高斯滤波 gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) ret, target = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) # 目标图二值化 # cv.imshow("template", tpl) # cv.imshow("target", target) method = cv.TM_CCOEFF_NORMED width, height = tpl.shape[:2] result = cv.matchTemplate(target, tpl, method) min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result) left_up = max_loc right_down = (left_up[0] + height, left_up[1] + width) cv.rectangle(img_target, left_up, right_down, (0, 0, 255), 2) cv.imshow('res', img_target) if __name__ == '__main__': img0 = cv.imread('./demo/3/hycdn_3.jpg') img1 = cv.imread('./demo/3/hycdn_3_2.png') template_match(img0, img1) cv.waitKey(0) cv.destroyAllWindows()
轮廓检测识别缺口
基于轮廓检测缺口的思路简单很多,加上合理的条件识别率在95%
以上,实现过程如下:
带缺口图高斯模糊去噪用(200,400)
的阈值做Canny边缘检测寻找轮廓对已有的轮廓做约束,比如轮廓的面积范围,轮廓的周长范围
多个匹配结果如下:
实现代码如下:
# encoding:utf-8 import cv2 as cv def get_pos(image): blurred = cv.GaussianBlur(image, (5, 5), 0) canny = cv.Canny(blurred, 200, 400) contours, hierarchy = cv.findContours(canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for i, contour in enumerate(contours): M = cv.moments(contour) if M['m00'] == 0: cx = cy = 0 else: cx, cy = M['m10'] / M['m00'], M['m01'] / M['m00'] if 6000 < cv.contourArea(contour) < 8000 and 370 < cv.arcLength(contour, True) < 390: if cx < 400: continue x, y, w, h = cv.boundingRect(contour) # 外接矩形 cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) cv.imshow('image', image) return x return 0 if __name__ == '__main__': img0 = cv.imread('./demo/4/hycdn_4.jpg') get_pos(img0) cv.waitKey(0) cv.destroyAllWindows()
看完上述内容,你们掌握使用OpenCV怎么实现滑块验证码的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联成都网站设计公司行业资讯频道,感谢各位的阅读!
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。