NCC匹配原理公式:

1.旋转的情况使用圆投影的旋转不变性原理匹配

2.通过对图像进行降采样,从降采样的高层开始匹配筛选匹配点极大地减少了运算量

3.差分简化运算数据量(但是目前实现的差分貌似没有起到加速的效果,主要是计算src的累积和会消耗太多的时间)

4.gitee代码持续改进中gitee代码地址https://gitee.com/lzj12321/ncc_match.git,欢迎交流,最后希望可以实现一个可工业化应用的NCC匹配(1.带旋转,2.不规则模板匹配,3.实时性高)

5.微信同号,支持帮忙做付费项目(哈哈)

注意:

不支持缩放匹配,圆投影匹配目前不输出匹配角度,只是NCC匹配的初步实现,还需很多优化,目前的实现对规则矩形不旋转的匹配还是挺友好的

import math
import numpy as np
import cv2
from PyQt5.QtCore import QTime'''
1.二维数组降维
2.圆投影匹配算法
'''def calculate_unrotate_temp_data(temp):####使用圆投影匹配算法####temp_mean = np.mean(temp)temp_sub_avg = temp - temp_meantemp_deviation = np.vdot(temp_sub_avg, temp_sub_avg)return temp_deviation, temp_sub_avgdef calculate_rotate_temp_data(temp):temp_column = temp.shape[1]temp_row = temp.shape[0]if temp_column < temp_row:diameter = temp_rowelse:diameter = temp_columnmax_radius = math.floor(diameter / 2)circle_center = (temp_row / 2, temp_column / 2)circle_ring_point = {}###统计每个点到中心的半径,并分类###for i in range(temp_column):for j in range(temp_row):radius = round(np.sqrt((i - circle_center[0]) ** 2 + (j - circle_center[1]) ** 2))if radius > max_radius:continueif radius in circle_ring_point.keys():circle_ring_point[radius].append(j * temp_column + i)else:circle_ring_point[radius] = [j * temp_column + i]###排序获取每个环上的点###circle_ring_point = sorted(circle_ring_point.items(), key=lambda item: item[0])circular_projection_data = []for item in circle_ring_point:circular_projection_data.append(np.array(item[1]))_circle_sum = []_temp = temp.reshape(1, -1)[0]for item in circular_projection_data:_circle_sum.append(np.sum(_temp[item]))_circle_sum = np.array(_circle_sum)_mean = np.mean(_circle_sum)_deviation_array = _circle_sum - _mean_deviation = np.dot(_deviation_array, _deviation_array)tempData = {'deviation': _deviation, 'deviation_array': _deviation_array,'circular_projection_data': circular_projection_data, 'temp_size': temp.shape}return tempDatadef generate_temp_data(temp, downsamplingtime=0, is_rotate=False):######每次从原图开始取样#############temp_downsampling_data = []temp_downsampling_img = []###generate downsampling img###temp_downsampling_img.append(temp)for i in range(downsamplingtime):temp_downsampling_img.append(cv2.pyrDown(temp_downsampling_img[i]))###generate downsampling data###for temp_img in temp_downsampling_img:if is_rotate:temp_downsampling_data.append(calculate_rotate_temp_data(temp_img))else:temp_downsampling_data.append({'deviation': (calculate_unrotate_temp_data(temp_img))[0],'sub_avg': (calculate_unrotate_temp_data(temp_img))[1]})return temp_downsampling_datadef ncc_unrotate_match(src, temp_data, threshold=0.5, match_region=None):temp_deviation, temp_sub_avg = temp_data['deviation'], temp_data['sub_avg']temp_row_num = temp_sub_avg.shape[0]temp_column_num = temp_sub_avg.shape[1]_line_start = 0_column_start = 0_line_range = src.shape[0] - temp_row_num + 1_column_range = src.shape[1] - temp_column_num + 1if match_region is not None:_line_start = match_region[1]_column_start = match_region[0]_line_range = match_region[1] + match_region[3] + 1_column_range = match_region[0] + match_region[2] + 1if _line_range > src.shape[0] - temp_row_num + 1:_line_range = src.shape[0] - temp_row_num + 1if _column_range > src.shape[1] - temp_column_num + 1:_column_range = src.shape[1] - temp_column_num + 1src_integration = cv2.integral(src)pixel_num = temp_sub_avg.sizematch_points = []for i in range(_line_start, _line_range, 1):for j in range(_column_start, _column_range, 1):src_mean = (src_integration[i + temp_row_num][j + temp_column_num] +src_integration[i][j] -src_integration[i][j + temp_column_num] -src_integration[i + temp_row_num][j]) / pixel_num_src_deviation = src[i:i + temp_row_num, j:j + temp_column_num] - src_meansrc_deviation = np.vdot(_src_deviation, _src_deviation)ncc_numerator = np.vdot(temp_sub_avg, _src_deviation)ncc_denominator = np.sqrt(temp_deviation * src_deviation)ncc_value = ncc_numerator / ncc_denominatorif ncc_value > threshold:match_point = {'match_score': ncc_value, 'point': (j, i)}match_points.append(match_point)return match_pointsdef ncc_rotate_match(src, tempData, threshold=0.5, angle_start=0, angle_end=360, angle_step=1, match_region=None):temp_deviation = tempData['deviation']temp_deviation_array = tempData['deviation_array']circular_projection_data = tempData['circular_projection_data']temp_row_num, temp_column_num = tempData['temp_size'][0], tempData['temp_size'][1]_line_start, _column_start, _line_range, _column_range = 0, 0, src.shape[0] - temp_row_num, src.shape[1] - temp_column_numif match_region is not None:_line_start = match_region[1]_column_start = match_region[0]_line_range = match_region[1] + match_region[3] + 1_column_range = match_region[0] + match_region[2] + 1if _line_range > src.shape[0] - temp_row_num + 1:_line_range = src.shape[0] - temp_row_num + 1if _column_range > src.shape[1] - temp_column_num + 1:_column_range = src.shape[1] - temp_column_num + 1match_points = []for i in range(_line_start, _line_range, 1):for j in range(_column_start, _column_range, 1):_src = src[i:i + temp_row_num, j:j + temp_column_num].reshape(1, -1)[0]src_sum = []for item in circular_projection_data:src_sum.append(np.sum(_src[item]))_src_sum = np.array(src_sum)src_mean = np.mean(_src_sum)src_deviation_array = _src_sum - src_meanncc_numerator = np.vdot(src_deviation_array, temp_deviation_array)src_deviation = np.dot(src_deviation_array, src_deviation_array)ncc_denominator = np.sqrt(temp_deviation * src_deviation)ncc_value = ncc_numerator / ncc_denominatorif ncc_value > threshold:match_point = {'match_score': ncc_value, 'point': (j, i)}match_points.append(match_point)return match_pointsdef ncc_match(src, temp, is_rotate=False, downsamplingtime=0, threshold=0.7, angle_start=0, angle_end=0,match_region=None):assert temp.shape[0] <= src.shape[0] and temp.shape[1] <= src.shape[1]temp_downsampling_data = generate_temp_data(temp, downsamplingtime, is_rotate)src_down_sampling_array = []src_down_sampling_array.append(src)for i in range(1, downsamplingtime + 1):src_down_sampling_array.append(cv2.pyrDown(src_down_sampling_array[i - 1]))match_points = []downsample_match_point = Nonefor i in range(downsamplingtime, -1, -1):match_offset = 2 ** (i + 1)if i == downsamplingtime:match_region = [0, 0, src_down_sampling_array[i].shape[1], src_down_sampling_array[i].shape[0]]else:_x, _y, _w, _h = 0, 0, 0, 0if downsample_match_point[0] * 2 - match_offset >= 0:_x = downsample_match_point[0] * 2 - match_offset_w = match_offset * 2 + 1else:_x = 0_w = match_offset + 1if downsample_match_point[1] * 2 - match_offset >= 0:_y = downsample_match_point[1] * 2 - match_offset_h = match_offset * 2 + 1else:_y = 0_h = match_offset + 1match_region = [_x, _y, _w, _h]if not is_rotate:_match_points = ncc_unrotate_match(src_down_sampling_array[i],temp_downsampling_data[i], match_region=match_region,threshold=threshold)else:_match_points = ncc_rotate_match(src_down_sampling_array[i],temp_downsampling_data[i], match_region=match_region,threshold=threshold)if i == 0:match_points = _match_pointsif len(_match_points) != 0:###利用上一层的最佳匹配值来作为下一层匹配的种子点###downsample_match_point = sorted(_match_points, key=lambda _point: _point['match_score'], reverse=True)[0]['point']else:breakreturn match_pointsdef draw_result(src, temp, match_point):src = cv2.cvtColor(src, cv2.COLOR_GRAY2RGB)cv2.rectangle(src, match_point,(match_point[0] + temp.shape[1], match_point[1] + temp.shape[0]),(0, 255, 0), 1)cv2.imshow('temp', temp)cv2.imshow('result', src)cv2.waitKey()if __name__ == '__main__':src = cv2.imread('img/1.jpg', cv2.IMREAD_GRAYSCALE)temp = cv2.imread('img/temp.png', cv2.IMREAD_GRAYSCALE)downsamplingtime = 4threshold = 0.7is_rotate = Truematch_points = ncc_match(src, temp, is_rotate=is_rotate, threshold=threshold, downsamplingtime=downsamplingtime)if len(match_points) != 0:best_match_point = sorted(match_points, key=lambda _point: _point['match_score'], reverse=True)[0]print(best_match_point)draw_result(src, temp, best_match_point['point'])else:print("no match point")

代码下载地址:opencvpython实现NCC旋转匹配_快速旋转匹配opencvpython-图像处理文档类资源-CSDN下载

python+opencv实现NCC模板旋转匹配(图像处理)相关推荐

  1. python opencv屏幕找图_使用Python+OpenCV进行图像模板匹配(Match Template)实例-找到百度首页按钮并点击...

    意图:准备一张小图,在电脑屏幕上找到小图坐标,并点击. 1  安装 opencv 和 numpy: pip3 install opencv-python 上述命令将 opencv 和 numpy都安装 ...

  2. 重磅升级,52个Python+OpenCV实战项目教你掌握图像处理

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 近期小白学视觉公众号推出了多篇Python+OpenCV实战项目的 ...

  3. Python OpenCV 修改一寸照片底色,图像处理取经之旅第 20 天

    昨天写美女换装案例的时候,忽然间想到,相同的代码可以复用照片底色中,所以本文继续夯实一下对应的效果吧. 本案例使用的素材来源网络,如有侵权,联系橡皮擦删除 二值化参数调整 使用上篇博客,实现的一个小功 ...

  4. python opencv图片拼接、特征点匹配

    一.算法目的: 在同一位置拍摄的两幅或者多幅图像是单应性相关的的,使用该约束将很多图片缝补起来,拼成一个大的图像来创建全景图像.两张图片的拼接必须首先找到相同特征,也就是说两张照片必须要有重叠的部分才 ...

  5. Python+Opencv实现图像匹配——模板匹配

    1.原理 简单来说,模板匹配就是拿一个模板(图片)在目标图片上依次滑动,每次计算模板与模板下方的子图的相似度,最后就计算出了非常多的相似度: 如果只是单个目标的匹配,那只需要取相似度最大值所在的位置就 ...

  6. Python OpenCV 实现对图片旋转矩形的裁剪

    前言: 最近需要实现一个在一张大图上给定一个带方向的点,以这个点为中心,以方向为角度裁剪出一个矩形区域.在网上查到很多方法都是先对大图像进行旋转,再从中切片取出目标区域.不失为一个好办法,但是我要处理 ...

  7. python opencv特征点检测和匹配教程

    导入相关的包 import cv2 import numpy as np import random import os import matplotlib.pyplot as plt from ti ...

  8. python opencv显示图片动态_opencv-python计算机视觉图像处理学习笔记2——打开图片,保存图片,显示图片...

    用到的函数:imread(读取).imwrite(保存)和imshow(显示) 1.打开VS code,如图 2.左上角新建文件,出现Untitled-1,输入代码: import cv2       ...

  9. python图片旋转脚本_Python+OpenCV 实现图片无损旋转90°且无黑边

    0. 引言 有如上一张图片,在以往的图像旋转处理中,往往得到如图所示的图片. 然而,在进行一些其他图像处理或者图像展示时,黑边带来了一些不便.本文解决图片旋转后出现黑边的问题,实现了图片尺寸不变的旋转 ...

最新文章

  1. 转帖-Linux 磁盘坏道检测和修复
  2. mysql 分区表 归档_MySQL分区表
  3. 在matlab中如何使用SVM工具箱
  4. 图片服务 - thumbor用法
  5. python pso_利用python实现PSO算法优化二元函数
  6. 动机的寓言:孩子为谁在玩
  7. Google及其云智慧
  8. MyBatis插件开发:简单分页插件
  9. MT4MT5跟单EA系统跨平台
  10. u盘写保护+计算机管理,电脑如何去除u盘写保护?
  11. 中国长白山国际林海雪地马拉松节将于三月底举办
  12. 51CTO学院 oracle相关视频地址
  13. 浏览器主页被劫持篡改了怎么办
  14. JAVA四大名著(程序员必读)
  15. 关于js中0==‘‘判断为True
  16. 时间复杂度O(1),O(n),O(logn),O(nlogn)的意思
  17. python中字符串转数组、数组转字符串
  18. Android开源项目 个性化控件(View)
  19. 何为Robocode
  20. 栈和队列:魔王语言解释

热门文章

  1. oracle完整建表,Oracle数据库建表完整sql
  2. 数字电路基础知识——组合逻辑电路(奇偶校验电路、数据比较器的设计)
  3. JAVAWEB之JSTL标签
  4. VMware中ubuntu设置成中文
  5. IDEA解决开两个窗口问题
  6. vue中用ref实现父子组件、孙组件、兄弟组件、非亲子孙组件互相调用的方法
  7. IP-guard文档透明加密——加密文件外发管理
  8. 【备忘】Mongodb/Redis/HBase NoSql视频教程2017数据库自学教程
  9. Maven使用(一)
  10. web前端学习路线(含20个真实web开发项目集合)