我们在利用爬虫采集数据时经常会碰到滑块验证码,下面我将通过OpenCV来识别滑块的缺口坐标。

一、Python3安装OpenCV
安装opencv可以用pip3来安装,命令如下:
pip3 install opencv-python
如果在安装时碰到错误,可以安装下下面几个东西。
pip3 install scikit-build
pip3 install cmake
pip3 install pip -U
二、缺口识别
2.1 读取图片
滑块验证码一般有两张图片,一张背景图片,一张缺口图片。


可以用imread函数来读取。
bg_img = cv2.imread('bg.jpg') # 背景图片
cut_img = cv2.imread('cut.png') # 缺口图片
如果是图片流,可以用imdecode来读取。
bg_img = cv2.imdecode(np.fromstring(bg, np.uint8), cv2.IMREAD_COLOR)
cut_img = cv2.imdecode(np.fromstring(cut, np.uint8), cv2.IMREAD_COLOR)
2.2 图片处理
读取图片后,先要识别图片边缘。
bg_edge = cv2.Canny(bg_img, 100, 200)
cut_edge = cv2.Canny(cut_img, 100, 200)
然后把得到的灰度图转为RGB格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
cut_pic = cv2.cvtColor(cut_edge, cv2.COLOR_GRAY2RGB)


2.3 缺口识别
缺口识别可以用模板识别matchTemplate函数
res = cv2.matchTemplate(bg_pic, cut_pic, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配
max_loc就是缺口坐标,x为max_loc[0],y为max_loc[1]。
识别效果如下:

三、最终代码
import cv2
def identify_gap(bg, cut):
'''
bg: 背景图片
cut: 缺口图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
cut_img = cv2.imread(cut) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
cut_edge = cv2.Canny(cut_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
cut_pic = cv2.cvtColor(cut_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, cut_pic, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配
# 返回缺口坐标
return max_loc
if __name__ == '__main__':
print(identify_gap('bgPic.jpeg', 'cutPic.png'))
正文完