Soru 'object' özniteliği yoktur 'drawMatches' opencv python


OpenCV'de sadece bir özellik tespiti örneği yapıyorum. Bu örnek aşağıda gösterilmiştir. Bana şu hatayı veriyor

'object' özniteliği yoktur 'drawMatches'

OpenCV Dokümanlarını kontrol ettim ve neden bu hatayı aldığımı bilmiyorum. Nedenini bilen var mı?

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()

Hata:

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


Menşei


olası kopyası Python'da opencv modülünü kullanarak tanımlayıcı eşleştirmeyi nasıl görselleştirilir - Lokesh A. R.
hangi dokümanlar Doğru sürümü kullandığınızdan emin olun. - aIKid
docs. opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/... - Javed
Bunlar resmi OpenCV Dokümanlar değil! Resmi OpenCV Dokümanları şu adreste bulunabilir: docs.opencv.org - Mailerdaimon
Resmi Dokümanlar: Maalesef bu OpenCV 3.0.0-dev belgelerini gördüm - Javed


Cevaplar:


drawMatches İşlev, Python arabiriminin bir parçası değildir.
Gördüğünüz gibi docs, sadece tanımlanmış C++ Şu an.

Dokümanlar'dan alıntı:

 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 )

İşlev bir Python arabirimine sahip olsaydı, şöyle bir şey bulursun:

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

DÜZENLE 

Aslında bir işlemek Bu fonksiyonu 5 ay önce tanıttı. Ancak, resmi belgelerde (henüz) değildir.
En yeni OpenCV sürümünü kullandığınızdan emin olun (2.4.7). Tamlığı sağlamak için OpenCV 3.0.0 için Fonksiyonlar arayüzü bu:

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

18
2017-11-28 07:23



Ben onu burada gördüm opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/... - Javed
Düzenleme bölümüne bakın, 5 Ay önce eklendi ancak resmi dokümanlar (henüz) eklenmedi. - Mailerdaimon
Haklisin canim ..... - Javed
Cevabım yardımcı olursa, lütfen kabul etmeyi düşünün. Bir cevabı kabul edildi olarak işaretlemek için, içi boştan yeşile geçmek için yanıtın yanındaki onay işaretine tıklayın. Teşekkürler! - Mailerdaimon
Bir taahhüt varsa, bu fonksiyonun mevcut olduğu anlamına mı gelmez? OpenCV 2.4.8_0 ile py2.7.6_0 yüklemem ile kullanamıyorum - Paul Seeb


Ben de partiye geç kaldım, ama Mac OS X için OpenCV 2.4.9'u kurdum. drawMatches dağıtımımda işlev yok. İkinci yaklaşımı da denedim find_obj ve bu da benim için çalışmadı. Bununla, kendi taklitlerimi kendim yazmam için karar verdim. drawMatches yeteneğimin en iyisine ve bu benim ürettiğim şey.

Bir kameranın nerede olduğunu kendi resimlerimi sağladım, diğeri ise aynı görüntü ancak saat yönünün tersine 55 derece döndürüldü.

Yazdıklarımın temelleri, çıktı miktarındaki görüntülerin her ikisini de yerleştirmek için satırların miktarının maksimum iki görüntü olduğu ve sütunların her iki sütunun birlikte toplamı olduğu bir çıkış RGB görüntüsü tahsis etmekti. . Her iki görüntünün de gri tonlamalı olduğunu varsayalım.

Her görüntüyü karşılık gelen noktalara yerleştiriyorum, ardından eşleşen tüm anahtar noktalarının bir döngüsünden geçiyorum. İki görüntü arasında hangi anahtar noktaların eşleştiğini alıp (x,y) koordine eder. Algılanan konumların her birine daireler çiziyorum, ardından bu çemberleri birbirine bağlayan bir çizgi çiziyorum.

İkinci görüntüdeki tespit edilen anahtar noktasının kendi koordinat sistemine göre olduğunu aklınızda bulundurun. Bunu son çıktı görüntüsüne yerleştirmek isterseniz, sütun koordinatını ilk görüntüdeki sütun sayısıyla dengelemeniz gerekir, böylece sütun koordinatı çıktı görüntüsünün koordinat sistemine göre olur.

Daha fazla uzatmadan:

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

Bunun işe yaradığını göstermek için, burada kullandığım iki resim var:

Cameraman Image

Rotated Cameraman Image

Anahtar noktalarını tespit etmek için OpenCV'nin ORB dedektörünü kullandım ve normalleştirilmiş Hamming mesafesini, ikili bir tanımlayıcı olduğu için benzerlik için mesafe ölçüsü olarak kullandım. Gibi:

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])

Bu aldığım görüntü:

Matched Features


İle kullanmak için knnMatch itibaren cv2.BFMatcher

Yukarıdaki kodun yalnızca eşleşmelerin 1D listesinde görüneceğini varsayarsanız, bir not yazmak istiyorum. Ancak, kullanmaya karar verirseniz knnMatchyöntemi cv2.BFMatcher örneğin, iade edilenler bir liste listesidir. Özellikle, içindeki tanımlayıcılar göz önüne alındığında img1 denilen des1 ve içindeki tanımlayıcılar img2 denilen des2, listedeki her öğe knnMatch başka bir listesi k dan eşleşir des2 içindeki her tanıtıcıya en yakın olan des1. Bu nedenle, ilk eleman çıktısından knnMatch listesi k dan eşleşir des2 bulunan ilk tanımlayıcıya en yakın olan des1. Çıktısından ikinci eleman knnMatch listesi k dan eşleşir des2 bulunan ikinci tanımlayıcıya en yakın olan des1 ve bunun gibi.

En mantıklı olmak knnMatch, sen şart eşleşecek toplam komşu miktarını sınırlamak k=2. Bunun nedeni, eşleşmenin kalitesini doğrulamak için en az iki eşleşme noktası kullanmak istediğinizden ve kalitenin yeterince iyi olması durumunda, bunları kibritlerinizi çizmek ve ekranda göstermek için kullanmak isteyeceksiniz. Çok basit bir oran testi kullanabilirsiniz. David Loweİlk eşleştirilen noktadan uzaklığı sağlamak des2 içindeki tanıtıcıya des1 ikinci eşleşen noktaya göre biraz uzaktır. des2. Bu nedenle, iade edilenleri döndürmek için knnMatch Yukarıda yazdığım kodla neye ihtiyacım var, eşleşmelerde yineleyin, yukarıdaki oran testini kullanın ve geçip geçmediğini kontrol edin. Bunu yaparsa, ilk eşleşen anahtar noktasını yeni bir listeye ekleyin.

Bildirmeden önce yaptığınız gibi tüm değişkenleri yarattığınızı varsayalım. BFMatcher örneğin, bunu yapmak için şimdi bunu yaparsınız knnMatch kullanmak için yöntem 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)

Yukarıdaki değişiklikleri kullanıcıyla ilişkilendirmek istiyorum @ryanmeasel ve bu değişikliklerin bulunduğuna dair cevabı yazılarında: OpenCV Python: drawMatchesknn işlevi yok.


77
2017-10-07 02:51



Bunun için teşekkürler ... geri dönen 'dışarı' çok küçük bir gömülü cihaz üzerinde koşuyorum ve opencv yeniden derlemek için 10 saat götürdüğümde çok yararlıdır. İşimi bitirip yatağa gitmeme izin verdi :) - wentbackward
@wentbackward - Merhaba! Rica ederim! Dönen güzel iş out. Sadece gerçek görüntü eşlemesini göstermeyi amaçlıyordum, ancak geri geliyor out daha sonra göstermek için sonuçları kaydetmek için harika :) En iyi! - rayryeng
Sen bir centilmensin. - Aphire
@Aphire - ah teşekkürler :) Bu kodun size yardımcı olmasına sevindim! - rayryeng
@rayryeng Merhaba, herhangi bir fikrin var mı, neden bu hatayı alıyorum: ValueError: could not broadcast input array from shape (347,550,9) into shape (347,550,3)? Bu hata, ilk görüntüyü sola yerleştirdiğiniz satırda gerçekleşir. - primoz


Bu sorunun doğru olduğunu kabul eden bir cevabı olduğunu biliyorum, ancak OpenCV 2.4.8 ve 3.0 (-dev) kullanmıyorsanız, aşağıdaki örnekte bulunan örneklerden bazı işlevlerin kullanılması geçici bir çözüm olabilir. 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()

Bu çıktı görüntüsüdür:

enter image description here


16
2018-02-24 13:29



teşekkürler noob ,,, ama kendim gerekli fonksiyon için bir arayüz ekledim ve diğer fonksiyonlar için de ... hala teşekkürler - Javed