广告牌角落检测

时间:2018-10-15 10:13:26

标签: opencv image-processing computer-vision corner-detection

我试图在随机背景下检测广告牌图像。我能够使用SSD定位广告牌,这给了我广告牌周围的大致边界框。现在,我想为我的应用程序找到广告牌的确切角落。我尝试使用遇到的不同策略,例如哈里斯拐角检测(使用Opencv),使用Canny +形态运算+轮廓查找线的交点。输出的详细信息在下面给出。

哈里斯拐角检测 harris拐角检测的伪代码如下:

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 link类似,但是由于广告牌中包含文本和图形,因此很难获得确切的线条。

基于轮廓的 在这种方法中,我使用Canny边缘检测器,然后使用dilation(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 dialtionLargest contour detected。我曾尝试使用来自openCV的roxPolyDp函数,但它没有达到预期的效果,因为它也可以通过四个点近似较大或较小的轮廓,并且在某些图像中,它可能不会在广告牌框架周围形成轮廓。

我已将openCV 3.4用于所有图像处理操作。您可以在此处找到使用的Original image。请注意,此处讨论的图像仅用于说明目的,一般而言,该图像可以是任何广告牌。 在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

这是一个非常困难的任务,因为图像包含很多噪点。您可以获得轮廓的近似值,但是特定的角点将非常困难。我已经举例说明了如何进行近似。它可能不适用于其他图像。也许会有所帮助或给您一个新的主意。干杯!

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