python图像倾斜校正_校正倾斜的文本

有时候文本是倾斜的,则不利于文本识别,如下图所示,那么进行文本识别之前我们需要应用文本倾斜校正算法(text skew correction,deskewing text)。

对于一幅包含旋转文本块的图像,我们需要通过以下方式纠正文本倾斜:检测图像中的文本块

确定文本块的倾斜角度和倾斜方向

旋转图像以校正倾斜的文本

那么我们开始吧。

首先读取图像并转换为灰度图:

img_path = "text.jpg"

img = cv2.imread(img_path)

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

在进行图像处理操作时,前景通常为亮色,而背景(图像中不感兴趣的部分)通常是暗的。但是我们的输入图像是白底黑字,所以需要反转图像,让文本部分作为前景。

# flip the foreground and background to ensure text is "white"

gray = cv2.bitwise_not(gray)

先进行高斯模糊,再对图像进行阈值处理得到二值图像:

blur = cv2.GaussianBlur(gray, (7,7), 0)

# setting all foreground pixels to 255 and all background pixels to 0

ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

如下图所示:

对于这个二值图像,我们先获取图像中灰度值不为零的所有像素的坐标(x,y),这些都是表示文本的像素。

whereid = np.where(thresh > 0)

# 交换横纵坐标的顺序,否则下面得到的每个像素点为(y,x)

whereid = whereid[::-1]

# 将像素点格式转换为(n_coords, 2),每个点表示为(x,y)

coords = np.column_stack(whereid)

np.where 的用法可以查看 这里,对于二维图像,whereid 是一个包含两个元素的列表,第一个元素为所有满足要求的像素的纵坐标,第二个元素为所有满足要求的像素的横坐标。

我们需要使用 whereid[::-1] 交换横纵坐标的顺序,下一步,使用 np.column_stack 将所有像素点坐标转换为 (n_pixel, 2),其中每个像素点坐标表示为 (x, y)。np.column_stack 的用法可以查看 这里。

我们就可以根据这些像素坐标来计算文本倾斜的角度和方向。

(x,y), (w,h), angle = cv2.minAreaRect(coords)

if angle < -45:

angle = 90 + angle

通过 cv2.minAreaRect(coords) 来得到包含整个文本区域的最小旋转矩形,cv2.minAreaRect(coords) 的用法可以查看我的这篇文章 OpenCV 中的轮廓应用。

会得到这个区域的倾斜角度angle,angle的范围为 (-90,-0],一个正矩形框逆时针旋转,

的值变化为:-0 -> -30 -> -60 -> -0,然后不断循环。

所以这个角度值就是逆时针旋转的角度,当旋转角度小于-45度时,我们需要加上90度,具体原因后面解释。

为了更好地理解我们得到的是一个什么矩形框,这里额外添加一步绘图操作:

vis = img.copy()

box = cv2.boxPoints(((x,y), (w,h), angle))

box = np.int0(box)

cv2.drawContours(vis,[box],0,(0,0,255),2)

这几句具体代表什么意思,可以查看这篇文章 OpenCV 中的轮廓应用,这不是本文重点,就不多说了。

终于来到最后一步了,对倾斜文本进行校正。

# rotate the image to deskew it

h, w = image.shape[:2]

center = (w // 2, h // 2)

# center = x, y # 可以试试中心点设置为文本区域中心会是什么情况

Mat = cv2.getRotationMatrix2D(center, angle, 1.0)

rotated = cv2.warpAffine(image, Mat, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)

我们先得到整个图像的中心点center,这里通过 cv2.warpAffine 进行对图像进行仿射变换来实现校正倾斜文本。

仿射变换对角度要求是:angle为正,则逆时针选择;angle为负,则顺时针旋转。当文本倾斜角度范围为 (-45, 0) 时,即小于45度的负角度,表示文本逆时针倾斜,该角度不进行处理,在仿射变换时顺时针旋转。

当文本倾斜角度范围为 (-90, -45) 时,表示文本顺时针倾斜,对该角度加上90度,得到一个小于45度的正角度,在仿射变换时逆时针旋转。

关于仿射变换的详细信息可以查看这篇文章 图像的仿射变换。

通过 cv2.getRotationMatrix2D 得到旋转矩阵,根据旋转矩阵,那么就可以使用 cv2.warpAffine 来对图像进行仿射变换,从而实现文本倾斜校正。

使用如下语句在旋转后的图上绘制出倾斜的角度:

cv2.putText(rotated, "Angle: {:.2f} degrees".format(angle), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

最终的结果图为:

该图的倾斜角度为 -3.87,即逆时针倾斜3.87度,校正后的效果还是比较好的。

看一下更多的例子:

参考:OpenCV - Rotation (Deskewing)​felix.abecassis.meText skew correction with OpenCV and Python - PyImageSearch​www.pyimagesearch.com

如果觉得有用,点个赞吧(ง •̀_•́)ง。

你可能感兴趣的:(python图像倾斜校正)