> 文章列表 > cv2 五边形矫正,python ,多边形透视变换

cv2 五边形矫正,python ,多边形透视变换

cv2 五边形矫正,python ,多边形透视变换

#图像透视变换--矫正
#根据最大的5边形进行透视变换
#获取最大和最次长   周长对应的轮廓
#该轮廓进行5边形拟合逼近
#进行透视变换:应用两线交点
import numpy as np
import cv2#大津阈值法 OSTU
def myApprox(con,pointnum=5):# con为预先得到的最大轮廓num = 0.001# 初始化时不需要太小,因为四边形所需的值并不很小ep = num * cv2.arcLength(con, True)con = cv2.approxPolyDP(con, ep, True)while (1):if len(con) == pointnum:#防止程序崩溃设置的==pointnumbreakelse:num = num * 1.5if num >2:breakep = num * cv2.arcLength(con, True)con = cv2.approxPolyDP(con, ep, True)continuereturn con#多边形矫正
def Polygon_correction(img):if len(img.shape) > 2:img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)contours, hierarchy = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)perimeter_list, area_list, cnt_list, center_lsit, box_list = [], [], [], [], []ori_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)ori_w,ori_h = ori_img.shape[0],ori_img.shape[1]print('ori_w,ori_h:',ori_w,ori_h)#ori_img = cv2.drawContours(ori_img, contours, -1, (0, 0, 255), 2)cv2.imshow('binary7', img)cv2.waitKey(0)cv2.destroyAllWindows()#筛选面积最大的三个候选轮廓if len(contours) > 0:cnts = sorted(contours,key=cv2.contourArea,  # 根据该函数计算的结果排序reverse=True)cnts = cnts[:2]docCnt =Nonex, y, w, h = 0,0,ori_w,ori_hfor cnt in cnts:#逼近法五边形拟合approx =myApprox(cnt, pointnum=5)if len(approx)==5:docCnt = approxx, y, w, h = cv2.boundingRect(docCnt) #左上角,w,h# 绘制矩形#cv2.rectangle(ori_img, (x, y + h), (x + w, y), (0, 255, 255))break#获取得到五边形边框五个原始点if not docCnt is None:points = [] #逆时针旋转排序,五个点for doc in docCnt:peak = doc[0]# 在角点绘制小圆圈#cv2.circle(ori_img, tuple(peak), 10, (0, 0, 255), 2) #橙色points.append(tuple(peak))p1, p2, p3, p4, p5 = points[0], points[1], points[2], points[3], points[4]#求四点确定的两条线段的交点,p1,p2,crossp,p5 作为ori转移矩阵前坐标点from util import get_crosss_pointcrossp = get_crosss_point(p2, p3, p4, p5)#如果有交点,让交点作为四个点之一,如果无交点则选择点3或则点4即可if crossp is not None:src = np.float32([p1,p2,crossp,p5])#外接矩阵,水平垂直矩形afterp1 = (x, y)afterp2 = (x, y + h-1)afterpcrossp = (x + w-1, y + h-1)afterp5 = (x + w-1, y)afterpoints = np.float32([afterp1, afterp2, afterpcrossp, afterp5])else:src = np.float32([p1,p2,p3,p5])#存在一定误差#根据自己需求得到多边形点xmin, ymin = np.array(points)[:, 0].min(), np.array(points)[:, 1].min()xmax, ymax = np.array(points)[:, 0].max(), np.array(points)[:, 1].max()sigma = (xmax - p3[0] + ymax - p4[1])/2sigma = int(sigma)afterp1 = (xmin, ymin)afterp2 = (xmin, ymax)afterp3 = (xmax - sigma, ymax)afterp4 = (xmax, ymax - sigma)afterp5 = (xmax, ymin)afterpoints = [afterp1, afterp2, afterp3,afterp5]print("原始点:", src)print("after点:",afterpoints)m = cv2.getPerspectiveTransform(src,afterpoints)result = cv2.warpPerspective(ori_img, m,(ori_h,ori_w))  # 透视变换cv2.circle(result, afterp1, 5, (0, 255, 0), 2)cv2.circle(result, afterp2, 5, (0, 255, 0), 2)cv2.circle(result, afterpcrossp, 5, (0, 255, 0), 2)cv2.circle(result, afterp5, 5, (0, 255, 0), 2)print(result.shape)cv2.polylines(result,[np.array(afterpoints, np.int32)], True,(255, 255, 0),1)cv2.imshow('result', result)cv2.waitKey(0)cv2.destroyAllWindows()return resultelse:return imgelse:return imgif __name__ == '__main__':img = cv2.imread('./data/binary7.png')#二值图afterPolygonimg = Polygon_correction(img)

 

 

 ps:求交点函数,链接为:(85条消息) python 已知四点,两条线,求交点_Lee魅儿的博客-CSDN博客