微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python OpenCV 透视变换问题

如何解决Python OpenCV 透视变换问题

我正在尝试使用 opencv 进行透视转换。 我想从我的电子书中提取屏幕并将其对齐。

1

首先,我找到一个最大的轮廓并将其放入screenCnt2变量。 之后,我将值提取到 2 个列表中:

x1_1 = [i[0] for j in screenCnt2 for i in j]
y1_1 = [i[1] for j in screenCnt2 for i in j]

然后,我计算了轮廓内子图像的 max_width 和 max_height:

len_yr = np.sqrt((x1_1[1] - x1_1[0]) ** 2 + (y1_1[0] - y1_1[1])**2)
len_rb = np.sqrt((x1_1[1] - x1_1[2])**2 + (y1_1[2] - y1_1[1])**2)
len_bg = np.sqrt((x1_1[2] - x1_1[3])**2 + (y1_1[2] - y1_1[3])**2)
len_gy = np.sqrt((y1_1[3] - y1_1[0])**2 + (x1_1[0] - x1_1[3])**2)
print(len_yr,len_rb,len_bg,len_gy)
max_width = max(int(len_yr),int(len_bg))
max_height = max(int(len_gy),int(len_rb))

最后应用透视变换

p1 = [i for i in zip(x1_1,y1_1)]
pts1 = np.float32(p1)
pts2 = np.float32([[0,0],[max_width - 1,max_height - 1],[0,max_height -1 ]])


M = cv2.getPerspectiveTransform(pts1,pts2)
dst2 = cv2.warpPerspective(seg_im3,M,(max_width,max_height))

x1_2 = [i[0] for i in pts2]
y1_2 = [i[1] for i in pts2]

plt.figure(figsize=(10,10))
plt.subplot(121),plt.imshow(angle_im2[:,:,::-1]),plt.title('Input')
plt.scatter(x1_1,y1_1,color = colors)
for x,y,color in zip(x1_1,colors):
    plt.text(x,f'[{int(x)},{int(y)}]',color = color)
plt.subplot(122),plt.imshow(dst2[:,plt.title('Output')
plt.scatter(x1_2,y1_2,color in zip(x1_2,color = color)
plt.show()

最终结果:

2

我不知道我做错了什么,因为相同的代码可以很好地处理另一个图像:

3

//编辑

第一张图片中的红色矩形是最大的轮廓。 为了找到它,我使用了这两个函数: 调整伽玛使图像更暗

def adjust_gamma(image,gamma=1.0):

   invGamma = 1.0 / gamma
   table = np.array([((i / 255.0) ** invGamma) * 255
      for i in np.arange(0,256)]).astype("uint8")

   return cv2.LUT(image,table)

然后我找到了所有的轮廓并取了最大的:

def find_biggest_cnt(img):
    img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,thrash = cv2.threshold(img_gray,35,200,cv2.CHAIN_APPROX_NONE)
    cnts = cv2.findContours(thrash,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
    cnts = imutils.grab_contours(cnts)
    cnts = sorted(cnts,key = cv2.contourArea,reverse = True)[:5]

    for c in cnts:
        peri = cv2.arcLength(c,True)
        approx = cv2.approxpolyDP(c,0.02 * peri,True)
        if len(approx) == 4:
            screenCnt = approx
            break
    return screenCnt

结果是:

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。