Hough Line Transform - Как закрыть линии, чтобы сформировать полигоны? - PullRequest
2 голосов
/ 26 апреля 2019

В настоящее время я разрабатываю программу обнаружения игральных карт.Я использую Hough Line Transform для определения положения карт, так как это кажется наиболее надежным способом.потому что он меньше зависит от условий окружающей среды, таких как свет и фон (я думаю), вместо того, чтобы находить контуры.

Я использую это изображение для проверки:

И после преобразования я получаю следующий результат:

Как видите, линии не закрывают многоугольники, и я не могу сделать какой-либо вывод относительноположение карт.

Я уже думал об использовании некоторых критериев (таких как угол и т. д.) для группировки линий, принадлежащих одной и той же карте, но мне было интересно, есть ли лучший и более быстрый способ определения положения каждой карты.

Я использовал этот код:

#include <cstdlib>
#include <cstdio>
#include "detector.h"
#include "data_structs.h"
#include <unistd.h>

#define MIN_LINE_LEN 80 
#define MAX_LINE_GAP 10 

//Variáveis globais 
Mat img;
Mat src;

int main( int argc, char** argv ){

    src = imread("img.jpg");
    src.copyTo(img);

    preProcessImg();

    detectCards();

    return 0;
}

//Prepara a img para ser analisada
void preProcessImg(){
    Mat aux_gray;

    cvtColor(img, aux_gray, CV_BGR2GRAY);    // Convert the image to grayscale
    GaussianBlur(aux_gray, img, Size(5,5), 0);
}

void detectCards(){
    vector<Vec4i> lines;

    //Detetar as linhas
    Canny(img, img, 30, 200);
    HoughLinesP(img, lines, 1, CV_PI/180, 80, MIN_LINE_LEN, MAX_LINE_GAP);

}

1 Ответ

4 голосов
/ 26 апреля 2019

Вместо использования Hough Line Transform для обнаружения карт и необходимости закрывать линии для формирования полигонов, я предлагаю другой метод. Вот основная идея:

  • Преобразование изображения в оттенки серого
  • размытие по Гауссу
  • Используйте Обнаружение канни для определения положения карт
  • Найти контуры
  • Фильтрация контуров путем получения площади каждого контура, чтобы убедиться, что она соответствует пороговой минимальной площади

Вот результат:

Обнаружены карты Canny edge (слева) (справа)

Обратите внимание, что все ребра были обнаружены, поэтому мы должны фильтровать, чтобы удалить мелкие частицы

image image

Обнаружены контуры

Обнаружены контуры: 7

Моя реализация была на Python, но вы можете конвертировать ее в C ++, используя ту же стратегию

import numpy as np
import cv2
import imutils

original_image = cv2.imread("1.jpg")
original_image = imutils.resize(original_image, width=500)
image = original_image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
canny = cv2.Canny(blurred, 120, 255, 1)

cv2.imshow("canny", canny)

# Find contours in the image
cnts = cv2.findContours(canny.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

contours = []

contour_image = canny.copy()
threshold_min_area = 400
for c in cnts:
    area = cv2.contourArea(c)
    if area > threshold_min_area:
        cv2.drawContours(original_image,[c], 0, (0,255,0), 3)
        contours.append(c)

cv2.imshow("detected", original_image) 
print('contours detected: {}'.format(len(contours)))
cv2.waitKey(0)
...