Обнаружение углов билбордов - PullRequest
0 голосов
/ 15 октября 2018

Я пытался обнаружить рекламные щиты на случайном фоне.Мне удалось локализовать рекламный щит с помощью SSD, это дает мне приблизительную ограничивающую рамку вокруг рекламного щита.Теперь я хочу найти точные углы рекламного щита для моего приложения.Я пытался использовать различные стратегии, с которыми мне приходилось сталкиваться, такие как определение угла Харриса (с использованием Opencv), поиск пересечений линий с использованием Canny + морфологические операции + контуры.Подробная информация о выходе приведена ниже.

Обнаружение угла Харриса Псевдокод для обнаружения угла Харриса выглядит следующим образом:

img_patch_gray = np.float32(img_patch_gray)
harris_point = cv2.cornerHarris(img_patch_gray,2,3,0.04)
img_patch[harris_point>0.01*harris_point.max()]=[255,0,0]
plt.figure(figsize=IMAGE_SIZE)
plt.imshow(img_patch)

Harris detection result Здесь красныйточки - это углы, обнаруженные алгоритмом обнаружения углов Харриса, и представляющие интерес точки обведены зеленым.

Использование обнаружения линии Хафа Здесь я пытался найти пересечение линий, а затемвыбирая очки.Нечто похожее на ссылка на stackoverflow , но очень трудно получить точные строки, поскольку рекламные щиты содержат текст и графику.

Контур на основе В этом подходе я имеюиспользовался детектор краев Canny, за которым следовало расширение (ядро 3 * 3), за которым следовал контур.

bin_img = cv2.Canny(gray_img_patch,100,250)
bin_img = dilate(bin_img, 3)
plt.imshow(bin_img, cmap='gray')
(_,cnts, _) = cv2.findContours(bin_img.copy(), 
cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
cv2.drawContours(img_patch, [cnts[0]],0, (0,255,0), 1)

binarized image after dialtion, Largest contour detected.Я пытался использовать функцию приближения OpenPV от openCV, но она не была такой, как ожидалось, поскольку она также может приближать большие или меньшие контуры на четыре точки, а на некоторых изображениях она может не образовывать контуры вокруг рамки рекламного щита.

Я использовал openCV 3.4 для всех операций по обработке изображений.Original image используется можно найти здесь.Пожалуйста, обратите внимание, что изображение, обсуждаемое здесь, предназначено только для иллюстрации, и в целом изображение может быть любого рекламного щита.Заранее спасибо, любая помощь приветствуется.

1 Ответ

0 голосов
/ 15 октября 2018

Это очень сложная задача, потому что изображение содержит много шума.Вы можете получить аппроксимацию контура, но конкретные углы будут очень трудными.Я сделал пример того, как я бы сделал приближение.Это может не работать на других изображениях.Может быть, это поможет немного или даст вам новую идею.Ура!

import cv2
import numpy as np

# Read the image
img = cv2.imread('billboard.png')

# Blur the image with a big kernel and then transform to gray colorspace
blur = cv2.GaussianBlur(img,(19,19),0)
gray = cv2.cvtColor(blur,cv2.COLOR_BGR2GRAY)

# Perform histogram equalization on the blur and then perform Otsu threshold
equ = cv2.equalizeHist(gray)
_, thresh = cv2.threshold(equ,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# Perform opening on threshold with a big kernel (erosion followed by dilation)
kernel = np.ones((20,20),np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

# Search for contours and select the biggest one
_, contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)

# Make a hull arround the contour and draw it on the original image
mask = np.zeros((img.shape[:2]), np.uint8)
hull = cv2.convexHull(cnt)
cv2.drawContours(mask, [hull], 0, (255,255,255),-1)

# Search for contours and select the biggest one again
_, thresh = cv2.threshold(mask,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)

# Draw approxPolyDP on the image
epsilon = 0.008*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
cv2.drawContours(img, [cnt], 0, (0,255,0), 5)

# Display the image
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Результат:

enter image description here

...