主要流程:
1.首先得到灰度图像
2.对灰度图像进行二值化
3.然后找一个最小矩形框住对象轮廓(opencv中有相应的函数)
4.这个最小矩形的函数会返回一个角度
5.我们利用这个角度得到一个旋转的矩形(仿射变换所需要的)
6.使用仿射变换得到矫正后的图像
1.得到灰度图像
//读取图像
src= cv.imread('imageTextR.png')
(h,w)=src.shape[:2]
//记录图像宽高,后面会用
//cv.imshow('src',src)
//cvtColor函数用于转换色彩空间,将图像转换为GRAY灰度图像
gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
这是我们需要矫正的图像
2.对灰度图像进行二值化
ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
#由于文本是黑底白字的,我们需要让背景是黑色的,所以我们在传入参数的时候需要使用cv.THRESH_BINARY_INV 加上_INV使二值图反转
这是二值图
3.找一个最小矩形框住对象轮廓
coords=np.column_stack(np.where(binary>0))
np.where(binary>0):可以理解为找出二值图中所有的白色
np.column_stack(np.where(binary>0)):将所有白色的像素统计起来
这里可以看到返回的coords的大小是(24527,2)即二值图中共有24527个白色像素点。
4.得到矩形角度
接下使用cv的minAreaRect函数求出最小外接矩形,传入的参数要求为点集数组或向量。返回的参数有三个:1.矩形的中心点 2.矩形的长和宽 3.矩形的旋转角度
angle =cv.minAreaRect(coords)[-1]
//[-1]表示返回参数中的最后一个,即角度
角度是根据这个规则来的:
这里我们默认倾斜角度不是特别大,所以如果我们的倾斜角度大于-45度我们就将其矫正为水平的,如果小于-45度我们将其矫正为垂直的:
if angle<-45:
angle = -(90+angle)
else:
angle=-angle
center = (w//2,h//2)
//求出矩形中点
5.我们利用这个角度得到一个旋转变换的矩形(仿射变换所需要的)
使用cv.getRotationMatrix2D()来得到选择最小外接旋转矩形,3个参数分别为旋转中心,旋转角度,旋转后图像的缩放比例
M= cv.getRotationMatrix2D(center,angle,1.0)
6.使用仿射变换得到矫正后的图像
使用cv.warpAffine来进行仿射变换,传入参数为:需要处理的图像,旋转变换矩阵,宽高,flags:插值方法,borderMode:边界填充
rotated = cv.warpAffine(src,M,(w,h),flags=cv.INTER_CUBIC,borderMode=cv.BORDER_REPLICATE)
得到的矫正后的图片
如果觉得有用 点个赞哦 谢谢啦
最后附上完整代码:
import numpy as np
import cv2 as cv
def binary(img):
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,binary = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
return binary
def Transformation(img,src):
coords=np.column_stack(np.where(img>0))
print(coords)
print(coords.shape)
angle =cv.minAreaRect(coords)[-1] #最小外接矩形
print(angle)
if angle<-45:
angle = -(90+angle)
else:
angle=-angle
center = (w//2,h//2)
M= cv.getRotationMatrix2D(center,angle,1.0) #传入中心和角度 得到旋转矩形
rotated = cv.warpAffine(src,M,(w,h),flags=cv.INTER_CUBIC,borderMode=cv.BORDER_REPLICATE)
cv.putText(rotated,'Angle:{:.2f} degrees'.format(angle),(10,30),cv.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)#绘制文字
cv.imshow('Rotated',rotated)
src= cv.imread('imageTextR.png')
(h,w)=src.shape[:2]
gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
binary=binary(src)
Transformation(binary,src)
cv.imshow('src',src)
cv.imshow('binary',binary)
cv.waitKey(0)