2025年4月5日 星期六 乙巳(蛇)年 正月初六 夜 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

验证识别:滑块缺口位置识别

时间:06-25来源:作者:点击数:23

1.基于图片对比计算缺口位置

  • # -*- coding: utf-8 -*-
  • from PIL import Image
  • class SlideCrack(object):
  • def __init__(self, gap_img, bg):
  • self.gap_img = gap_img
  • self.bg = bg
  • @staticmethod
  • def pixel_is_equal(image1, image2, x, y):
  • """
  • 判断两张图片的像素是否相等,不想等即为缺口位置
  • :param image1:
  • :param image2:
  • :param x: x坐标
  • :param y: y 坐标
  • :return:
  • """
  • # 取两个图片的像素点
  • pixel1 = image1.load()[x, y]
  • pixel2 = image2.load()[x, y]
  • threshold = 60 # 像素色差
  • if abs(pixel1[0]-pixel2[0]) < threshold and abs(pixel1[1]-pixel2[1]) < threshold and abs(pixel1[2]-pixel2[2]) <threshold:
  • return True
  • else:
  • return False
  • def get_gap(self, image1, image2):
  • """
  • 获取缺口位置
  • :param image1:完整图片
  • :param image2: 带缺口的图片
  • :return:
  • """
  • left = 60 # 设置一个起始量,因为验证码一般不可能在左边,加快识别速度
  • for i in range(left, image1.size[0]):
  • for j in range(image1.size[1]):
  • if not self.pixel_is_equal(image1, image2, i, j):
  • left = i
  • return left
  • return left
  • def run(self):
  • image1 = Image.open(self.bg)
  • image2 = Image.open(self.gap_img)
  • # 获取缺口的位置
  • gap = self.get_gap(image1, image2)
  • print(gap)
  • if __name__ == "__main__":
  • img1 = "img/1_1.png" # 带缺口的背景图
  • img2 = "img/1_2.png" # 不带缺口的背景图
  • gt = SlideCrack(img1, img2)
  • gt.run()

2.基于边界对比计算缺口位置

  • # -*- coding: utf-8 -*-
  • import cv2
  • class SlideCrack(object):
  • def __init__(self, gap, bg, out):
  • """
  • init code
  • :param gap: 缺口图片
  • :param bg: 背景图片
  • :param out: 输出图片
  • """
  • self.gap = gap
  • self.bg = bg
  • self.out = out
  • @staticmethod
  • def clear_white(img):
  • # 清除图片的空白区域,这里主要清除滑块的空白
  • img = cv2.imread(img)
  • rows, cols, channel = img.shape
  • min_x = 255
  • min_y = 255
  • max_x = 0
  • max_y = 0
  • for x in range(1, rows):
  • for y in range(1, cols):
  • t = set(img[x, y])
  • if len(t) >= 2:
  • if x <= min_x:
  • min_x = x
  • elif x >= max_x:
  • max_x = x
  • if y <= min_y:
  • min_y = y
  • elif y >= max_y:
  • max_y = y
  • img1 = img[min_x:max_x, min_y: max_y]
  • return img1
  • def template_match(self, tpl, target):
  • th, tw = tpl.shape[:2]
  • result = cv2.matchTemplate(target, tpl, cv2.TM_CCOEFF_NORMED)
  • # 寻找矩阵(一维数组当作向量,用Mat定义) 中最小值和最大值的位置
  • min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
  • tl = max_loc
  • br = (tl[0] + tw, tl[1] + th)
  • # 绘制矩形边框,将匹配区域标注出来
  • # target:目标图像
  • # tl:矩形定点
  • # br:矩形的宽高
  • # (0,0,255):矩形边框颜色
  • # 1:矩形边框大小
  • cv2.rectangle(target, tl, br, (0, 0, 255), 2)
  • cv2.imwrite(self.out, target)
  • return tl[0]
  • @staticmethod
  • def image_edge_detection(img):
  • edges = cv2.Canny(img, 100, 200)
  • return edges
  • def discern(self):
  • img1 = self.clear_white(self.gap)
  • img1 = cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)
  • slide = self.image_edge_detection(img1)
  • back = cv2.imread(self.bg, 0)
  • back = self.image_edge_detection(back)
  • slide_pic = cv2.cvtColor(slide, cv2.COLOR_GRAY2RGB)
  • back_pic = cv2.cvtColor(back, cv2.COLOR_GRAY2RGB)
  • x = self.template_match(slide_pic, back_pic)
  • # 输出横坐标, 即 滑块在图片上的位置
  • print(x)
  • if __name__ == "__main__":
  • # 滑块图片
  • image1 = "img/1_1.png"
  • # 背景图片
  • image2 = "img/1_2.png"
  • # 处理结果图片,用红线标注
  • image3 = "img/1_3.png"
  • sc = SlideCrack(image1, image2, image3)
  • sc.discern()
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门