import cv2 as cv
import numpy as np
src = cv.imread("../images/st_02.png")
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", src)
# 图像二值化
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3), (-1, -1))
binary = cv.morphologyEx(binary, cv.MORPH_OPEN, se)
cv.imshow("binary", binary)
# 轮廓提取, 发现最大轮廓
contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
index = 0
max = 0
for c in range(len(contours)):
area = cv.contourArea(contours[c])
if area > max:
max = area
index = c
# 寻找最小外接矩形
rect = cv.minAreaRect(contours[index])
print(rect[2])
print(rect[0])
# trick
height, width = rect[1]
print(rect[1])
box = cv.boxPoints(rect)
src_pts = np.int0(box)
print(src_pts)
dst_pts = []
dst_pts.append([width,height])
dst_pts.append([0, height])
dst_pts.append([0, 0])
dst_pts.append([width, 0])
# 透视变换
M, status = cv.findHomography(src_pts, np.array(dst_pts))
result = cv.warpPerspective(src, M, (np.int32(width), np.int32(height)))
if height < width:
result = cv.rotate(result, cv.ROTATE_90_CLOCKWISE)
cv.imshow("result", result)
cv.waitKey(0)
cv.destroyAllWindows()
对于很多的文本扫描图像,有时候因为放置的原因导致ROI区域倾斜,这个时候我们会想办法把它纠正为正确的角度视角来,方便下一步的布局分析与文字识别,这个时候通过透视变换就可以取得比较好的裁剪效果,一步就可以实现裁剪与调整。使用透视变换相关几何变换的好处如下:
retval, mask = cv.findHomography(srcPoints, dstPoints[, method[, ransacReprojThreshold[, mask[, maxIters[, confidence]]]]])
一般情况下仅设置srcPoints
和dstPoints
即可。
srcPoints
源平面中点的坐标矩阵dstPoints
目标平面中点的坐标矩阵method
计算单应矩阵所使用的方法。不同的方法对应不同的参数,具体如下:
ransacReprojThreshold
将点对视为内点的最大允许重投影错误阈值(仅用于RANSAC和RHO方法)。若srcPoints和dstPoints是以像素为单位的,则该参数通常设置在1到10的范围内。mask
可选输出掩码矩阵,通常由鲁棒算法(RANSAC或LMEDS)设置。 请注意,输入掩码矩阵是不需要设置的。maxIters
RANSAC算法的最大迭代次数,默认值为2000。confidence
可信度值,取值范围为0到1.dst = cv.warpPerspective( src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]] )
src
输入图像M
3×3转换矩阵dsize
输出图像的大小dst
输出图像flags
插值方法(INTER_LINEAR或INTER_NEAREST)与可选标志WARP_INVERSE_MAP的组合,将M设置为逆变换(dst→src)borderMode
像素外推方法(BORDER_CONSTANT或BORDER_REPLICATE)borderValue
在边界不变的情况下使用的值;默认情况下,它等于0所有内容均来源于贾志刚老师的知识星球——OpenCV研习社,本文为个人整理学习,已获得贾老师授权,有兴趣、有能力的可以加入贾老师的知识星球进行深入学习。