多边形拟合+透视变换

# -*- coding: utf-8 -*-
# ----------------------------
# ! Copyright(C) 2022
# All right reserved.
# 文件名称:xxx.py
# 摘 要:xxx
# 当前版本:1.0
# 作 者:刘恩甫
# 完成日期:2022-x-x
# -----------------------------
import os
import cv2
import numpy as np

def Perspective_transform(image, pts):
(tl, tr, br, bl) = pts
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max(int(widthA), int(widthB))
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max(int(heightA), int(heightB))

# in the top-left, top-right, bottom-right, and bottom-left order
dst = np.array([[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHeight - 1],
[0, maxHeight - 1]], dtype="float32")
M = cv2.getPerspectiveTransform(pts, dst)
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
return warped

if __name__ == '__main__':
label_path = r'.\truck_warp_affine\1\label\\'
img_path = r'.\truck_warp_affine\1\img\\'

for path in os.listdir(label_path):
name, ext = os.path.splitext(path)

img = cv2.imread(img_path + name + '.jpg')
r_img = cv2.resize(img, dsize=None, fx=.25, fy=.25)
label = cv2.imread(label_path + name + '.png')
r_label = cv2.resize(label, dsize=None, fx=.25, fy=.25)
#腐蚀操作
r_label=cv2.erode(r_label,kernel=np.ones((5,5),np.uint8))
#二值化
gray = cv2.cvtColor(r_label, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]

# 多边形拟合
epi_thres=0.01 # epi_thres 越小,拟合越精细
epsilon = epi_thres * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
cv2.polylines(r_label, [approx], True, (0, 0, 255), 2)

#找到最左,最下,最右,最上的四个点
approx=approx.squeeze()
row,col=sorted(approx, key=lambda x: x[0]),sorted(approx, key=lambda x: x[1])
left,right,top,bottom=row[0],row[-1],col[0],col[-1]

#进行透视变换
min_area_rect = cv2.minAreaRect(np.array([left,right,top,bottom]))
angle = min_area_rect[-1]
if 0 < angle < 90:
box=np.array([left,top,right,bottom]).astype(np.float32)
else:
box=np.array([top,right,bottom,left]).astype(np.float32)
warpPerspective = Perspective_transform(r_img,box)
if warpPerspective.shape[0]>warpPerspective.shape[1]:
warpPerspective=np.rot90(warpPerspective)

#画图操作
for p in [left,right,top,bottom]:
cv2.circle(r_img, p, 3, (255, 0, 0), 3)
cv2.circle(r_label, p, 3, (255, 0, 0), 3)
cv2.imshow('warpPerspective',warpPerspective)
cv2.imshow('r_img', r_img)
cv2.imshow('r_label', r_label)
cv2.waitKey()

# break
posted @ 2022-07-02 15:35  刘恩福  阅读(159)  评论(0编辑  收藏  举报