Carlos
Carlos

Reputation: 117

Detecting a pattern in an image and retrieving its position

I have a 1920x1080 image. I need to get the location for each rectangle in the image. Preferably as 2 points (upper-left, lower right).

I am fairly new to Python. I think of maybe using the opencv module but if you could give me some pointers it would be very helpful.

Thanks.

Sample Image

Upvotes: 4

Views: 3207

Answers (2)

Victor Sonck
Victor Sonck

Reputation: 406

The keywords your looking for is template matching. It basically searches a whole image for copies of the 'template'. In other words, exactly what you're looking for!

Some example code can be found here: https://docs.opencv.org/3.3.0/d4/dc6/tutorial_py_template_matching.html

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

img_rgb = cv2.imread('mario.png')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('mario_coin.png',0)

w, h = template.shape[::-1]
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

cv2.imwrite('res.png',img_rgb)

Where mario_coin.png is your rectangle and mario.png is your full size image.

Upvotes: 2

Mark Setchell
Mark Setchell

Reputation: 207465

I would recommend using OpenCV findContours() like this:

#!/usr/bin/env python3

import numpy as np
import cv2

# Load image
im = cv2.imread('pattern.png')

# Convert to grayscale
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

# Find contours, draw on image and save
im2, contours, hierarchy = cv2.findContours(imgray,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im, contours, -1, (0,0,255), 3)

# Show user what we found
i=0
for cnt in contours:
    x,y,w,h = cv2.boundingRect(cnt)
    print('Contour {}: x={}, y={}, w={}, h={}'.format(i,x,y,w,h))
    i = i+1

# Save the result
cv2.imwrite('result.png',im)

enter image description here

Sample Output

Contour 0: x=1743, y=903, w=77, h=77
Contour 1: x=1552, y=903, w=77, h=77
Contour 2: x=291, y=903, w=77, h=77
Contour 3: x=100, y=903, w=77, h=77
Contour 4: x=1648, y=808, w=77, h=77
Contour 5: x=196, y=808, w=77, h=77
Contour 6: x=1743, y=712, w=77, h=77
Contour 7: x=291, y=712, w=77, h=77
Contour 8: x=100, y=712, w=77, h=77
Contour 9: x=1551, y=711, w=78, h=78
Contour 10: x=1017, y=597, w=77, h=77
Contour 11: x=826, y=597, w=77, h=77
Contour 12: x=922, y=502, w=77, h=77
Contour 13: x=1017, y=406, w=77, h=77
Contour 14: x=826, y=406, w=77, h=77
Contour 15: x=1743, y=291, w=77, h=77
Contour 16: x=1552, y=291, w=77, h=77
Contour 17: x=291, y=291, w=77, h=77
Contour 18: x=100, y=291, w=77, h=77
Contour 19: x=1648, y=196, w=77, h=77
Contour 20: x=196, y=196, w=77, h=77
Contour 21: x=1743, y=100, w=77, h=77
Contour 22: x=1552, y=100, w=77, h=77
Contour 23: x=291, y=100, w=77, h=77
Contour 24: x=100, y=100, w=77, h=77

Note that this is not looking for your patterns specifically, it is just looking for white objects on a black background. This has advantages and disadvantages. The advantage is that it will work for any white shape (circles, stars, octagons) without changing the code. It is also probably faster than template matching. The disadvantage is that it will give you false positives if there are other white objects in your image - though you can check shape, circularity, colour or whatever to confirm/disambiguate.

Upvotes: 3

Related Questions