Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python OpenCV特征匹配图像中的多个相似对象_Python_Image_Python 3.x_Opencv_Image Processing - Fatal编程技术网

Python OpenCV特征匹配图像中的多个相似对象

Python OpenCV特征匹配图像中的多个相似对象,python,image,python-3.x,opencv,image-processing,Python,Image,Python 3.x,Opencv,Image Processing,我目前有一个项目,我需要使用OpenCV和Python查找照片中列出的带圆圈的X。我尝试过使用模板匹配和特征匹配,但是我只能得到从照片中裁剪出来的一个X作为查询图像。查询照片与其他X不完全相同,但非常相似,因此我不明白为什么特征匹配无法检测到其他X。这段代码是从另一个教程中提取出来的,但我似乎无法实现这一点。请帮忙 当前代码: import cv2 from matplotlib import pyplot as plt MIN_MATCH_COUNT = 3 img1 = cv2.

我目前有一个项目,我需要使用OpenCV和Python查找照片中列出的带圆圈的X。我尝试过使用模板匹配和特征匹配,但是我只能得到从照片中裁剪出来的一个X作为查询图像。查询照片与其他X不完全相同,但非常相似,因此我不明白为什么特征匹配无法检测到其他X。这段代码是从另一个教程中提取出来的,但我似乎无法实现这一点。请帮忙

当前代码:

    import cv2
from matplotlib import pyplot as plt

MIN_MATCH_COUNT = 3

img1 = cv2.imread('template.jpg', 0)  # queryImage
img2 = cv2.imread('originalPic.jpg', 0) # trainImage

orb = cv2.ORB_create(10000, 1.2, nlevels=8, edgeThreshold = 5)

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

import numpy as np
from sklearn.cluster import MeanShift, estimate_bandwidth

x = np.array([kp2[0].pt])

for i in range(len(kp2)):
    x = np.append(x, [kp2[i].pt], axis=0)

x = x[1:len(x)]

bandwidth = estimate_bandwidth(x, quantile=0.1, n_samples=500)

ms = MeanShift(bandwidth=bandwidth, bin_seeding=True, cluster_all=True)
ms.fit(x)
labels = ms.labels_
cluster_centers = ms.cluster_centers_

labels_unique = np.unique(labels)
n_clusters_ = len(labels_unique)
print("number of estimated clusters : %d" % n_clusters_)

s = [None] * n_clusters_
for i in range(n_clusters_):
    l = ms.labels_
    d, = np.where(l == i)
    print(d.__len__())
    s[i] = list(kp2[xx] for xx in d)

des2_ = des2

for i in range(n_clusters_):

    kp2 = s[i]
    l = ms.labels_
    d, = np.where(l == i)
    des2 = des2_[d, ]

    FLANN_INDEX_KDTREE = 0
    index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
    search_params = dict(checks = 50)

    flann = cv2.FlannBasedMatcher(index_params, search_params)

    des1 = np.float32(des1)
    des2 = np.float32(des2)

    matches = flann.knnMatch(des1, des2, 2)

    # store all the good matches as per Lowe's ratio test.
    good = []
    for m,n in matches:
        if m.distance < 0.7*n.distance:
            good.append(m)

    if len(good)>3:
        src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
        dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)

        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 2)

        if M is None:
            print ("No Homography")
        else:
            matchesMask = mask.ravel().tolist()

            h,w = img1.shape
            pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
            dst = cv2.perspectiveTransform(pts,M)

            img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA)

            draw_params = dict(matchColor=(0, 255, 0),  # draw matches in green color
                               singlePointColor=None,
                               matchesMask=matchesMask,  # draw only inliers
                               flags=2)

            img3 = cv2.drawMatches(img1, kp1, img2, kp2, good, None, **draw_params)

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

    else:
        print ("Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT))
        matchesMask = None
导入cv2
从matplotlib导入pyplot作为plt
最小匹配计数=3
img1=cv2.imread('template.jpg',0)#查询图像
img2=cv2.imread('originalPic.jpg',0)#列车图像
orb=cv2.orb_create(10000,1.2,nlevels=8,edgeThreshold=5)
#使用ORB查找关键点和描述符
kp1,des1=orb.detectAndCompute(img1,无)
kp2,des2=orb.detectAndCompute(img2,无)
将numpy作为np导入
从sklearn.cluster import MeanShift,估计\u带宽
x=np.array([kp2[0].pt])
对于范围内的i(len(kp2)):
x=np.append(x[kp2[i].pt],轴=0)
x=x[1:len(x)]
带宽=估计带宽(x,分位数=0.1,n_样本=500)
ms=MeanShift(带宽=bandwidth,bin\u seaking=True,cluster\u all=True)
菲特女士(x)
标签=ms标签_
群集\u中心=ms.cluster\u中心_
标签\u unique=np.unique(标签)
n\u集群\uu=len(标签\u唯一)
打印(“估计的群集数:%d”%n\u群集\u)
s=[None]*n_集群_
对于范围内的i(n_簇):
l=ms标签_
d、 =np.其中(l==i)
打印(d._;len__;()
s[i]=列表(d中xx的kp2[xx]
des2=des2
对于范围内的i(n_簇):
kp2=s[i]
l=ms标签_
d、 =np.其中(l==i)
des2=des2_d,]
法兰索引KDTREE=0
索引参数=dict(算法=FLANN\u索引树,树=5)
搜索参数=dict(检查=50)
flann=cv2.FlannBasedMatcher(索引参数、搜索参数)
des1=np.32(des1)
des2=np.32(des2)
匹配=法兰。knnMatch(des1、des2、2)
#根据Lowe比率测试存储所有良好匹配项。
好的=[]
对于匹配中的m,n:
如果m.距离<0.7*n.距离:
好。追加(m)
如果len(良好)>3:
src_pts=np.float32([kp1[m.queryIdx].pt代表m处于良好状态])。重塑(-1,1,2)
dst_pts=np.float32([kp2[m.trainIdx].pt代表m处于良好状态])。重塑(-1,1,2)
M、 掩模=cv2.findHomography(src_pts,dst_pts,cv2.RANSAC,2)
如果M为无:
打印(“无单应性”)
其他:
matchesMask=mask.ravel().tolist()
h、 w=img1.1形状
pts=np.float32([[0,0],[0,h-1],[w-1,h-1],[w-1,0]])。重塑(-1,1,2)
dst=cv2.透视变换(pts,M)
img2=cv2.多段线(img2[np.int32(dst)],真,255,3,cv2.线_AA)
draw_params=dict(matchColor=(0,255,0),#以绿色绘制匹配
singlePointColor=无,
matchesMask=matchesMask,#只绘制内线
旗帜=2)
img3=cv2.绘图匹配(img1、kp1、img2、kp2、良好、无、**绘图参数)
plt.imshow(img3,‘灰色’),plt.show()
其他:
打印(“未找到足够的匹配项-%d/%d”%(长度(良好),最小匹配数))
matchesMask=None
|
这是一种更简单的方法,只使用openCV和numpy。由于查询图像的大小远小于火车图像的大小,我首先将火车图像缩小了0.33倍以适合我的屏幕,然后创建了一个函数来迭代查询图像的各种大小,因为对于这种方法,您也必须匹配大小

当然,您可以调整变量fx和fy、mult和threshold,以查看可以获得多少个X。从粗略迭代中,我的最大值是3,但下面的设置实现了2:

import cv2
import numpy as np

originalPicRead = cv2.imread('originalPic.jpg')
img_bgr = cv2.resize(originalPicRead, (0,0), fx=0.33, fy=0.33)
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)

templateR = cv2.imread('template.jpg',0)

w,h = templateR.shape[::-1]

for magn in range(1,11):
    mult = magn*0.35
    w,h = int(mult*w),int(mult*h)
    template = cv2.resize(templateR, (0,0), fx=mult, fy = mult)

    res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
    threshold = 0.35
    loc = np.where(res >= threshold)

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

cv2.imshow('Detected', img_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()

如果您想简单地检测图片中的多个X,那么有一种不使用sklearn的简单方法,即cv2和numpy。