opencv文档矫正
棒子胡豆 人气:0原始文档
矫正后文档
思路:
只要获得倾斜文档的倾斜角度,然后通过仿射变化旋转一下就可以实现矫正了,这里获取倾斜角度的方法有两个,下面分别介绍
1、利用霍夫变换,文档内容都是平行的,首先利用利用霍夫变换检测直线,然后将所有直线的平均倾斜角度当做文档的倾斜角度,最后再进行仿射变换就可以了。
import cv2 import numpy as np def imshow(img): cv2.imshow("img",img) cv2.waitKey(0) cv2.destroyAllWindows() img = cv2.imread("2.png",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.png",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)
加载全部内容