Angelo
Angelo

Reputation: 1765

Python OpenCV - get coordinates of borders of elements inside an image

I know my question might sound a little generic but I read a lot of blogs and questions about this and still can't find a solution that get any close to what I'm trying to do. I have the attached sample IG screenshot. My goal is to get the coordinates of the elements I highlighted in green. Canny edges doesn't seem to do a thing (see also https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_canny/py_canny.html). I read Houg Transform could have helped (https://pysource.com/2018/03/07/lines-detection-with-hough-transform-opencv-3-4-with-python-3-tutorial-21/) but still no luck. All I would need is a way to get those sections and get their coordinates. If somebody could simply point me out to what technique(s) could help me, that would be helpful.

enter image description here

Upvotes: 3

Views: 3634

Answers (3)

Senthilkumar S
Senthilkumar S

Reputation: 1

This kind of border detection can be done using a normal Canny edge detector. We just need to sharpen the image before applying Canny.

Code follows:

import cv2
import numpy as np

image = cv2.imread('test.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Sharpen the image
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32) 
dst = cv2.filter2D(gray, -1, kernel)


#Canny Edge detection
canny = cv2.Canny(dst, 30, 200, 1)

# Find contours
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Iterate thorugh contours and draw rectangles around contours
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
   

    cv2.rectangle(image, (x, y), (x + w, y + h), (255,0,255), 1)

#write output
cv2.imwrite('resultimage.png', image)

Upvotes: 0

Martin Beckett
Martin Beckett

Reputation: 96109

Assuming they aren't green in the actual data !

The standard way is edge detect (canny or adaptiveThreshold) and then contour. Simplify the contours using approxPolyDP and then search the contour list for edges that are the correct length and shape.

Hint: use cv2.minAreaRect() to check for contours that are likely box size/shape/alignment

You could use probablistic Hough to find line segments, but since the source image is so clean it is easier to just look through the contours

Upvotes: 1

EnriqueBet
EnriqueBet

Reputation: 1473

Hello I think you could do the next:

  1. Since you have really identified the color of the bounding rectangle you could extract that color from that image into another image (image_green).

  2. Now, once you have image_green binarize it (image_bin) i,e. Make an array with two colors, the extracted one and the foreground.

    1. Loop over the image_bin matrix and find all the "corners" that will be all the couple of pixels that match this condition image_bin[i:i+2,j]/max(image_bin.flatten()) == [1,0] for any j (column), and i (row).
    2. Store this coordinates ([i,j]). As I mentioned before this values represent 2 corners of the rectangles: The upper-left corner and the lower-right corner.

This approach is done with numpy arrays, so as you might imagine you need to convert the image into an array before step 3. If you still are having problems with this let me know and whenever I have some free time I will post a code that does this.

Good Luck!

Upvotes: 0

Related Questions