python +opencv 多尺度缩放与旋转的模板匹配

这篇具有很好参考价值的文章主要介绍了python +opencv 多尺度缩放与旋转的模板匹配。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#python opencv 多尺度,平移,缩放,旋转等模板匹配法
##多尺度缩放与旋转的均为模板图
import cv2
import numpy as np
import pandas as pd
import time


# 图片旋转函数-保持图像不被裁剪且去除黑边
def ImageRotate(img, angle,borderValue=255):   # img:输入图片;newIm:输出图片;angle:旋转角度(°)
    height, width = img.shape[:2]  # 输入(H,W,C),取 H,W 的值
    center = (width // 2, height // 2)  # 绕图片中心进行旋转
    M = cv2.getRotationMatrix2D(center, -angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
    nW = int((height * sin) + (width * cos))
    nH = int((height * cos) + (width * sin))
    M[0, 2] += (nW / 2) - center[0]
    M[1, 2] += (nH / 2) - center[1]
    image_rotation = cv2.warpAffine(img, M, (nW, nH),borderValue=borderValue)
    return image_rotation

#金字塔下采样---弃用(没进行深入理解)
def ImagePyrDown(image,NumLevels):
    for i in range(NumLevels):
        image = cv2.pyrDown(image)       #pyrDown下采样
    return image


# 旋转匹配函数(输入参数分别为模板图像、待匹配图像)
def RatationMatch(modelpicture, searchpicture):
    searchtmp, modeltmp = searchpicture.copy(),modelpicture.copy()

    # 使用matchTemplate对原始灰度图像和图像模板进行匹配
    mask = np.zeros_like(modeltmp, np.uint8)
    pts = np.where(modeltmp == 0)
    mask[pts[0], pts[1]] = 255
    print('searchtmp:',searchtmp.shape,modeltmp.shape)
    res = cv2.matchTemplate(searchtmp, modeltmp, cv2.TM_CCOEFF_NORMED,mask)
    min_val, max_val, min_indx, max_indx = cv2.minMaxLoc(res)
    location = max_indx
    temp = max_val
    angle = 0  # 当前旋转角度记录为0

    tic = time.time()
    # 以步长为5进行第一次粗循环匹配
    for i in range(-90, 181, 5):
        newIm = ImageRotate(modeltmp, i)
        mask = np.zeros_like(newIm, np.uint8)
        pts = np.where(newIm == 0)
        mask[pts[0], pts[1]] = 255
        #cv2.imshow('--mask', mask)
        #cv2.waitKey(0)
        #cv2.destroyAllWindows()
        #mask[newIm[:]==0]=255
        res = cv2.matchTemplate(searchtmp, newIm, cv2.TM_SQDIFF_NORMED,mask)
        min_val, max_val, min_indx, max_indx = cv2.minMaxLoc(res)
        #print(min_val, max_val, min_indx, max_indx)
        if max_val > temp:
            location = max_indx
            temp = max_val
            angle = i
            #print('angle:',angle)
            #draw_result(searchtmp, newIm, (location[0], location[1]))
            #modelpicture00 = ImageRotate(modelpicture, angle)
            #cv2.imshow('--modelpicture00', modelpicture00)
            #cv2.waitKey(0)
            #cv2.destroyAllWindows()
    toc = time.time()
    #ss = ImageRotate(modelpicture, angle)
    #draw_result(searchpicture, ss, (location[0],location[1]))

    print('第一次粗循环匹配所花时间为:' + str(1000 * (toc - tic)) + 'ms'+'------angle:'+str(angle))

    tic = time.time()
    # 在当前最优匹配角度周围10的区间以1为步长循环进行循环匹配计算
    for j in range(angle - 5, angle + 6):
        newIm = ImageRotate(modeltmp, j)
        #print('jj:',j)
        res = cv2.matchTemplate(searchtmp, newIm, cv2.TM_SQDIFF_NORMED)
        min_val, max_val, min_indx, max_indx = cv2.minMaxLoc(res)
        if max_val > temp:
            location = max_indx
            temp = max_val
            angle = j
            #print('angel2:',angle)
            #draw_result(searchtmp, newIm, (location[0], location[1]))
    toc = time.time()
    print('在当前最优匹配角度周围10的区间以1为步长循环进行循环匹配所花时间为:' + str(1000 * (toc - tic)) + 'ms'+'-----angle:'+str(angle))

    tic = time.time()
    # 在当前最优匹配角度周围2的区间以0.1为步长进行循环匹配计算
    k_angle = angle - 1
    for k in range(0, 19):
        k_angle = k_angle + 0.1
        #print('k_angle:',k_angle)
        newIm = ImageRotate(modeltmp, k_angle)
        res = cv2.matchTemplate(searchtmp, newIm, cv2.TM_SQDIFF_NORMED)
        min_val, max_val, min_indx, max_indx = cv2.minMaxLoc(res)
        if max_val > temp:
            location = max_indx
            temp = max_val
            angle = k_angle
            #draw_result(searchtmp, newIm, (location[0], location[1]))
    toc = time.time()
    print('在当前最优匹配角度周围2的区间以0.1为步长进行循环匹配所花时间为:' + str(1000 * (toc - tic)) + 'ms'+"---angle:"+str(angle))
    location_x = location[0]
    location_y = location[1]

    #angle = -angle
    match_point = {'angle': angle,"temp":temp, 'point': (location_x, location_y)}
    #print(match_point)
    return match_point

def scale_resize(img,scale):
    # 要缩小图像,建议选择:cv2.INTER_AREA;如果要放大图像,cv2.INTER_CUBIC效果更好但是速度慢
    if scale <= 1:
        method = cv2.INTER_AREA
    else:
        method = cv2.INTER_CUBIC
    newh = int(img.shape[1] * scale)
    neww = int(img.shape[0] * scale)
    new_dim = [neww, newh]
    resizedimg = cv2.resize(img, new_dim, method)
    return resizedimg

def run_main(templeimg, img):
    imgW,imgH = img.shape[0],img.shape[1]

    #初试:使用matchTemplate对原始灰度图像和图像模板进行匹配
    mask = np.zeros_like(templeimg, np.uint8)
    pts = np.where(templeimg == 0)
    mask[pts[0], pts[1]] = 255
    res = cv2.matchTemplate(img, templeimg, cv2.TM_CCOEFF_NORMED,mask)
    min_val, max_val, min_indx, max_indx = cv2.minMaxLoc(res)
    location_best = max_indx
    temp_best = max_val
    angle_best = 0  # 当前旋转角度记录为0
    best_scale_img = img.copy()
    #print(location_best)

    for scale in np.linspace(3.0, 0, 100)[::-1]:
        #要缩小图像,建议选择:cv2.INTER_AREA;如果要放大图像,cv2.INTER_CUBIC效果更好但是速度慢
        if scale<=1:
            method = cv2.INTER_AREA
        else:
            method = cv2.INTER_CUBIC
        newh = int(templeimg.shape[1]*scale)
        neww = int(templeimg.shape[0] * scale )
        new_dim = [neww,newh]

        # 业务要求:目标文件长度至少为img的宽的二分之一
        if max(neww,newh) <(min(img.shape[0],img.shape[1])/2):
            continue
        if (neww>imgW) or(newh>imgH) :
            continue

        resizedtempleimg = cv2.resize(templeimg, new_dim, method)
        resizedtempleimgcopy = resizedtempleimg.copy()
        # ------旋转匹配 match_point = {'angle': angle,"temp":temp, 'point': (location_x, location_y)}
        match_points = RatationMatch(resizedtempleimgcopy, img)
        temp = match_points['temp']
        angle = match_points['angle']
        point = match_points['point']
        if temp_best<temp:
            temp_best = temp
            location_best = point
            angle_best = angle
            best_temple_img1 = resizedtempleimg.copy()
            #print('scale:',scale)

    match_point_best = {'angle': angle_best, "temp": temp_best, 'point': (location_best[0], location_best[1]),'best_temple_img1':best_temple_img1}
    return match_point_best




# 画图
def draw_result(src, temp, match_point):
    print('match_point:',match_point,temp.shape)
    #cv2.circle(src, match_point, 3, 0, 2, 8, 0)
    cv2.rectangle(src, match_point,
                  (match_point[0] + temp.shape[1], match_point[1] + temp.shape[0]),
                  (0, 0, 0), 1)
    #con = np.hstack((src,temp))
    cv2.imshow('result', src)
    #cv2.imshow('temp', temp)
    cv2.waitKey()

if __name__ == '__main__':
    img = cv2.imread("./data/point_img.png", 0)
    templeimg = cv2.imread("./data/07point_temple.png", 0)
    cv2.imshow('img------ori', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    cv2.imshow('templeimg------ori', templeimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    #templeimg = ImageRotate(templeimg, 180)#顺时针
    #cv2.imshow('ImageRotate', templeimg)
    #cv2.waitKey(0)
    #cv2.destroyAllWindows()

    #主程序---旋转的为模板图,多尺度放大缩小的是模板图
    match_points =run_main(templeimg, img)
    best_temple_img1 = match_points["best_temple_img1"]
    print("主程序,最终返回结果:",match_points)

    #模型图像旋转最佳状态
    TmpImage= ImageRotate(best_temple_img1, match_points['angle'])
    cv2.imshow("TmpImage", TmpImage)
    cv2.waitKey()

    #画图最终结果
    draw_result(img, TmpImage, match_points['point'])
    
    #下一步计划:
        #根据模板识别的区域,对img的轮廓进行筛选
        #指针最准的角度为,针尖中心点的坐标


#传统的方法,还是需要大量的参数阈值控制,太鸡肋了,决定,只在数据量很少的冷启动项目阶段采用传统方式。文章来源地址https://www.toymoban.com/news/detail-563339.html

到了这里,关于python +opencv 多尺度缩放与旋转的模板匹配的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV中图像的缩放与旋转讲解及实战演示(附Python源码)

    需要源码请点赞关注收藏后评论区留言私信~~~ 几何变换是指改变图像的几何结构,例如大小、角度和形状等,让图像呈现出缩放、翻转、映射和透视效果。这些几何变换操作都涉及复杂、精密的计算,OpenCV将这些计算过程封装成非常灵活的方法,开发者只需修改一些参数,就

    2023年04月25日
    浏览(32)
  • OpenCV-Python中的图像处理-模板匹配

    使用模板匹配可以在一幅图像中查找目标 函数: cv2.matchTemplate(), cv2.minMaxLoc() 模板匹配是用来在一副大图中搜寻查找模版图像位置的方法。 OpenCV 为我们提供了函数: cv2.matchTemplate()。和 2D 卷积一样,它也是用模板图像在输入图像(大图)上滑动,并在每一个位置对模板图像

    2024年02月12日
    浏览(46)
  • 【opencv】教程代码 —Histograms_Matching(2)计算直方图、直方图比较、直方图均衡、模板匹配...

    计算直方图 直方图比较 图像进行直方图均衡化处理 模板匹配 1. calcHist_Demo.cpp 计算直方图 这段代码的功能是加载图像,分离图像的三个颜色通道,然后分别计算这三个通道的直方图,绘制出来并显示结果。直方图是图像中像素值分布的图形表示,可以用于图像分析或图像处

    2024年04月11日
    浏览(51)
  • 通过opencv实现图像的旋转、缩放

    用opencv来实现图像的旋转与缩放,代码如下: #include iostream #include opencv2/opencv.hpp using namespace cv; //#include opencv.hpp /*** (1). implementing Bilinear Interpolation ***/ bool BilinearInterpolation(     IplImage* pSrcImg,   //@pSrcImg : input gray image     IplImage* pDstImg,  //@pDstImg : output scaled gray image     

    2024年02月22日
    浏览(39)
  • 【OpenCV】图像变换(缩放、平移、旋转、仿射)

    图像变换是指通过对图像进行缩放、平移、旋转、仿射、透视等变换来改变图像的形状和大小。在本篇博客中,我们将详细介绍OpenCV中的图像变换函数,并提供示例代码以帮助读者更好地理解这些函数的使用方法。 缩放变换是指通过改变图像的大小来改变图像的形状。在Op

    2024年02月07日
    浏览(61)
  • OpenCV图像的仿射变换、旋转和缩放

    以下是对代码的逐行解释:

    2024年02月13日
    浏览(53)
  • opencv 图像的缩放(放大,缩小),翻转,旋转

    opencv 图像的缩放(放大,缩小),翻转,旋转 opencv 最常用的图像缩放方法是使用 cv2::resize() 函数,它需要指定输出图像的大小,和插值算法; opencv 最常用的图像翻转方法是使用 cv::flip() 函数,它需要指定图像翻转方式; opencv 最常用的图像旋转方法是使用 cv::warpAffine() 函数,

    2024年02月07日
    浏览(62)
  • opencv006图像处理之仿射变换(旋转,缩放,平移)

    空间变换中的仿射变换对应着五种变换,平移,缩放,旋转,翻转,错切。而这五种变化由原图像转变到变换图像的过程,可以用仿射变换矩阵进行描述。而这个变换过程可以用一个2*3的矩阵与原图进行相乘得到。关键就是这个矩阵M:  平移,旋转   透视 M: 变换矩阵 desi

    2024年01月21日
    浏览(52)
  • 计算机视觉CV领域中多尺度特征的概念

    知乎:深度学习中的多尺度模型设计 知乎:计算机视觉中的多尺度模型都有哪些设计? CSDN:多尺度理解  所谓多尺度,实际就是对信号的不同粒度的采样。 通常在不同的尺度下我们可以观察到不同的特征,从而完成不同的任务。 粒度更小/更密集的采样可以看到更多的细节

    2023年04月08日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包