解决思路:
1.先把图片录入,临时处理。(滑块去除白边,图片转黑白,边缘描边;背景图片转黑白,边缘描边)。
去除白边函数
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
图片转黑白,两种办法:
(1) cv2.cvtColor(img1, cv2.COLOR_RGB2GRAY)#转变颜色,彩色变黑白
#cv2.cvtColor(p1,p2) 是颜色空间转换函数,p1是需要转换的图片,p2是转换成何种格式。
#cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式
#cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片
(2) cv2.imread(self.bg, 0)#读入图像第二个参数0是灰色,1是彩色
2.背景图片和滑块把BGR格式转换成RGB格式,图片转化成矩阵的模式。
slide_pic = cv2.cvtColor(slide, cv2.COLOR_GRAY2RGB)
back_pic = cv2.cvtColor(back, cv2.COLOR_GRAY2RGB)
3.对比二进制的图片,匹配滑块在背景图片的横坐标,输出。
下边是函数的内容:
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]
使用:
x = self.template_match(slide_pic, back_pic)
输出一个横坐标
下边是整体代码,图片自加
# -*- 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)#读入图像第二个参数0是灰色,1是彩色
back = self.image_edge_detection(back)
#cv2.cvtColor(p1,p2) 是颜色空间转换函数,p1是需要转换的图片,p2是转换成何种格式。
#cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式
#cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片
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/3_3.png"
sc = SlideCrack(image1, image2, image3)
sc.discern()
参考:https://blog.csdn.net/Crazy__Hope/article/details/100149283
函数:(1)cv2.imread()和cv2.cvtColor() 的使用
https://blog.csdn.net/zhang_cherry/article/details/88951259
(2)python opencv入门 Canny边缘检测
https://blog.csdn.net/tengfei461807914/article/details/76376941