浙江网站建设推荐seo兼职招聘

当前位置: 首页 > news >正文

浙江网站建设推荐,seo兼职招聘,建设工程项目报建网站,长春搜索排名提升文章结构 模板匹配方法单模板匹配单目标匹配多目标匹配 多模板匹配 模板匹配方法 模板是被查找的图像。模板匹配是指查找模板在原始图像中的哪个位置的过程。 result cv2.matchTemplate(image, templ, method, mask)image#xff1a; 原始图像templ#xff1a; 模板图像 cv2.matchTemplate(image, templ, method, mask)image 原始图像templ 模板图像尺寸必须小于或等于原始图像method 匹配的方法mask可选掩模只有 cv2.TM_SQDIFF和 c2.TM_CCORR_NORMED 支持此参数建议采用默认值result 计算得出的匹配结果。如果原始图像的宽、高分别为 W、H模板图像的宽、高分别为 w、hresult 就是一个 W-w1列、H-h1行的32位浮点型数组。数组中每个浮点数都是原始图像中对应像素位置的匹配结果其含义需要根据 method 参数来解读 在模板匹配的计算过程中模板会在原始图像中移动。模板会与重叠区域内的像素逐个对比最后将对比的结果保存在模板左上角像素点索引位置对应的数组位置中。 使用 cv2.TM_SQDIFF(平方差匹配)方法计算出的数组格式如下所示(其他方法计出的数组格式相同仅数值不同): 模板会将原始图像中每一块区域都覆盖一遍但结果数组的行列数并不会等于原始图像的像素的行列数。假设模板的宽为 w、高为h原始图像的宽为 W、高为H 模板移动到原始图像的边缘之后就不会继续移动了所以模板的移动区域如下图所示该区域的边长为“原始图像边长 - 模板边长 1”最后加 1 是因为移动区域内的上下、左右的两个边都被模板覆盖到了如果不加1会丢失数据。
单模板匹配 匹配过程中只用到一个模板的场景叫单模板匹配。原始图像中可能只有一个和模板相以的图像也有可能有多个。如果只获取匹配程度最高的那一个结果这种操作叫单目标配如果需要同时获取所有匹配程度较高的结果这种操作叫多目标匹配。 单目标匹配 单目标匹配只获取一个结果即可就是匹配程度最高的结果 (如果使用平方差匹配则为计算出的最小结果如果使用相关匹配或相关系数匹配则为计算出的最大结果)。本节以平方差匹配为例做介绍。 matchTemplate() 方法的计算结果是一个二维数组minMaxLoc()方法专门用来解析这个二维数组中的最大值、最小值以及这两个值对应的坐标 minValue, maxValue, minLoc, maxLoc cv2.minMaxLoc(src, mask)src matchTemplate() 方法计算得出的数组mask可选掩模建议使用默认值。minValue 数组中的最小值maxValue 数组中的最大值。minLoc 最小值的坐标格式为(x,y)。maxLoc 最大值的坐标格式为(x,y)。 平方差匹配的计算结果越小匹配程度越高。minMaxLoc() 方法返回的 minValue 值是模板匹配的最优结果minLoc 是最优结果区域左上角的点坐标区域大小与模板大小一致。 实例1 为原始图片中匹配成功的区域绘制红框 import cv2img cv2.imread(background.jpg) # 读取原始图像 templ cv2.imread(template.png) # 读取模板图像 height, width, c templ.shape # 获取模板图像的高度、宽度和通道数 results cv2.matchTemplate(img, templ, cv2.TM_SQDIFF_NORMED) # 按照标准平方差方式匹配

获取匹配结果中的最小值、最大值、最小值坐标和最大值坐标

minValue, maxValue, minLoc, maxLoc cv2.minMaxLoc(results) resultPoint1 minLoc # 将最小值坐标当作最佳匹配区域的左上角点坐标

计算出最佳匹配区域的右下角点坐标

resultPoint2 (resultPoint1[0] width, resultPoint1[1] height)

在最佳匹配区域位置绘制红色方框线宽为2像素

cv2.rectangle(img, resultPoint1, resultPoint2, (0, 0, 255), 2) cv2.imshow(img, img) # 显示匹配的结果 cv2.waitKey() # 按下任何键盘按键后 cv2.destroyAllWindows() # 释放所有窗体结果如下 实例2 从两幅图像中选择最佳的匹配结果 import cv2image [] # 存储原始图像的列表

向image列表添加原始图像image_221.png

image.append(cv2.imread(image_221.png))

向image列表添加原始图像image_222.png

image.append(cv2.imread(image_222.png)) templ cv2.imread(templ.png) # 读取模板图像 index -1 # 初始化车位编号列表的索引为-1 min 1 for i in range(0, len(image)): # 循环匹配image列表中的原始图像# 按照标准平方差方式匹配results cv2.matchTemplate(image[i], templ, cv2.TM_SQDIFF_NORMED)# 获得最佳匹配结果的索引if min any(results[0]):index i cv2.imshow(result, image[index]) # 显示最佳匹配结果 cv2.waitKey() # 按下任何键盘按键后 cv2.destroyAllWindows() # 释放所有窗体结果如下 实例3 查找重复的图像 现在有十张图像这些图像格式不同而且分辨率也各不相同。想要找到重复的图像可以使用matchTemplate()来判断两幅图像的相似度如果相似度大于0.9就认为这两幅图像是相同的。 import cv2 import os import sysPIC_PATH C:\Users\Administrator\Desktop\test\ # 照片文件夹地址 width, height 100, 100 # 缩放比例pic_file os.listdir(PIC_PATH) # 所有照片文件列表 same_pic_index [] # 相同图像的索引列表 imgs [] # 缩放后的图像对象列表 has_same set() # 相同图像的集合 count len(pic_file) # 照片数量if count 0: # 如果照片数量为零print(没有图像)sys.exit(0) # 停止程序for file_name in pic_file: # 遍历照片文件pic_name PIC_PATH file_name # 拼接完整文件名img cv2.imread(pic_name) # 创建文件的图像img cv2.resize(img, (width, height)) # 缩放成统一大小imgs.append(img) # 按文件顺序保存图像对象for i in range(0, count - 1): # 遍历所有图像文件不遍历最后一个图像if i in has_same: # 如果此图像已经找到相同的图像continue # 跳过templ imgs[i] # 取出模板图像same [i] # 与templ内容相同的图像索引列表for j in range(0 i 1, count): # 从templ的下一个位置开始遍历if j in has_same: # 如果此图像已经找到相同的图像continue # 跳过pic imgs[j] # 取出对照图像results cv2.matchTemplate(pic, templ, cv2.TM_CCOEFF_NORMED) # 比较两图像相速度if results 0.9: # 如果相似度大于90%认为是同一张照片same.append(j) # 记录对照图像的索引has_same.add(i) # 模板图像已找到相同图像has_same.add(j) # 对照图像已找到相同图像if len(same) 1: # 如果模板图像找到了至少一张与自己相同的图像same_pic_index.append(same) # 记录相同图像的索引for same_list in same_pic_index: # 遍历所有相同图像的索引text 相同的照片for same in same_list:text str(pic_file[same]) , # 拼接文件名print(text) 结果如下 多目标匹配 多目标匹配需要将原始图像中所有与模板相似的图像都找出来使用相关匹配或相关系数匹配可以很好地实现这个功能。如果计算结果大于某一值则认为匹配区域的图案和模板是相同的。 实例4 为原始图片中所有匹配成功的图案绘制红框 使用cv2.TM_CCOEFF_NORMED方式进行模板匹配使用for循环遍历matchTemplate()方法返回的结果找到所有大于0.99的计算结果在这些结果的对应区域位置绘制红色矩形边框。 import cv2 img cv2.imread(background2.jpg) # 读取原始图像 templ cv2.imread(template.png) # 读取模板图像 width, height, c templ.shape # 获取模板图像的宽度、高度和通道数 results cv2.matchTemplate(img, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配 for y in range(len(results)): # 遍历结果数组的行for x in range(len(results[y])): # 遍历结果数组的列if results[y][x] 0.99: # 如果相关系数大于0.99则认为匹配成功# 在最佳匹配结果位置绘制红色方框cv2.rectangle(img, (x, y), (x width, y height), (0, 0, 255), 2) cv2.imshow(img, img) # 显示匹配的结果 cv2.waitKey() # 按下任何键盘按键后 cv2.destroyAllWindows() # 释放所有窗体结果如下 实例5 统计一条快轨线路的站台总数 import cv2image cv2.imread(image.png) # 读取原始图像 templ cv2.imread(templ.png) # 读取模板图像 height, width, c templ.shape # 获取模板图像的高度、宽度和通道数 results cv2.matchTemplate(image, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配 station_Num 0 # 初始化快轨的站台个数为0 for y in range(len(results)): # 遍历结果数组的行for x in range(len(results[y])): # 遍历结果数组的列if results[y][x] 0.99: # 如果相关系数大于0.99则认为匹配成功# 在最佳匹配结果位置绘制蓝色矩形边框cv2.rectangle(image, (x, y), (x width, y height), (255, 0, 0), 2)station_Num 1 # 快轨的站台个数加1 cv2.putText(image, the numbers of stations: str(station_Num), (0, 30),cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1) # 在原始图像绘制快轨站台的总数 cv2.imshow(result, image) # 显示匹配的结果 cv2.waitKey() # 按下任何键盘按键后 cv2.destroyAllWindows() # 释放所有窗体结果如下 实例6 优先选择直线距离最短的地铁站 import cv2 import numpy as np import mathimage cv2.imread(image.png) # 读取原始图像 templ cv2.imread(templ.png) # 读取模板图像 height, width, c templ.shape # 获取模板图像的高度、宽度和通道数 results cv2.matchTemplate(image, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配 point_X [] # 用于存储最佳匹配结果左上角横坐标的列表 point_Y [] # 用于存储最佳匹配结果左上角纵坐标的列表 for y in range(len(results)): # 遍历结果数组的行for x in range(len(results[y])): # 遍历结果数组的列if results[y][x] 0.99: # 如果相关系数大于0.99则认为匹配成功# 在最佳匹配结果位置绘制红色方框cv2.rectangle(image, (x, y), (x width, y height), (255, 0, 0), 2)point_X.extend([x]) # 把最佳匹配结果左上角的横坐标添加到列表中point_Y.extend([y]) # 把最佳匹配结果左上角的纵坐标添加到列表中

出发点的横、纵坐标

start_X 62 start_Y 150

计算出发点到人民广场地铁站的距离

place_Square np.array([point_X[0], point_Y[0]]) place_Start np.array([start_X, start_Y]) minus_SS place_Start - place_Square start_Square math.hypot(minus_SS[0], minus_SS[1])

计算出发点到解放大路地铁站的距离

place_Highroad np.array([point_X[1], point_Y[1]]) minus_HS place_Highroad - place_Start start_Highroad math.hypot(minus_HS[0], minus_HS[1])

用绿色的线画出距离较短的路线

if start_Square start_Highroad:cv2.line(image, (start_X, start_Y), (point_X[0], point_Y[0]), (0, 255, 0), 2) else:cv2.line(image, (start_X, start_Y), (point_X[1], point_Y[1]), (0, 255, 0), 2) cv2.imshow(result, image) # 显示匹配的结果 cv2.waitKey() # 按下任何键盘按键后 cv2.destroyAllWindows() # 释放所有窗体结果如下 多模板匹配 匹配过程中同时查找多个模板的操作叫多模板匹配。多模板匹配实际上就是进行了n次“单模板多模板匹配”操作n的数量为模板总数。 实例7 同时匹配3个不同的模板 每一个模板都要做一次“单模板多目标匹配”最后把所有模板的匹配结果汇总到一起。“单模板多模板匹配”的过程可以封装成一个方法方法参数为模板和原始图像方法内部将计算结果再加工一下直接返回所有红框左上角和右下角两点横纵坐标的列表。在方法之外将所有模板计算得出的坐标汇总到一个列表中按照这些汇总的坐标一次性将所有红框都绘制出来。 import cv2def myMatchTemplate(img, templ): # 自定义方法获取模板匹配成功后所有红框位置的坐标width, height, c templ.shape # 获取模板图像的宽度、高度和通道数results cv2.matchTemplate(img, templ, cv2.TM_CCOEFF_NORMED) # 按照标准相关系数匹配loc list() # 红框的坐标列表for i in range(len(results)): # 遍历结果数组的行for j in range(len(results[i])): # 遍历结果数组的列if results[i][j] 0.99: # 如果相关系数大于0.99则认为匹配成功# 在列表中添加匹配成功的红框对角线两点坐标loc.append((j, i, j width, i height))return locimg cv2.imread(background2.jpg) # 读取原始图像 templs list() # 模板列表 templs.append(cv2.imread(template.png)) # 添加模板1 templs.append(cv2.imread(template2.png)) # 添加模板2 templs.append(cv2.imread(template3.png)) # 添加模板3loc list() # 所有模板匹配成功位置的红框坐标列表 for t in templs: # 遍历所有模板loc myMatchTemplate(img, t) # 记录该模板匹配得出的for i in loc: # 遍历所有红框的坐标cv2.rectangle(img, (i[0], i[1]), (i[2], i[3]), (0, 0, 255), 2) # 在图片中绘制红框cv2.imshow(img, img) # 显示匹配的结果 cv2.waitKey() # 按下任何键盘按键后 cv2.destroyAllWindows() # 释放所有窗体结果如下 实例8 控制台输出4辆车分别停在了哪个车位上 import cv2image cv2.imread(image.png) # 读取原始图像 templs [] # 模板列表 templs.append(cv2.imread(car1.png)) # 添加模板图像1 templs.append(cv2.imread(car2.png)) # 添加模板图像2 templs.append(cv2.imread(car3.png)) # 添加模板图像3 templs.append(cv2.imread(car4.png)) # 添加模板图像3 for car in templs: # 遍历所有模板图像# 按照标准相关系数匹配results cv2.matchTemplate(image, car, cv2.TM_CCOEFF_NORMED)for i in range(len(results)): # 遍历结果数组的行for j in range(len(results[i])): # 遍历结果数组的列# print(results[i][j])if results[i][j] 0.99: # 如果相关系数大于0.99则认为匹配成功if 0 j 140:print(车位编号:, 1)elif j 330:print(车位编号:, 2)elif j 500:print(车位编号:, 3)else:print(车位编号:, 4)break 1号车位水平像素的取值范围是0 ~ 1402号车位水平像素的取值范围是 141 ~ 3303号车位水平像素的取值范围是331 ~ 5004号车位水平像素的取值范围是 501 ~ 650。 结果如下