OpenCV系列(九)图像仿射变换
无论是在人脸识别或者跟踪领域,还是在图像处理领域,在我们做训练或者分析局部数据之前,都需要把对应的图像数据提取出来。但是在实际情况中,我们不一定每次都能找到水平的预测框,例如在OCR识别中,我们检测到的文字事实上可能是歪的。这时候就需要反射变化将歪的图片转换成正的,以供我们进行下一步的训练或识别。
● 场景模拟
首先,我们使用Opencv模拟出一个斜着的矩形框,并且提取出矩形框四个角的坐标,代码如下:
import cv2
import numpy as np
def get_point(th):
boxes=[]
contours, _ = cv2.findContours(th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) > 120000:
continue
else:
rect = cv2.minAreaRect(contour)
boxs = cv2.boxPoints(rect)
for index ,value in enumerate(boxs):
print(value)
x,y=value
boxes.append([int(x),int(y)])
cv2.circle(img,(x,y),1,(0,255,0))
cv2.putText(img,'%s'%index,(x,y),
cv2.FONT_HERSHEY_COMPLEX,.5,(255,0,0),1)
return boxes
if __name__ == '__main__':
img=cv2.imread('opencv_image/range_back.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur=cv2.GaussianBlur(gray,(5,5),0)
_,th=cv2.threshold(blur,0,255,cv2.THRESH_BINARY)
points=get_point(th)
cv2.imshow('img',img)
cv2.waitKey(0)
程序运行结果如下,在一张白色为底色的带有旋转方框的图片中,我们取到了4个顶点的坐标,分别为:左下角、左上角、右上角、右下角:
● 放射变换
取得这些坐标后,我们就可以对图中的矩形进行矫正,把矩形变为水平的,并提取出来。使用的代码如下:
if __name__ == '__main__':
img=cv2.imread('opencv_image/range_back.jpg')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur=cv2.GaussianBlur(gray,(5,5),0)
cv2.threshold(blur,0,255,cv2.THRESH_BINARY) =
points=get_point(th)
# 只需要3个点就可以进行仿射变换
points=np.array(points,np.float32)[:-1]
# 图片反射变换之后的对应坐标系 位置与获取的点的位置相同
new_point = np.array([[0, 150], [0, 0], [250,0]], np.float32)
A1 = cv2.getAffineTransform(points, dst=new_point)
d1=cv2.warpAffine(img,A1,(250,150),borderValue=125)
cv2.imshow('img',img)
cv2.imshow('s',d1)
cv2.waitKey(0)
运行程序的结果为如下,我们把非水平的矩形提取出来,变成水平的矩形,但是这需要最少3个坐标才能完成仿射变换:
函数解析: cv2.getAffineTransform(src, dst)
作用:生成仿射变换矩阵
src | 输入的3个点 |
dst | 输出的3个点 |
函数解析:cv2.warpAffine(img,M,dsize,borderValue)
作用:进行仿射变换
img | 输入图像 |
M | 变换矩阵 |
dsize | 输出的图片大小 |
borderValue | 边框填充,默认为0 |
评论