OpenCV图像处理

OpenCV图像处理

图像的几何变换

Opencv提供两种变换函数,cv2.warpAffine()cv2.warpPerspective()。基于这两个函数可以得到所有类型的变换。

  • cv2.warpAffine() 以一个 2 × 3 2 \times 3 2×3变换矩阵为输入
  • cv2.warpPerspective() 以一个 3 × 3 3 \times 3 3×3变换矩阵为输入

转换

转换(Translation)是物体位置的转移。如果在 ( x , y ) \left( x, y \right) (x,y)方向上的偏移量为 ( t x , t y ) \left( t_{x}, t_{y} \right) (tx,ty),那么变换矩阵 M M M可如下定义。将 M M M以类型为np.float32的numpy数组表示,然后将其传入到cv2.warpAffine() 函数中
M = [ 1 0 t x 0 1 t y ] M = \left [ \begin{matrix} 1 & 0 & t_{x}\\ 0 & 1 & t_{y} \end{matrix} \right ] M=[1001txty]

import cv2
import numpy as np
img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
# 偏移量为(100,50)
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

偏移

旋转

得到一个旋转角度为 θ \theta θ的图像的变换矩阵 M M M定义如下:
M = [ c o s θ − s i n θ s i n θ c o s θ ] M = \left [ \begin{matrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{matrix} \right ] M=[cosθsinθsinθcosθ]
OpenCV提供了可调整旋转中心的缩放旋转,以至于可以以任何位置为中心旋转。调整后的变换矩阵定义如下:
M = [ α β ( 1 − α ) ⋅ c e n t e r . x − β ⋅ c e n t e r . y − β α β ⋅ c e n t e r . x + ( 1 − α ) ⋅ c e n t e r . y ] M = \left [ \begin{matrix} \alpha & \beta & \left( 1- \alpha \right) \cdot center.x - \beta \cdot center.y \\ -\beta& \alpha & \beta \cdot center.x + \left( 1- \alpha \right) \cdot center.y \end{matrix} \right ] M=[αββα(1α)center.xβcenter.yβcenter.x+(1α)center.y]
其中
α = s c a l e ⋅ c o s θ β = s c a l e ⋅ s i n θ \begin{matrix} \alpha = scale \cdot cos \theta \\ \beta = scale \cdot sin\theta \end{matrix} α=scalecosθβ=scalesinθ
Opencv提供了cv2.getRotationMatrix2D()函数寻找变换矩阵。

img = cv2.imread('messi5.jpg',0)
rows,cols = img.shape
# 没有缩放,旋转图像90度
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img,M,(cols,rows))

旋转

仿射变换

仿射变换(Affine Transformation)是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。那么每个仿射变换可以由一个矩阵 A A A和一个向量 b b b给出,假设原图像为 X X X,目标图像为 Y Y Y,仿射变换可用公式表示为 Y = A ⋅ X + b Y = A \cdot X + b Y=AX+b

仿射变换,在原图中所有平行的线条在输入图像中仍然平行。OpenCV提供了cv2.getAffineTransform()函数得到一个 2 × 3 2 \times 3 2×3的变换矩阵,传送给cv2.warpAffine() 函数。

为了得到变换矩阵,需要原图中的三个点和这三个点在输出图像中的位置。

img = cv2.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
dst = cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

仿射

透视变换

透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。 --百度百科

透视变换需要一个 3 × 3 3 \times 3 3×3大小的变换矩阵。为了得到变换矩阵,需要原图中的四个点和这三个点在输出图像中的相应位置。并且四个点中的三个不能在一条直线上。OpenCV提供cv2.getPerspectiveTransform() 函数得到变换矩阵,然后传送给cv2.warpPerspective() 函数。

img = cv2.imread('sudokusmall.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

透视变换

边框矩形

边框矩形有两种形式,一种是直边矩形(Straight Bounding rectangle),一种是最小面积的边框矩形,被称为旋转矩形(Rotated Rectangle)。直边矩形不考虑物体的角度,因此,直边矩形的面积不是最小的。旋转矩形考虑物体的旋转角度。下图中的青色矩形就是直边矩形,红色矩形是旋转矩形。

边框矩形

直边矩形

OpenCV中提供了**cv2.boundingRect()**函数提供直边矩形。

# x,y是矩形的左上坐标,w,h是宽和高
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

旋转矩形

OpenCV中提供cv2.minAreaRect() 函数提供旋转矩形。返回左上坐标为 ( x , y ) \left( x,y\right) (x,y),宽和高为 ( w , h ) \left( w, h\right) (w,h),旋转角度为 θ \theta θ的2D边框。为了能够绘制矩形,需要借助cv2.boxPoints()函数得到矩形的4个角坐标。

rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
im = cv2.drawContours(im,[box],0,(0,0,255),2)

参考

  1. OpenCV-Python Tutorials Documentation
  2. 仿射变换
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马鹤宁

谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值