import cv2 as cv
from matplotlib import pyplot as plt
queryImage = cv.imread("template.png", 0)
trainingImage = cv.imread("target.png", 0) # 读取要匹配的灰度照片
sift = cv.SIFT_create() # 创建sift检测器
kp1, des1 = sift.detectAndCompute(queryImage, None)
kp2, des2 = sift.detectAndCompute(trainingImage, None)
# 设置Flannde参数
FLANN_INDEX_KDTREE = 0
indexParams = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
searchParams = dict(checks=50)
flann = cv.FlannBasedMatcher(indexParams, searchParams)
matches = flann.knnMatch(des1, des2, k=2)
# 设置好初始匹配值
matchesMask = [[0, 0] for i in range(len(matches))]
for i, (m, n) in enumerate(matches):
if m.distance < 0.5 * n.distance: # 舍弃小于0.5的匹配结果
matchesMask[i] = [1, 0]
drawParams = dict(matchColor=(0, 0, 255), singlePointColor=(255, 0, 0), matchesMask=matchesMask,
flags=0) # 给特征点和匹配的线定义颜色
resultimage = cv.drawMatchesKnn(queryImage, kp1, trainingImage, kp2, matches, None, **drawParams) # 画出匹配的结果
plt.imshow(resultimage, ), plt.show()
target.png template.png: 最终的运行结果: matchTemplate:
def main():
otemp = 'template.png'
oblk = 'target.png'
identify_gap(oblk, otemp, "D:\\books\\plantuml_picture\\target.png");
def identify_gap(bg, tp, out):
'''
bg: 背景图片
tp: 缺口图片
out:输出图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配
# 绘制方框
th, tw = tp_pic.shape[:2]
tl = max_loc # 左上角点的坐标
br = (tl[0] + tw, tl[1] + th) # 右下角点的坐标
cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2) # 绘制矩形
cv2.imwrite(out, bg_img) # 保存在本地
# 返回缺口的X坐标
return tl[0]
if __name__ == '__main__':
main()
|