Python Opencv基于透视变换的图像矫正
这篇文章主要为大家详细介绍了Python Opencv基于透视变换的图像矫正,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了Python Opencv基于透视变换的图像矫正,供大家参考,具体内容如下
一、自动获取图像顶点变换(获取图像轮廓顶点矫正)
图像旋转校正思路如下
1、以灰度图读入
2、腐蚀膨胀,闭合等操作
3、二值化图像
4、获取图像顶点
5、透视矫正
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #(基于透视的图像矫正) import cv2 import math import numpy as np def Img_Outline(input_dir): original_img = cv2.imread(input_dir) gray_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray_img, ( 9 , 9 ), 0 ) # 高斯模糊去噪(设定卷积核大小影响效果) _, RedThresh = cv2.threshold(blurred, 165 , 255 , cv2.THRESH_BINARY) # 设定阈值165(阈值影响开闭运算效果) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, ( 5 , 5 )) # 定义矩形结构元素 closed = cv2.morphologyEx(RedThresh, cv2.MORPH_CLOSE, kernel) # 闭运算(链接块) opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel) # 开运算(去噪点) return original_img, gray_img, RedThresh, closed, opened def findContours_img(original_img, opened): image, contours, hierarchy = cv2.findContours(opened, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) c = sorted (contours, key = cv2.contourArea, reverse = True )[ 1 ] # 计算最大轮廓的旋转包围盒 rect = cv2.minAreaRect(c) # 获取包围盒(中心点,宽高,旋转角度) box = np.int0(cv2.boxPoints(rect)) # box draw_img = cv2.drawContours(original_img.copy(), [box], - 1 , ( 0 , 0 , 255 ), 3 ) print ( "box[0]:" , box[ 0 ]) print ( "box[1]:" , box[ 1 ]) print ( "box[2]:" , box[ 2 ]) print ( "box[3]:" , box[ 3 ]) return box,draw_img def Perspective_transform(box,original_img): # 获取画框宽高(x=orignal_W,y=orignal_H) orignal_W = math.ceil(np.sqrt((box[ 3 ][ 1 ] - box[ 2 ][ 1 ]) * * 2 + (box[ 3 ][ 0 ] - box[ 2 ][ 0 ]) * * 2 )) orignal_H = math.ceil(np.sqrt((box[ 3 ][ 1 ] - box[ 0 ][ 1 ]) * * 2 + (box[ 3 ][ 0 ] - box[ 0 ][ 0 ]) * * 2 )) # 原图中的四个顶点,与变换矩阵 pts1 = np.float32([box[ 0 ], box[ 1 ], box[ 2 ], box[ 3 ]]) pts2 = np.float32([[ int (orignal_W + 1 ), int (orignal_H + 1 )], [ 0 , int (orignal_H + 1 )], [ 0 , 0 ], [ int (orignal_W + 1 ), 0 ]]) # 生成透视变换矩阵;进行透视变换 M = cv2.getPerspectiveTransform(pts1, pts2) result_img = cv2.warpPerspective(original_img, M, ( int (orignal_W + 3 ), int (orignal_H + 1 ))) return result_img if __name__ = = "__main__" : input_dir = "../staticimg/oldimg_04.jpg" original_img, gray_img, RedThresh, closed, opened = Img_Outline(input_dir) box, draw_img = findContours_img(original_img,opened) result_img = Perspective_transform(box,original_img) cv2.imshow( "original" , original_img) cv2.imshow( "gray" , gray_img) cv2.imshow( "closed" , closed) cv2.imshow( "opened" , opened) cv2.imshow( "draw_img" , draw_img) cv2.imshow( "result_img" , result_img) cv2.waitKey( 0 ) cv2.destroyAllWindows() |
直接变换
1、获取图像四个顶点
2、形成变换矩阵
3、透视变换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread( 'original_img.jpg' ) H_rows, W_cols = img.shape[: 2 ] print (H_rows, W_cols) # 原图中书本的四个角点(左上、右上、左下、右下),与变换后矩阵位置 pts1 = np.float32([[ 161 , 80 ], [ 449 , 12 ], [ 1 , 430 ], [ 480 , 394 ]]) pts2 = np.float32([[ 0 , 0 ],[W_cols, 0 ],[ 0 , H_rows],[H_rows,W_cols],]) # 生成透视变换矩阵;进行透视变换 M = cv2.getPerspectiveTransform(pts1, pts2) dst = cv2.warpPerspective(img, M, ( 500 , 470 )) """ 注释代码同效 # img[:, :, ::-1]是将BGR转化为RGB # plt.subplot(121), plt.imshow(img[:, :, ::-1]), plt.title('input') # plt.subplot(122), plt.imshow(dst[:, :, ::-1]), plt.title('output') # plt.show """ cv2.imshow( "original_img" ,img) cv2.imshow( "result" ,dst) cv2.waitKey( 0 ) cv2.destroyAllWindows() |
两次透视变换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | def get_warp_perspective(img, width, height, array_points, array_points_get, array_points_warp): middle_len = 268 # rows, cols = img.shape[:2] # D_value1 = (middle_len - array_points_get[0][1])*2+((middle_len - array_points_get[0][1])//3) # D_value2 = (middle_len - array_points_get[1][1])*2+((middle_len - array_points_get[1][1])//3) D_value1 = 0 D_value2 = 0 # 原图中的四个角点 # pts1 = np.float32([[0, 249],[512, 253],[0, 512], [512, 512]])#重要的测试1和2 pts1 = np.float32(array_points_get) #重要的测试1和2 # pts2 = np.float32([[0, middle_len], [width, middle_len], [0, height], [width, height]])#重要的测试1和2 # pts2 = np.float32([[0, middle_len],[0, height] , [width, height],[width, middle_len]])#重要的测试1和2 pts2 = np.float32([[ 0 , 0 ],[ 0 , middle_len] , [width, middle_len],[width, 0 ]]) #重要的测试1和2 # 生成透视变换矩阵 M = cv2.getPerspectiveTransform(pts1, pts2) # 进行透视变换 dst = cv2.warpPerspective(img, M, (width, height)) # # 保存图片,仅用于测试 img_path = './cut_labels/cut_image_one.jpg' cv2.imwrite(img_path, dst) return warp_perspective(dst, width, height,array_points,array_points_warp,middle_len, D_value1, D_value2) def warp_perspective(dst, width, height,array_points,array_points_warp,middle_len, D_value1, D_value2): # new_img_path = img_path # img = cv2.imread(new_img_path) # 原图的保存地址 # rows, cols = img.shape[:2] # 原图中的四个角点 # pts3 = np.float32([[0, 268], [0, 44], [512,35], [512, 268]])#重要测试1 # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要测试1 pts3 = np.float32([[ 0 , 0 ], [ 0 , height], [width, height], [width, 0 ]]) # pts3 = np.float32([[0, middle_len], [0, D_value1], [512,D_value2], [512, middle_len]])#重要测试1 # pts3 = np.float32([[0, 512], [0, array_points[1][1]], [512,512], [512, middle_len]])#重要测试1 # 变换后的四个角点 pts4 = np.float32([[ 0 , 0 ], [ 0 , height - D_value1], [width, height - D_value2], [width, 0 ]]) #重要测试1 # pts4 = np.float32([[0, 268], [0, 0], [512, 0], [512, 268]])#重要测试1 # 生成透视变换矩阵 M = cv2.getPerspectiveTransform(pts3, pts4) # 进行透视变换 dst_img = cv2.warpPerspective(dst, M, (width, height)) # #保存最终图片,仅用于测试 print ( "++++++++++++++++" ) final_img_path = './cut_labels/cut_image_two.jpg' cv2.imwrite(final_img_path, dst_img) # 进行透视变换 return cv2.warpPerspective(dst_img, M, (width, height)) # return output_warp_perspective(img, width, height, array_points, array_points_get, array_points_warp) if __name__ = = "__main__" : # 透视转换 img = cv2.imread( '../staticimg/oldimg_04.jpg' ) dst = get_warp_perspective(img, 512 , 512 , array_points = [[ 395.2 , 75.0 ], [ 342 , 517 ], [ 1000 , 502 ], [ 900 , 75 ]]) cv2.imwrite( 'aaa2.jpg' , dst) cv2.imshow( 'title' , dst) cv2.waitKey( 0 ) imgrectificate = imgRectificate(img, width, height, array_points) imgrectificate.warp_perspective() |
以上就是本文的全部内容,希望对大家的学习有所帮助
原文链接:https://blog.csdn.net/weixin_43431189/article/details/93513923