4

Here is my code, and i am getting an AttributeError: 'tuple' object has no attribute 'sort. I am trying to do an image alignment and found this standard image alignment code in an article. I am learning openCV and python which i am really new too, I am able to do basic stuff with openCV right now i am trying to learn image alignment and i am stuck on this part.

Traceback (most recent call last):
  File "test9.py", line 31, in <module>
    matches.sort(key = lambda x: x.distance)
AttributeError: 'tuple' object has no attribute 'sort'


------------------
(program exited with code: 1)
Press return to continue


import cv2
import numpy as np

# Open the image files.
img1_color = cv2.imread("/home/pi/Desktop/Project AOI/testboard1/image_2.jpg") # Image to be aligned.
img2_color = cv2.imread("/home/pi/Desktop/Project AOI/testboard1/image_0.jpg") # Reference image.

# Convert to grayscale.
img1 = cv2.cvtColor(img1_color, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(img2_color, cv2.COLOR_BGR2GRAY)
height, width = img2.shape

# Create ORB detector with 5000 features.
orb_detector = cv2.ORB_create(5000)

# Find keypoints and descriptors.
# The first arg is the image, second arg is the mask
# (which is not required in this case).
kp1, d1 = orb_detector.detectAndCompute(img1, None)
kp2, d2 = orb_detector.detectAndCompute(img2, None)

# Match features between the two images.
# We create a Brute Force matcher with
# Hamming distance as measurement mode.
matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)

# Match the two sets of descriptors.
matches = matcher.match(d1, d2)

# Sort matches on the basis of their Hamming distance.
matches.sort(key = lambda x: x.distance)

# Take the top 90 % matches forward.
matches = matches[:int(len(matches)*0.9)]
no_of_matches = len(matches)

# Define empty matrices of shape no_of_matches * 2.
p1 = np.zeros((no_of_matches, 2))
p2 = np.zeros((no_of_matches, 2))

for i in range(len(matches)):
    p1[i, :] = kp1[matches[i].queryIdx].pt
    p2[i, :] = kp2[matches[i].trainIdx].pt

# Find the homography matrix.
homography, mask = cv2.findHomography(p1, p2, cv2.RANSAC)

# Use this matrix to transform the
# colored image wrt the reference image.
transformed_img = cv2.warpPerspective(img1_color,
                    homography, (width, height))

# Save the output.
cv2.imwrite('output.jpg', transformed_img)
2
  • yeah sorry, OpenCV has changed its python bindings generation in some unfortunate ways. you're getting a tuple, not a list, returned. you can't just .sort() that. you have to use sorted(matches, ...) Commented Jul 28, 2022 at 19:02
  • Thanks a lot for your help. Tour was helpful for me to understand and navigating this site. Commented Jul 29, 2022 at 12:07

1 Answer 1

4

You're getting a tuple returned, not a list. You can't just matches.sort(...) that.

OpenCV, since v4.5.4, exhibits this behavior in its Python bindings generation.

You have to use this instead:

matches = sorted(matches, ...)

This creates a new list, which contains the sorted elements of the original tuple.

Related issues:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.