सवाल मॉड्यूल 'ऑब्जेक्ट में कोई विशेषता नहीं है' drawMatches 'opencv पायथन


मैं ओपनसीवी में फीचर डिटेक्शन का एक उदाहरण कर रहा हूं। यह उदाहरण नीचे दिखाया गया है। यह मुझे निम्नलिखित त्रुटि दे रहा है

मॉड्यूल 'ऑब्जेक्ट में कोई विशेषता नहीं है' drawMatches '

मैंने ओपनसीवी डॉक्स की जांच की है और मुझे यकीन नहीं है कि मुझे यह त्रुटि क्यों मिल रही है। क्या किसी को पता है क्यों?

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

img1 = cv2.imread('box.png',0)          # queryImage
img2 = cv2.imread('box_in_scene.png',0) # trainImage

# Initiate SIFT detector
orb = cv2.ORB()

# find the keypoints and descriptors with SIFT
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# Match descriptors.
matches = bf.match(des1,des2)

# Draw first 10 matches.
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2)

plt.imshow(img3),plt.show()

त्रुटि:

Traceback (most recent call last):
File "match.py", line 22, in <module>
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2)
AttributeError: 'module' object has no attribute 'drawMatches'

44
2017-11-28 06:17


मूल


के संभावित डुप्लिकेट पायथन में opencv मॉड्यूल का उपयोग कर वर्णनकर्ता मिलान को कैसे विज़ुअलाइज़ करें - Lokesh A. R.
कौन सा दस्तावेज़? और सुनिश्चित करें कि आप सही संस्करण का उपयोग कर रहे हैं। - aIKid
डॉक्स। opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/... - Javed
ये आधिकारिक ओपनसीवी डॉक्स नहीं हैं! आधिकारिक ओपनसीवी डॉक्स इस पर पाया जा सकता है: docs.opencv.org - Mailerdaimon
आधिकारिक डॉक्स: दुर्भाग्य से मैंने यह ओपनसीवी 3.0.0-dev दस्तावेज देखा है - Javed


जवाब:


drawMatches फ़ंक्शन पायथन इंटरफ़ेस का हिस्सा नहीं है।
जैसा कि आप देख सकते हैं डॉक्स, यह केवल के लिए परिभाषित किया गया है C++ इस समय।

दस्तावेज़ों से उद्धरण:

 C++: void drawMatches(const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const vector<KeyPoint>& keypoints2, const vector<DMatch>& matches1to2, Mat& outImg, const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), const vector<char>& matchesMask=vector<char>(), int flags=DrawMatchesFlags::DEFAULT )
 C++: void drawMatches(const Mat& img1, const vector<KeyPoint>& keypoints1, const Mat& img2, const vector<KeyPoint>& keypoints2, const vector<vector<DMatch>>& matches1to2, Mat& outImg, const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), const vector<vector<char>>& matchesMask=vector<vector<char> >(), int flags=DrawMatchesFlags::DEFAULT )

अगर फ़ंक्शन में पाइथन इंटरफ़ेस था, तो आपको ऐसा कुछ मिल जाएगा:

 Python: cv2.drawMatches(img1, keypoints1, [...]) 

संपादित करें 

वास्तव में एक था प्रतिबद्ध जिसने 5 महीने पहले इस समारोह को पेश किया था। हालांकि, यह आधिकारिक दस्तावेज में (अभी तक) नहीं है।
सुनिश्चित करें कि आप नवीनतम ओपनसीवी संस्करण (2.4.7) का उपयोग कर रहे हैं। पूर्णता के लिए ओपनसीवी 3.0.0 के लिए फ़ंक्शन इंटरफ़ेस जैसा दिखता है इस:

cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches1to2[, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]]) → outImg

18
2017-11-28 07:23



मैंने इसे यहाँ देखा है opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/... - Javed
मेरा संपादन देखें, इसे 5 महीने पहले जोड़ा गया था लेकिन आधिकारिक दस्तावेज़ों में नहीं है (अभी तक)। - Mailerdaimon
तुम सही हो प्रिय ..... - Javed
अगर मेरे उत्तर में मदद मिली, तो कृपया इसे स्वीकार करने पर विचार करें। उत्तर को स्वीकार करने के रूप में चिह्नित करने के लिए, खोखले से हरे रंग तक टॉगल करने के उत्तर के बगल में स्थित चेक मार्क पर क्लिक करें। धन्यवाद! - Mailerdaimon
यदि कोई प्रतिबद्धता है, तो इसका मतलब यह नहीं होना चाहिए कि यह कार्य उपलब्ध है? मैं इसे अपने py2.7.6_0 ओपनसीवी 2.4.8_0 के साथ स्थापित नहीं कर सकता - Paul Seeb


मैं पार्टी के लिए भी देर हो चुकी हूं, लेकिन मैक ओएस एक्स के लिए ओपनसीवी 2.4.9 स्थापित किया गया, और drawMatches समारोह मेरे वितरण में मौजूद नहीं है। मैंने दूसरे दृष्टिकोण की भी कोशिश की है find_obj और यह मेरे लिए भी काम नहीं करता था। इसके साथ में, मैंने इसका अपना कार्यान्वयन लिखने का फैसला किया जो नकल करता है drawMatches मेरी सबसे अच्छी क्षमता के लिए और यही वह है जो मैंने बनाया है।

मैंने अपनी खुद की छवियां प्रदान की हैं जहां एक कैमरा आदमी का है, और दूसरा एक ही छवि है लेकिन 55 डिग्री घुमावदार घुमावदार है।

मैंने जो लिखा है, उसकी मूल बातें यह है कि मैं एक आउटपुट आरजीबी छवि आवंटित करता हूं जहां पंक्तियों की मात्रा आउटपुट छवि में दोनों छवियों को रखने के लिए समायोजित करने के लिए अधिकतम दो छवियों में से एक है और कॉलम केवल कॉलम दोनों का संक्षेप है । सलाह दीजिए कि मुझे लगता है कि दोनों छवियां ग्रेस्केल हैं।

मैं प्रत्येक छवि को उनके संबंधित स्थानों में रखता हूं, फिर मिलान किए गए कीपॉइंट्स के लूप के माध्यम से चलाता हूं। मैं निकालें कि कौन सी कीपॉइंट्स दो छवियों के बीच मेल खाती हैं, फिर उन्हें निकालें (x,y) समन्वय करता है। मैं प्रत्येक ज्ञात स्थानों पर मंडलियों को आकर्षित करता हूं, फिर इन मंडलियों को एक साथ जोड़ने वाली रेखा खींचता हूं।

ध्यान रखें कि दूसरी छवि में पता लगाया गया मुख्य बिंदु अपने समन्वय तंत्र के संबंध में है। यदि आप इसे अंतिम आउटपुट छवि में रखना चाहते हैं, तो आपको पहली छवि से कॉलम की मात्रा से कॉलम समन्वय को ऑफ़सेट करना होगा ताकि कॉलम समन्वय आउटपुट छवि के समन्वय प्रणाली के संबंध में हो।

बिना और देरी के:

import numpy as np
import cv2

def drawMatches(img1, kp1, img2, kp2, matches):
    """
    My own implementation of cv2.drawMatches as OpenCV 2.4.9
    does not have this function available but it's supported in
    OpenCV 3.0.0

    This function takes in two images with their associated 
    keypoints, as well as a list of DMatch data structure (matches) 
    that contains which keypoints matched in which images.

    An image will be produced where a montage is shown with
    the first image followed by the second image beside it.

    Keypoints are delineated with circles, while lines are connected
    between matching keypoints.

    img1,img2 - Grayscale images
    kp1,kp2 - Detected list of keypoints through any of the OpenCV keypoint 
              detection algorithms
    matches - A list of matches of corresponding keypoints through any
              OpenCV keypoint matching algorithm
    """

    # Create a new output image that concatenates the two images together
    # (a.k.a) a montage
    rows1 = img1.shape[0]
    cols1 = img1.shape[1]
    rows2 = img2.shape[0]
    cols2 = img2.shape[1]

    # Create the output image
    # The rows of the output are the largest between the two images
    # and the columns are simply the sum of the two together
    # The intent is to make this a colour image, so make this 3 channels
    out = np.zeros((max([rows1,rows2]),cols1+cols2,3), dtype='uint8')

    # Place the first image to the left
    out[:rows1,:cols1] = np.dstack([img1, img1, img1])

    # Place the next image to the right of it
    out[:rows2,cols1:] = np.dstack([img2, img2, img2])

    # For each pair of points we have between both images
    # draw circles, then connect a line between them
    for mat in matches:

        # Get the matching keypoints for each of the images
        img1_idx = mat.queryIdx
        img2_idx = mat.trainIdx

        # x - columns
        # y - rows
        (x1,y1) = kp1[img1_idx].pt
        (x2,y2) = kp2[img2_idx].pt

        # Draw a small circle at both co-ordinates
        # radius 4
        # colour blue
        # thickness = 1
        cv2.circle(out, (int(x1),int(y1)), 4, (255, 0, 0), 1)   
        cv2.circle(out, (int(x2)+cols1,int(y2)), 4, (255, 0, 0), 1)

        # Draw a line in between the two points
        # thickness = 1
        # colour blue
        cv2.line(out, (int(x1),int(y1)), (int(x2)+cols1,int(y2)), (255,0,0), 1)


    # Show the image
    cv2.imshow('Matched Features', out)
    cv2.waitKey(0)
    cv2.destroyWindow('Matched Features')

    # Also return the image if you'd like a copy
    return out

यह वर्णन करने के लिए कि यह काम करता है, यहां दी गई दो छवियां हैं जिनका मैंने उपयोग किया था:

Cameraman Image

Rotated Cameraman Image

मैंने कीपॉइंट्स का पता लगाने के लिए ओपनसीवी के ओआरबी डिटेक्टर का इस्तेमाल किया, और समानता के लिए दूरी माप के रूप में सामान्यीकृत हैमिंग दूरी का उपयोग किया क्योंकि यह एक बाइनरी डिस्क्रिप्टर है। जैसे की:

import numpy as np
import cv2

img1 = cv2.imread('cameraman.png', 0) # Original image - ensure grayscale
img2 = cv2.imread('cameraman_rot55.png', 0) # Rotated image - ensure grayscale

# Create ORB detector with 1000 keypoints with a scaling pyramid factor
# of 1.2
orb = cv2.ORB(1000, 1.2)

# Detect keypoints of original image
(kp1,des1) = orb.detectAndCompute(img1, None)

# Detect keypoints of rotated image
(kp2,des2) = orb.detectAndCompute(img2, None)

# Create matcher
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# Do matching
matches = bf.match(des1,des2)

# Sort the matches based on distance.  Least distance
# is better
matches = sorted(matches, key=lambda val: val.distance)

# Show only the top 10 matches - also save a copy for use later
out = drawMatches(img1, kp1, img2, kp2, matches[:10])

यह वह छवि है जो मुझे मिलती है:

Matched Features


के साथ उपयोग करने के लिए knnMatch से cv2.BFMatcher

मैं एक नोट बनाना चाहता हूं जहां उपर्युक्त कोड केवल तभी काम करता है जब आप मानते हैं कि मैचों को 1 डी सूची में दिखाई देता है। हालांकि, अगर आप इसका उपयोग करने का फैसला करते हैं knnMatchसे विधि cv2.BFMatcher उदाहरण के लिए, क्या लौटाया जाता है सूचियों की एक सूची है। विशेष रूप से, वर्णनकर्ताओं को दिया गया img1 बुलाया des1 और वर्णनकर्ताओं में img2 बुलाया des2, सूची में प्रत्येक तत्व से लौटा दिया knnMatch की एक और सूची है k से मैच des2 जो प्रत्येक वर्णनकर्ता के सबसे नज़दीकी हैं des1। इसलिए, आउटपुट से पहला तत्व knnMatch की एक सूची है k से मैच des2 जो पहले वर्णक के सबसे नज़दीकी थे des1। आउटपुट से दूसरा तत्व knnMatch की एक सूची है k से मैच des2 जो कि दूसरे वर्णनकर्ता के सबसे नज़दीकी थे des1 और इसी तरह।

सबसे अधिक समझने के लिए knnMatch, आप जरूर मिलान करने के लिए पड़ोसियों की कुल राशि सीमित करें k=2। इसका कारण यह है कि आप मैच की गुणवत्ता को सत्यापित करने के लिए कम से कम दो मिलान किए गए बिंदुओं का उपयोग करना चाहते हैं और यदि गुणवत्ता पर्याप्त है, तो आप इन्हें अपने मैचों को आकर्षित करने और स्क्रीन पर दिखाने के लिए इनका उपयोग करना चाहेंगे। आप एक बहुत ही सरल अनुपात परीक्षण का उपयोग कर सकते हैं (क्रेडिट जाता है डेविड लोवे) यह सुनिश्चित करने के लिए कि पहले मिलान बिंदु से दूरी des2 में वर्णक के लिए des1 दूसरे मिलान बिंदु की तुलना में कुछ दूरी दूर है des2। इसलिए, जो वापस लौटाया जाता है उसे बदलने के लिए knnMatch मैंने जो कोड लिखा है, उसके साथ क्या आवश्यक है, मैचों के माध्यम से पुनरावृत्त करें, उपर्युक्त अनुपात परीक्षण का उपयोग करें और जांचें कि यह गुजरता है या नहीं। यदि ऐसा होता है, तो पहले मिलान किए गए कीपॉइंट को एक नई सूची में जोड़ें।

यह मानते हुए कि आपने सभी चरों को घोषित करने से पहले किया था BFMatcher उदाहरण के लिए, अब आप इसे अनुकूलित करने के लिए ऐसा करेंगे knnMatch उपयोग करने के लिए विधि drawMatches:

# Create matcher
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# Perform KNN matching
matches = bf.knnMatch(des1, des2, k=2)

# Apply ratio test
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
       # Add first matched keypoint to list
       # if ratio test passes
       good.append(m)

# Or do a list comprehension
#good = [m for (m,n) in matches if m.distance < 0.75*n.distance]

# Now perform drawMatches
out = drawMatches(img1, kp1, img2, kp2, good)

मैं उपर्युक्त संशोधनों को उपयोगकर्ता को विशेषता देना चाहता हूं @ryanmeasel और जवाब कि इन संशोधनों को मिला उनके पद में है: ओपनसीवी पायथन: कोई drawMatchesknn फ़ंक्शन नहीं


77
2017-10-07 02:51



इसके लिए धन्यवाद ... 'आउट' लौटाना बहुत उपयोगी है क्योंकि मैं एक छोटे से एम्बेडेड डिवाइस पर चल रहा हूं और मुझे ओपनसीवी को फिर से कंपाइल करने के लिए 10 घंटे लग जाएगा। मुझे अपना काम पूरा करने और बिस्तर पर जाने की अनुमति दी :) - wentbackward
@ वेंटबैकवर्ड - हैलो! आपका स्वागत है! लौटने में अच्छी नौकरी out। मैं केवल वास्तविक छवि मिलान दिखाने के लिए, लेकिन लौटने का इरादा रखता हूं out बाद में दिखाने के लिए परिणामों को बचाने के लिए बहुत अच्छा है :) सभी बेहतरीन! - rayryeng
आप एक सजन हो। - Aphire
@ अफ़ीर - आह धन्यवाद :) खुशी है कि इस कोड ने आपकी मदद की! - rayryeng
@rayryeng हाय, क्या आपके पास कोई विचार है, मुझे यह त्रुटि क्यों मिल रही है: ValueError: could not broadcast input array from shape (347,550,9) into shape (347,550,3)? यह त्रुटि उस पंक्ति में होती है जहां आप बाईं ओर पहली छवि डाल रहे हैं। - primoz


मुझे पता है कि इस प्रश्न में एक स्वीकार्य उत्तर है जो सही है, लेकिन यदि आप ओपनसीवी 2.4.8 और 3.0 (-dev) का उपयोग नहीं कर रहे हैं, तो इसमें शामिल नमूने से कुछ फ़ंक्शंस का उपयोग करने के लिए एक वर्कअराउंड हो सकता है opencv\sources\samples\python2\find_obj

import cv2
from find_obj import filter_matches,explore_match

img1 = cv2.imread('../c/box.png',0)          # queryImage
img2 = cv2.imread('../c/box_in_scene.png',0) # trainImage

# Initiate SIFT detector
orb = cv2.ORB()

# find the keypoints and descriptors with SIFT
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING)#, crossCheck=True)

matches = bf.knnMatch(des1, trainDescriptors = des2, k = 2)
p1, p2, kp_pairs = filter_matches(kp1, kp2, matches)
explore_match('find_obj', img1,img2,kp_pairs)#cv2 shows image

cv2.waitKey()
cv2.destroyAllWindows()

यह आउटपुट छवि है:

enter image description here


16
2018-02-24 13:29



धन्यवाद नोब, लेकिन मैंने खुद को आवश्यक फ़ंक्शन के लिए एक इंटरफेस जोड़ा और दूसरों के लिए भी काम करता है ... अभी भी धन्यवाद - Javed