Обнаружение четырехугольника (не прямоугольника) на фото - PullRequest
0 голосов
/ 26 сентября 2018

Я хочу определить четырехугольную область (т. Е. Найти 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 голосов
/ 27 сентября 2018

Хорошо, если фон PPT остается прежним, я выберу цветовое пространство HSV и определение цвета для вашей задачи.

enter image description here

I 'Я выберу H (80, 100), S (20, 255), v (20, 220) для области PPT.

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

Затем найду Контуры и отфильтрую по области, я получу это:

enter image description here

Будет лучше без белой мозаики.

Некоторые ссылки:

  1. Обнаружение краев на цветном фоне с использованием OpenCV

  2. Выбор правильной верхней и нижней границ ВПГ для обнаружения цвета с помощью `cv :: inRange` (OpenCV)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...