Я хочу определить четырехугольную область (т. Е. Найти 4 точки, наилучшим образом описывающие границу области), соответствующие проецируемому слайду презентации, чтобы исправить перекос перспективы: Яиспользуя подход, который описан во многих источниках: обнаружение областей с использованием градаций серого -> размытие -> пороговое значение 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
= 0,02) верхняя граница определена неправильно.Я пытался играть с множителем epsilon
, вот результат с 0,01:
, в этом случае верхняя граница верна, а левая и нижняя - нет.Что бы вы порекомендовали сделать здесь?отказаться от этого подхода и попробовать Hough Tranform вместо этого?