8

I have an image of the box. I am trying to detect corners and mark those corner from circles. I am using the following code for this:

import cv2
import numpy as np

img_file = 'Image.jpg'
img = cv2.imread(img_file, cv2.IMREAD_COLOR)

imgDim = img.shape
dimA = imgDim[0]
dimB = imgDim[1]

# RGB to Gray scale conversion
img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
# Noise removal with iterative bilateral filter(removes noise while preserving edges)
noise_removal = cv2.bilateralFilter(img_gray,9,75,75)
# Thresholding the image
ret,thresh_image = cv2.threshold(noise_removal,220,255,cv2.THRESH_OTSU)
th = cv2.adaptiveThreshold(noise_removal, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)

# Applying Canny Edge detection
canny_image = cv2.Canny(th,250,255)
canny_image = cv2.convertScaleAbs(canny_image)

# dilation to strengthen the edges
kernel = np.ones((3,3), np.uint8)
# Creating the kernel for dilation
dilated_image = cv2.dilate(canny_image,kernel,iterations=1)
np.set_printoptions(threshold=np.nan)

_, contours, h = cv2.findContours(dilated_image, 1, 2)
contours= sorted(contours, key = cv2.contourArea, reverse = True)[:1]


corners    = cv2.goodFeaturesToTrack(thresh_image,6,0.06,25)
corners    = np.float32(corners)

for item in corners:
    x,y    = item[0]
    cv2.circle(img,(x,y),10,255,-1)
cv2.namedWindow("Corners", cv2.WINDOW_NORMAL)
cv2.imshow("Corners",img)
cv2.waitKey()

This code will return my image with pointing edges with circles but you can see that two edges (edges at the back of the box) are detected incorrectly. I know there is some problem in determining the corners because here we are just plotting the corners. Can anyone guide me where I am doing it wrong ? Thanks enter image description here

enter image description here

Community
  • 1
  • 1
muazfaiz
  • 4,611
  • 14
  • 50
  • 88
  • after determining the edges, find out a way to find the intersections of these edges => CORNERS. :) – Jeru Luke Jan 16 '17 at 17:35
  • What do you exactly mean when you say find out the intersection of edges ? – muazfaiz Jan 16 '17 at 17:43
  • Obtain the Canny edge of the images and find their intersections. Visit [THIS ANSWER](http://stackoverflow.com/questions/10196198/how-to-remove-convexity-defects-in-a-sudoku-square/11366549#11366549) .Hope it helps – Jeru Luke Jan 16 '17 at 17:46
  • Can you upload the original image ? – Jeru Luke Jan 16 '17 at 18:37
  • @JeruLuke original image added. Your reference was useful I am studying that post and trying to learn. Appreciate if you can guide a bit more. – muazfaiz Jan 16 '17 at 18:45
  • 1
    ok before finding the corners of the box just try extracting the box and removing the background. [THIS ANSWER](http://stackoverflow.com/questions/41526023/php-remove-white-background-from-the-image-and-make-it-transparent/41567320#41567320) will help you with that. I would have used the **GrabCut** algorithm. After extracting the box finding corners would a tad bit easy I guess!! :) – Jeru Luke Jan 16 '17 at 19:19
  • 2
    Also visit [THIS PAGE](http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html) – Jeru Luke Jan 16 '17 at 19:22

2 Answers2

10

I wouldn't say I have reached the best solution, but after quite a lot of coding I was able to obtain the following:

enter image description here

To obtain this I followed the following steps:

1. First: Obtain the edges of the box

  • I performed bilateral filtering on the grayscale image.
  • Found the edges using Canny edge detection.
  • Enhanced the edges using morphological dilation.

This is the result of the above:

enter image description here

Now when I did Corner detection, I was not at all satisfied:

enter image description here

So what did I do?

2. Finding desired corners

  • I blurred the dilated image using a window of size 9x9.
  • Then applied Harris corner detection to this blurred image.

As a result I was able to obtain this:

enter image description here

I know it is not perfect but it can always be fine tuned.

Here is the code for corner detection:

dst = cv2.cornerHarris(dilate,2,3,0.04)
#----result is dilated for marking the corners, not important-------------
dst = cv2.dilate(dst,None) 
#----Threshold for an optimal value, it may vary depending on the image---
img[dst>0.01*dst.max()]=[0,0,255]
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
1

@Jeru Luke. Why not Harriscornering based on the result data from your step1?

  1. I performed bilateral filtering on the grayscale image.
  2. Found the edges using Canny edge detection.
  3. Enhanced the edges using morphological dilation.

If you do that the painting on the corners would be neat and fit within the lines, right?

ZF007
  • 3,708
  • 8
  • 29
  • 48