图像倾斜厉害,或者拼接后的图片形变较大就可以进行透视变换进行矫正。
矫正步骤:
1. 对形变图形寻找外接四边形,这里可以使用多边形拟合进行
2. 四边形对应透视变换后矩形的四个顶点
3. 透视变换矫正
python opencv 实现的代码如下:
import cv2
import numpy as np
imgp= "stitch_img.jpg"
img = cv2.imread(imgp)
indx=np.where((img[:,:,0]>1) | (img[:,:,1]>1) | (img[:,:,2]>1))
binary = np.zeros((img.shape[0],img.shape[1]),dtype="uint8")
binary[indx]=255
cv2.imwrite('binary.jpg', binary)
# contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE,cv2.RETR_EXTERNAL)
##寻找contours
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
areas = []
for c in range(len(contours)):
areas.append(cv2.contourArea(contours[c]))
max_id = areas.index(max(areas))
print(max_id)
rect = cv2.minAreaRect(contours[max_id])
show = np.zeros(img.shape,dtype="uint8")
##寻找最大面积contours
cnt_len = cv2.arcLength(contours[max_id], True)
#contour进行多边形拟合
cnt = cv2.approxPolyDP(contours[max_id], 0.02*cnt_len, True)
if len(cnt) >= 4:
print(cnt.shape)
points = cnt[:,0,:].tolist()
points.sort(key=lambda i:i[0])
#寻找四边形四个顶点
lt = points[0] if points[0][1]<points[1][1] else points[1]
ld = points[0] if points[0][1]>points[1][1] else points[1]
rt = points[-2] if points[-2][1]<points[-1][1] else points[-1]
rd = points[-2] if points[-2][1]>points[-1][1] else points[-1]
pts1 = np.float32([lt,rt,rd,ld])
wid=max(rt[0]-lt[0], rd[0]-ld[0])
hei=max(ld[1]-lt[1], rd[1]-rt[1])
pts2 = np.float32([[0,0],[wid,0],[wid,hei],[0,hei]])
print(lt, ld, rt, rd)
cv2.drawContours(show, [cnt], -1, (255, 255, 0), 3 )
# 透视变换
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img, M, (wid,hei))
cv2.imwrite('rect.jpg', dst)
矫正后结果如下所示,左边矫正前----->右边为矫正后