opencv平移、旋转图片以及变换后图片像素对应关系

32 篇文章 1 订阅
13 篇文章 1 订阅

        图像的平移,旋转变换以及仿射与投影都需要先定义转换矩阵,然后使用cv2.warpAffine()根据变换矩阵完成转换。

imgRotation = cv2.warpAffine(img, mat,(widthNew,heightNew),borderValue=(255,255,255))

其中,参数的定义如下表:

img需要变换的图像
mat转换矩阵
(widthNew,heightNew)转换后图像尺寸
borderValue=(255,255,255)转换后空白区域填充色

 返回值imgRotation 就是转换后的图像。

        注:转换矩阵mat可以自己定义也可以直接使用opencv内置的函数得到想要的转换矩阵。一般直接使用opencv的内置函数比较方便。

一、图像平移变换

        平移变换就是像素坐标x,y的加减运算,假设有两个点坐标pt1=(x1,y1),pt2=(x2,y2)。平移转换矩阵可以定义为TranslationMatrix =[[1, 0, 100],[0, 1, 50]]。

        左乘转换矩阵可以得到平移变换后的坐标值,矩阵运算的过程如下,其他旋转转换矩阵运算类似。
 

二、图像旋转变换

        图像旋转变换需要先确定旋转中心,旋转角度。如果使用图像某一角作为旋转中心会出现某点落在同一位子,某些位子是空白的问题。为避免这个问题,通常使用图像的中心作为旋转中心。

        旋转矩阵可由cv2.getRotationMatrix2D()得到,主要degree是角度值,不是弧度值。

cv2.getRotationMatrix2D((width//2, height//2), degree, 1)

        下面给出给定图像和旋转角度求旋转后图像的例子:

def dumpRotateImage(img,degree):
 
    height, width = img.shape[:2]
    heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
    widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
    matRotation = cv2.getRotationMatrix2D((width//2, height//2), degree, 1)
    imgRotation = cv2.warpAffine(img, matRotation,(widthNew,heightNew),borderValue=(255,255,255))
 
    return imgRotation

其中,heightNew和widthNew是旋转后图像的新尺寸。matRotation是以图像为中心,角度为degree的旋转矩阵。然后使用cv2.warpAffine()以该旋转矩阵旋转图像,这里需要注意必须使用原图像为旋转中心,旋转后的图像是,可以看到有部分图像像素点落在了图像区域外。这是由于新图像以原图像的为中心旋转会导致部分像素点旋转后落在图像外。为避免这个问题可以在该旋转矩阵中加入平移操作,使得原图旋转后完全落在图像图像中。

代码:

def dumpRotateImage(img,degree):
 
    height, width = img.shape[:2]
    heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
    widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
    matRotation = cv2.getRotationMatrix2D((width//2, height//2), degree, 1)
 
  #加入平移操作
    matRotation[0,2] += (widthNew - width)//2
    matRotation[1,2] += (heightNew - height)//2
 
    imgRotation = cv2.warpAffine(img, matRotation,(widthNew,heightNew),borderValue=(255,255,255))
 
    return imgRotation

三、图像旋转前后的坐标映射关系

(1)原图像某点坐标P -> 旋转后图像坐标Q

        假设某点坐标为P(x,y),旋转矩阵为matRotation,旋转后图像坐Q可直接有P左乘matRotation得到。

Q = np.dot(MatRotation,np.array([[P[0]],[P[1]],[1]]))

(2)旋转后图像坐标Q -> 原图像某点坐标P

        可以使用cv2.invertAffineTransform得到变换矩阵的逆矩阵reverseMatRotation。假设旋转后图像某点坐标值为Q(x,y),旋转矩阵逆矩阵为reverseMatRotation,在原图像中的坐标可有Q左乘reverseMatRotation得到。如下:

reverseMatRotation = cv2.invertAffineTransform(matRotation)
P = np.dot(reverseMatRotation,np.array([[Q[0]],[Q[1]],[1]]))

四、完整例子

代码:

import cv2
from math import *
import numpy as np
 
def dumpRotateImage(img,degree):
 
    height, width = img.shape[:2]
    heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
    widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
    matRotation = cv2.getRotationMatrix2D((width//2, height//2), degree, 1)
    #matRotation[0,2] += (widthNew - width)//2
    #matRotation[1,2] += (heightNew - height)//2
    imgRotation = cv2.warpAffine(img, matRotation,(widthNew,heightNew),borderValue=(255,255,255))
 
    matRotation2 = cv2.getRotationMatrix2D((widthNew//2, heightNew//2), degree, 1)
    imgRotation2 = cv2.warpAffine(img, matRotation2, (widthNew, heightNew), borderValue=(255, 255, 255))
    return imgRotation,imgRotation2, matRotation
 
 
def draw_box(img,box):
    cv2.line(img, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 3)
    cv2.line(img, (box[0], box[1]), (box[4], box[5]), (0, 255, 0), 3)
    cv2.line(img, (box[2], box[3]), (box[6], box[7]), (0, 255, 0), 3)
    cv2.line(img, (box[4], box[5]), (box[6], box[7]), (0, 255, 0), 3)
    return img
 
image = cv2.imread('/home/fangsh/Pictures/timg.jpeg')
imgRotation, imgRotation2, matRotation = dumpRotateImage(image, 45)
box = [200,250,250,200,230,280,280,230]
 
reverseMatRotation = cv2.invertAffineTransform(matRotation)
pt1 = np.dot(reverseMatRotation,np.array([[box[0]],[box[1]],[1]]))
pt2 = np.dot(reverseMatRotation,np.array([[box[2]],[box[3]],[1]]))
pt3 = np.dot(reverseMatRotation,np.array([[box[4]],[box[5]],[1]]))
pt4 = np.dot(reverseMatRotation,np.array([[box[6]],[box[7]],[1]]))
 
print(pt1, pt2, pt3, pt4)
box2 = [pt1[0],pt1[1],pt2[0],pt2[1],pt3[0],pt3[1],pt4[0],pt4[1]]
 
cv2.imwrite('/home/fangsh/drawBox.png',draw_box(imgRotation,box))
cv2.imwrite('/home/fangsh/raw.png',draw_box(image,box2))
#cv2.waitKey(0)

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV 是一个开源的计算机视觉库,其提供了丰富的图像处理和计算机视觉算法。其中一个常用的功能是模板匹配,它可以在给定的图像中查找与目标模板最匹配的位置。 模板匹配通常用于在图像中定位特定的对象,例如在一张照片中找到人脸、车辆或其他特定的物体。模板匹配基于计算目标模板与输入图像各个位置的相似度,并找到最匹配的位置。 在模板匹配中,模板图像是我们要在输入图像中查找的目标对象图像。匹配过程中,模板会在输入图像的各个位置上滑动,计算模板与输入图像对应区域的相似度。常用的相似度度量方法有平方差匹配(Squared Difference)、相关性匹配(Correlation)和归一化相关性匹配(Normalized Correlation)等。 在实际应用中,模板匹配可能会出现对象旋转平移的情况。为了解决旋转平移带来的匹配问题,可以通过对模板图像进行旋转平移变换,使其与输入图像更好地对齐。OpenCV 提供了旋转平移变换相关的函数,如 `cv2.getRotationMatrix2D` 和 `cv2.warpAffine`,可以方便地旋转平移模板图像。 通过旋转平移变换,我们可以将模板图像校正为与输入图像对齐的形式。然后再进行模板匹配,即可得到比较准确的匹配结果。需要注意的是,在进行旋转平移变换时,需要确定旋转角度和平移距离的参数,这需要根据实际情况进行调整。 综上所述,OpenCV 提供了丰富的功能用于模板匹配,并且可以通过旋转平移变换对模板图像进行调整以适应旋转平移的情况。这些功能在计算机视觉和图像处理领域有着广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值