计算机视觉--opencv---如何识别不同方向图片的识别

发布于:2025-09-14 ⋅ 阅读:(23) ⋅ 点赞:(0)

数据准备:

jt.jpg

jiant.jpg

一、使用 OpenCV 实现多模板匹配

步骤和原理:
  1. 读取图像和模板:首先需要加载待检测的原始图像和作为模板的图像
  2. 选择匹配方法:OpenCV 提供了多种匹配算法(如 TM_CCOEFF、TM_CCOEFF_NORMED 等)
  3. 执行模板匹配:使用 cv2.matchTemplate() 函数进行匹配计算
  4. 设置阈值筛选结果:通过设定合适的阈值,找出所有匹配度高于阈值的区域
  5. 处理重叠区域:如果匹配结果有重叠,通常保留匹配度最高的区域
示例代码
import  cv2
import  numpy as np

img_rgb = cv2.imread('jiant.jpg')
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)
template = cv2.imread('jt.jpg',0)
h,w = template.shape[:2]

res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)

threshold = 0.9

loc = np.where(res>=threshold)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb,pt,(pt[0]+w,pt[1]+h),(0,0,255),1)

cv2.imshow('1',img_rgb)
cv2.waitKey(0)

二、opencv图像旋转

这里介绍的是固定角度旋转,非特定角度需要详解数学原理,后面再介绍

固定角度旋转的技术特性

固定角度旋转(90°、180°、270°)与任意角度旋转相比,具有独特的技术优势:

  • 像素位置可预测:旋转后每个像素的新位置是整数坐标,无需复杂的插值计算(仅在边缘处理时可能用到简单插值)
  • 画布尺寸确定性变化:旋转后图像的宽高比会按规律变化(90° 和 270° 旋转时宽高互换,180° 旋转时尺寸不变)
  • 计算效率极高:底层采用矩阵转置等优化算法,避免了三角函数运算,速度比任意角度旋转快 10 倍以上
  • 无信息丢失:完整保留原始图像的所有像素信息,不会因旋转角度导致内容裁剪(除非主动设置)
cv2.rotate () 函数深度解析

函数原型与参数说明

rotated_img = cv2.rotate(src, rotateCode)
  • src:输入图像,必须是 numpy 数组格式(ndarray),可以是单通道(灰度图)、三通道(彩色图)或四通道(带 alpha 通道的图像)

  • rotateCode:旋转模式参数,决定旋转方向和角度,仅支持以下三个预定义值:

    • cv2.ROTATE_90_CLOCKWISE:顺时针旋转 90°
    • cv2.ROTATE_180:顺时针旋转 180°(与逆时针旋转 180° 结果相同)
    • cv2.ROTATE_90_COUNTERCLOCKWISE:逆时针旋转 90°(等价于顺时针旋转 270°)
  • 返回值:旋转后的图像,与输入图像具有相同的数据类型和通道数

旋转模式的底层实现机制
  1. 顺时针旋转 90°(ROTATE_90_CLOCKWISE)

    • 实现原理:先对图像进行转置(transpose),再进行水平翻转(flip)
    • 尺寸变化:原图像 (w, h) → 旋转后 (h, w)
    • 数学表达:新坐标 (x', y') 与原坐标 (x, y) 的关系为 x' = y,y' = w-1-x
  2. 180° 旋转(ROTATE_180)

    • 实现原理:对图像进行两次水平翻转(或两次垂直翻转),或直接反转像素顺序
    • 尺寸变化:原图像 (w, h) → 旋转后 (w, h)(尺寸不变)
    • 数学表达:新坐标 (x', y') 与原坐标 (x, y) 的关系为 x' = w-1-x,y' = h-1-y
  3. 逆时针旋转 90°(ROTATE_90_COUNTERCLOCKWISE)

    • 实现原理:先对图像进行转置(transpose),再进行垂直翻转(flip)
    • 尺寸变化:原图像 (w, h) → 旋转后 (h, w)
    • 数学表达:新坐标 (x', y') 与原坐标 (x, y) 的关系为 x' = h-1-y,y' = x

示例代码:

import cv2
import numpy as np
# 方法一
img = cv2.imread('./jt.jpg')
# 旋转 90 度, k=-1 表示顺时针旋转 90 度
rotated_image1 = np.rot90(img, k=-1)
# 旋转 90 度, k=1 表示逆时针旋转 90 度
rotated_image2 = np.rot90(img, k=1)

cv2.imshow(winname='yuantu', mat=img)
cv2.imshow(winname='rotated_image1', mat=rotated_image1)
cv2.imshow(winname='rotated_image2', mat=rotated_image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 方法二
rotated_image = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)  # 顺时针90度
rotated_image1 = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)  # 逆时针90度
rotated_image2 = cv2.rotate(img, cv2.ROTATE_180)  # 旋转180度
cv2.imshow(winname='shun90', mat=rotated_image)
cv2.imshow(winname='ni90', mat=rotated_image1)
cv2.imshow(winname='180', mat=rotated_image2)
cv2.waitKey(0)

三、实现图片中多角度识别的案例

需要实现在大图片中识别不同角度的小图片

  1. 读取图像文件

    img_rgb = cv2.imread('jiant.jpg')  # 读取原始彩色图像
    img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)  # 转换为灰度图
    template = cv2.imread('jt.jpg',0)  # 读取模板图像,0表示以灰度模式读取
    
  2. 生成旋转后的模板

    image1 = np.rot90(template, k=-1)  # 将模板逆时针旋转90度
    image2 = np.rot90(template, k=1)   # 将模板顺时针旋转90度
    
  3. 定义匹配函数ping

    def ping(template,img_rgb):
        h, w = template.shape[:2]  # 获取模板的高度和宽度
        # 使用归一化相关系数方法进行模板匹配
        res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
        threshold = 0.9  # 匹配阈值,只保留匹配度大于等于0.9的结果
        loc = np.where(res >= threshold)  # 找到所有匹配度超过阈值的位置
        
        # 遍历所有匹配位置,绘制矩形标记
        for pt in zip(*loc[::-1]):
            cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 1)
    
  4. 执行匹配并显示结果

    ping(template,img_rgb)   # 用原始模板匹配
    ping(image1,img_rgb)     # 用逆时针旋转90度的模板匹配
    ping(image2,img_rgb)     # 用顺时针旋转90度的模板匹配
    
    cv2.imshow('1',img_rgb)  # 显示标记后的图像
    cv2.waitKey(0)           # 等待用户按键,保持窗口显示

完整代码

import  cv2
import  numpy as np

img_rgb = cv2.imread('jiant.jpg')
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)
template = cv2.imread('jt.jpg',0)

image1 = np.rot90(template, k=-1)
image2 = np.rot90(template, k=1)

def ping(template,img_rgb):
    h, w = template.shape[:2]
    res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
    threshold = 0.9
    loc = np.where(res >= threshold)
    for pt in zip(*loc[::-1]):
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 1)

ping(template,img_rgb)
ping(image1,img_rgb)
ping(image2,img_rgb)
cv2.imshow('1',img_rgb)
cv2.waitKey(0)

结果: