OpenCV系列(九)图像仿射变换

共 2238字,需浏览 5分钟

 ·

2021-03-26 12:28

无论是在人脸识别或者跟踪领域,还是在图像处理领域,在我们做训练或者分析局部数据之前,都需要把对应的图像数据提取出来。但是在实际情况中,我们不一定每次都能找到水平的预测框,例如在OCR识别中,我们检测到的文字事实上可能是歪的。这时候就需要反射变化将歪的图片转换成正的,以供我们进行下一步的训练或识别。


● 场景模拟

首先,我们使用Opencv模拟出一个斜着的矩形框,并且提取出矩形框四个角的坐标,代码如下:

import cv2import 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 # 获得最小外接矩形的4个坐标 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 boxesif __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)    _,th=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



浏览 43
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报