检测照片上的四边形(非矩形)

时间:2018-09-26 18:16:50

标签: opencv image-processing

我想检测与投影演示幻灯片相对应的四边形区域(即找到最能描述该区域边界的4个点),以纠正倾斜的透视图: test image 我使用的方法在很多资料中都有介绍:通过使用灰度->模糊-> bin阈值-> findContours()来检测区域,然后采用最大的区域并调用approxPolyDP()

#!/usr/bin/env python3
import cv2

def maxl(l): return l.index(max(l))

def find_rect(i_inp):
    i_gray = cv2.cvtColor(i_inp, cv2.COLOR_BGR2GRAY)
    i_blur = cv2.GaussianBlur(i_gray, (11, 11), 0)
    i_bin = cv2.threshold(i_blur, 60, 255, cv2.THRESH_BINARY)[1]

    i_2, contours, hierarchy = cv2.findContours(i_bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnt_largest_i = maxl(list(cv2.contourArea(c) for c in contours))
    cnt_largest = contours[cnt_largest_i]

    cv2.polylines(i_inp, pts=[cnt_largest], isClosed=False, color=(255, 0, 0), thickness=3)

    epsilon = 0.02 * cv2.arcLength(cnt_largest, True)
    approx = cv2.approxPolyDP(cnt_largest, epsilon, True)

    cv2.polylines(i_inp, pts=[approx], isClosed=False, color=(0, 255, 0), thickness=1)

    cv2.imshow('img', i_inp)
    cv2.waitKey(0)

    return approx


img = cv2.imread('test.jpg')
quad = find_rect(img)

最典型的问题如下所示: (蓝色粗线显示在应用approxPolyDP()之前的最大区域,绿色细线是approxPolyDP()给出的内容) epsilon with 0.02
如您所见,使用默认参数(epsilon = 0.02的乘数)无法正确检测到上边界。我尝试使用epsilon的乘数,这是0.01的结果: epsilon with 0.01
在这种情况下,上边界是正确的,而左边界和下边界则不正确。您建议在这里做什么?放弃这种方法,尝试使用Hough Tranform代替?

1 个答案:

答案 0 :(得分:0)

好的,如果PPT的背景保持不变,那么我将为您的任务选择HSV色彩空间和颜色检测。

enter image description here

我将为PPT区域选择H(80,100),S(20,255),v(20,220)。

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (80, 20, 20), (100, 255, 220))

然后findContours并按区域过滤,我得到了:

enter image description here

没有白色马赛克会更好。

  

某些链接:

     
      
  1. Edge detection on colored background using OpenCV

  2.   
  3. Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)

  4.