Python 4点保护转换失败

Python 4点保护转换失败,python,opencv,Python,Opencv,我一直在尝试做一个4点透视变换,以便开始做一些OCR 从下图开始,我可以检测到车牌 把它裁剪出来,绿色的框是边框,红色的点是矩形的角点,我想把它弄成正方形 这是变换的输出 乍一看,似乎已经完成了由内而外的变换(将零件任一侧,而不是点之间) 我正在使用imutils包进行转换,并以和为指导进行工作。我肯定我错过了一些相对简单的东西 #!/usr/bin/python import numpy as np import cv2 import imutils from imutils impor

我一直在尝试做一个4点透视变换,以便开始做一些OCR

从下图开始,我可以检测到车牌

把它裁剪出来,绿色的框是边框,红色的点是矩形的角点,我想把它弄成正方形

这是变换的输出

乍一看,似乎已经完成了由内而外的变换(将零件任一侧,而不是点之间)

我正在使用imutils包进行转换,并以和为指导进行工作。我肯定我错过了一些相对简单的东西

#!/usr/bin/python
import numpy as np
import cv2
import imutils
from imutils import contours
from imutils.perspective import four_point_transform

img = cv2.imread("sample7-smaller.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.bilateralFilter(gray,15,75,75)
v = np.median(blurred)
lower = int(max(0, (1.0 - 0.33) * v))
upper = int(min(255, (1.0 + 0.33) * v))
edged = cv2.Canny(blurred, lower, upper, 255)

conts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)
conts = conts[0] if imutils.is_cv2() else conts[1]
conts = sorted(conts, key=cv2.contourArea, reverse=True)

for cnt in conts:
    approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
    if len(approx) == 4:
        x,y,w,h = cv2.boundingRect(cnt)
        cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
        for i in approx:
            cv2.circle(img,(i[0][0], i[0][1]),2,(0,0,255), thickness=4)
        warped = four_point_transform(img, approx.reshape(4,2))
        cv2.imshow("crop",img[y:y+h,x:x+w])
        cv2.imshow("warped", warped)
        cv2.waitKey(0)

我建议您使用OpenCV方法,根据给定的图像获得所需的结果:

首先标记src点的位置:

src_pts = np.array([[8, 136], [415, 52], [420, 152], [14, 244]], dtype=np.float32)
假设你想把这个号码牌放在一个50x200形状的矩阵中,那么目标点是:

dst_pts = np.array([[0, 0],   [200, 0],  [200, 50], [0, 50]], dtype=np.float32)
找到透视变换矩阵,如下所示:

M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warp = cv2.warpPerspective(img, M, (200, 50))

编辑:由于您不想硬编码板的最终宽度和高度,因此为了使计算更灵活,您可以从4个标记点计算板的宽度和高度,如下所示:

def get_euler_distance(pt1, pt2):
    return ((pt1[0] - pt2[0])**2 + (pt1[1] - pt2[1])**2)**0.5

src_pts = np.array([[8, 136], [415, 52], [420, 152], [14, 244]], dtype=np.float32)

width = get_euler_distance(src_pts[0][0], src_pts[0][1])
height = get_euler_distance(src_pts[0][0], src_pts[0][3])

dst_pts = np.array([[0, 0],   [width, 0],  [width, height], [0, height]], dtype=np.float32)

M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warp = cv2.warpPerspective(img, M, (width, height))

这就是imutils代码应该做的(),它看起来也在做同样的事情,只是计算飞行中输出的维度,所以你想让输出维度在飞行中计算@hardillb?我想让它保持相同的比例开始,然后我可以稍后重新缩放,不幸的是,它仍然提供相同的输出(并且传递到
get\u euler\u distance
的值需要成对,而不是单个值)。如果你想再看一看,我已经压缩了我所有的代码和原始图像。好的,我终于找到了问题所在,我安装的imutils版本在它的
order_points
中有一个bug,它正在交换要转换区域的右上角和右下角。