0

I have an image like this:

enter image description here

When i try to use any of the corner detection algorithms i get corners like this:

enter image description here

however i want to corners of the rectangle.

How can i get rid of those corners that i do not want.

and here is my code

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread("/home/mkmeral/Desktop/opencv/cropped.png")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
corners = cv2.goodFeaturesToTrack(gray,4,0.01,10)
corners = np.int0(corners)

for i in corners:
    x,y = i.ravel()
    cv2.circle(img,(x,y),3,255,-1)

plt.subplot(121),plt.imshow(img)
plt.title('2'), plt.xticks([]), plt.yticks([])
plt.suptitle("CORNERS")

cv2.imwrite("/home/mkmeral/Desktop/opencv/corners.png", img)

plt.show()

Here is the whole image, i cropped the image to make it smaller.

enter image description here

This is where i need corners to be:

enter image description here

mkmeral
  • 111
  • 1
  • 2
  • 10
  • Isn't your image already flawed? The objects overlaps the edge of the image? – RvdK Nov 06 '16 at 11:22
  • Yes, but that's not the whole image. I cropped it before posting. My bad :/ – mkmeral Nov 06 '16 at 12:51
  • Please post the whole image if possible, then it would be easier to solve the problem . – ZdaR Nov 06 '16 at 12:57
  • 1
    Maybe you could post another image showing where you perceive the corners to be. – Mark Setchell Nov 06 '16 at 13:05
  • "i want to corners of the rectangle" -- what rectangle? – Dan Mašek Nov 06 '16 at 13:34
  • Have you seen http://stackoverflow.com/questions/26583649/opencv-c-rectangle-detection-which-has-irregular-side ? It seems very close to your problem. It suggests to use [functions related to shape descriptor](http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html), such as `cv::findContours()`, `cv::minAreaRect()`... – francis Nov 06 '16 at 15:08

2 Answers2

1

As your image is of rather poor resolution and resemblance to a rectangle, any solution is going to be somewhat in the beholder's eye.

You can do this with OpenCV but I am just explaining the method using ImageMagick at the commandline. So, threshold the image to black and white at 50% and then do a "Blob Analysis" or "Connected Components Analysis".

convert rect.png -threshold 50%              \
   -define connected-components:verbose=true \
   -connected-components 8 result.png

Output

Objects (id: bounding-box centroid area mean-color):
  0: 160x120+0+0 78.0,58.7 18551 srgb(0,0,0)
  1: 52x50+97+58 121.8,82.6 649 srgb(255,255,255)

So, if we look at the last line we have an object 52x50 pixels with area 649 pixels and colour white - that is your shape - or burning cigarette as I think of it! Let's draw it in:

convert rect.png -stroke red -fill none -draw "rectangle 97,58 148,107" y.png

enter image description here

Now, if it is a rectangle as you say, it will have a length roughly equal to the diagonal of the enclosing box, so

L = sqrt(52*52 + 50*50) = 72

and its area is 649, so its width is around 9 pixels and it starts at +97+58 from the top-left corner. Or its centroid is at 121.8,82.6. So, all that's needed is a little schoolboy geometry to get your corner points.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
0

I found that by adjusting the arguments passed to cv2.cornerHarris() I could get corners correctly identified.

E.g. given this input image:

enter image description here

We can capture corners with the following (note the arguments passed to cornerHarris():

import cv2
import numpy as np
from matplotlib import pyplot as plt

img_file = 'a.jpg'

img = cv2.imread(img_file, 0)
img = np.float32(img)

'''args:
img - Input image, it should be grayscale and float32 type.
blockSize - It is the size of neighbourhood considered for corner detection
ksize - Aperture parameter of Sobel derivative used.
k - Harris detector free parameter in the equation.
'''
corners = cv2.cornerHarris(img, 4, 3, 0.04)
corners2 = cv2.dilate(corners, None, iterations=3)

img2 = cv2.imread(img_file)
img2[corners2>0.01*corners2.max()] = [255,0,0]

plt.subplot(2, 1, 2)
plt.imshow(img2, cmap = 'gray')
plt.title('Canny Edge Detection')
plt.xticks([])
plt.yticks([])
plt.show()

Output:

enter image description here

duhaime
  • 25,611
  • 17
  • 169
  • 224