opencv实现文档矫正

本文实例为大家分享了opencv实现文档矫正的具体代码,供大家参考,具体内容如下

原始文档

矫正后文档

思路:

只要获得倾斜文档的倾斜角度,然后通过仿射变化旋转一下就可以实现矫正了,这里获取倾斜角度的方法有两个,下面分别介绍

1、利用霍夫变换,文档内容都是平行的,首先利用利用霍夫变换检测直线,然后将所有直线的平均倾斜角度当做文档的倾斜角度,最后再进行仿射变换就可以了。

import cv2 import numpy as np def imshow(img):     cv2.imshow("img",img)     cv2.waitKey(0)     cv2.destroyAllWindows() img = cv2.imread("2.webp",1) img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  img2 = img.copy() img_canny = cv2.Canny(img,75,200)  img_line = cv2.HoughLines(img_canny,1,np.pi/180,280) average = 0 for line in img_line:      for rho,theta in line:         average = average + theta  average = average / len(img_line) angel = average/np.pi * 180 - 90 def rotateImg(img,angel):     rows, cols = img.shape     M = cv2.getRotationMatrix2D(((cols - 1) / 2.0, (rows - 1) / 2.0), angel, 1)  # 旋转中心x,旋转中心y,旋转角度,缩放因子     img = cv2.warpAffine(img, M, (cols, rows),borderValue = (255,255,255))  #在内存里完成了旋转     imshow(img) rotateImg(img2,angle)

2、求文档内容的最小包围矩形。首先检测轮廓,利用形态学操作求mask,然后再检测轮廓,求最下包围矩形,最小包围矩形会返回一个倾斜角度(度数,霍夫变换的倾斜角度是弧度制),可以对轮廓进行筛选,将面积最大的轮廓的倾斜角度作为文档的倾斜角度,然后做仿射变换。

import cv2 import numpy as np def imshow(img):     cv2.imshow("img",img)     cv2.waitKey(0)     cv2.destroyAllWindows() img = cv2.imread("2.webp",1) img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  img2 = img.copy() imgth = cv2.threshold(img,0,255,cv2.THRESH_OTSU|cv2.THRESH_BINARY_INV)[1] kernel = np.ones((17,17)) img_open = cv2.morphologyEx(imgth,cv2.MORPH_CLOSE,kernel,10) # imshow(img_open) cons = cv2.findContours(img_open,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[0] areas = [] for con in cons:     area = cv2.contourArea(con)     areas.append(area) index = areas.index(max(areas)) # 度数形式,霍夫变换的返回值是弧度制 rect = cv2.minAreaRect(cons[index]) angle = rect[2] mat = cv2.getRotationMatrix2D((img.shape[1]/2,img.shape[0]/2),angle,1) img_fin = cv2.warpAffine(img,mat,(img.shape[1],img.shape[0]),borderValue = (255,255,255)) imshow(img_fin) 补充:

利用仿射变换实现图像旋转指定度数

mat = cv2.getRotationMatrix2D(center,angle,c) (center: 旋转中心,angle:旋转角度,c:缩放大小)
img_final = cv2.warpAffine(img,mat, (img.shape[1],img.shape[0]), borderValue = (255,255,255)) (borderValue为可选参数,填充色,默认为黑色)

另外旋转指定90,180,270可以使用transpose、flip来实现

旋转90度(顺时针)
img = cv2.transpose(img)
res_img = cv2.flip(img,1)

旋转180度
img = cv2.flip(img,0)
img = cv2.flip(img,1)

推荐阅读