Ask Your Question
0

python matchShapes on images

asked 2017-07-20 01:15:13 -0600

jtlz2 gravatar image

In python, I am trying to exploit the affine invariance of matchShapes() (compared to matchTemplate()) to match my template to distorted candidate images.

The template and candidate images are quite complicated, but the documentation states that grayscale images can be inputted to matchShapes():

http://docs.opencv.org/2.4/modules/im...

This is my preferred option to breaking out into a large ensemble of contours.

As far as I can tell, matchShapes cannot in fact handle two grayscale images. What could I be doing wrong?

That then leaves the contours route. But how does one aggregrate information from all possible contour pairs in order to assess the confidence of a match?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-07-20 01:57:29 -0600

berak gravatar image

updated 2017-07-20 02:03:49 -0600

i can't test with 2.4, but opencv3 can compare binary images, using matchShapes:

>>> m = np.eye(10,10,dtype=np.uint8) # just the diagonal
>>> m2 = m[2:6,2:6]=1                # add a little rect
>>> cv2.matchShapes(m,m2,1,0)        # compare
9.974179503561947

to test against multiple shapes, you'll have to apply a nearest neighbour search:

s0 = ... # template shape
best_shape = None
best_dist = 9999999999 
for s in shapes: # image or contour, no matter
     dist = cv2.matchShapes(s0, s, 1,0)
     if dist < best_dist:
          best_dist = dist
          best_shape = s

# now use best_shape ..

but again, if you want to use images here, the assumption is, that there's a single shape in the image.

(as you cannot calculate moments() for multiple shapes in the same image)

edit flag offensive delete link more

Comments

Excellent. I still get an exception though:

import cv2 import numpy as np m = np.eye(10,10,dtype=np.uint8) m2 = m[2:6,2:6]=1 cv2.matchShapes(m,m2,1,0)

OpenCV Error: Assertion failed (contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 && (contour1.depth() == CV_32F || contour1.depth() == CV_32S) && contour1.depth() == contour2.depth()) in matchShapes, file /tmp/opencv-20170224-1869-10nlf6f/opencv-2.4.13.2/modules/imgproc/src/contours.cpp, line 1941

error Traceback (most recent call last) <ipython-input-5-ad4e7d59fa25> in <module>() ----> 1 cv2.matchShapes(m,m2,1,0)

error: /tmp/opencv-20170224-1869-10nlf6f/opencv-2.4.13.2/modu

jtlz2 gravatar imagejtlz2 ( 2017-07-20 02:20:19 -0600 )edit

i guess, you want to update to opencv3, then ..

you could make another test with: cv2.moments(image) -- should be the same problem.

berak gravatar imageberak ( 2017-07-20 02:26:03 -0600 )edit

cv2.moments(image) works fine - {'mu02': 82.5, 'mu03': 0.0, 'm11': 285.0, 'nu02': 0.8250000000000002, 'm12': 2025.0, 'mu21': 0.0, 'mu20': 82.5, 'nu20': 0.8250000000000002, 'm30': 2025.0, 'nu21': 0.0, 'mu11': 82.5, 'mu12': 0.0, 'nu11': 0.8250000000000002, 'nu12': 0.0, 'm02': 285.0, 'm03': 2025.0, 'm00': 10.0, 'm01': 45.0, 'mu30': 0.0, 'nu30': 0.0, 'nu03': 0.0, 'm10': 45.0, 'm20': 285.0, 'm21': 2025.0}

What is the cv3 equivalent syntax for matchShapes?

jtlz2 gravatar imagejtlz2 ( 2017-07-20 02:31:31 -0600 )edit

it'S the same syntax, see above. (still cv2, though)

berak gravatar imageberak ( 2017-07-20 02:38:51 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-07-20 01:15:13 -0600

Seen: 5,202 times

Last updated: Jul 20 '17