使用OpenCV Python检测对象

我是OpenCV的新手.我正在阅读一些教程和文档,以便制作我的第一个小脚本.

我有一个图像,我想检测这个上的物体:路灯,垃圾桶……

我的图片看起来像:

《使用OpenCV Python检测对象》

我写了这个脚本:

import cv2

img_filt = cv2.medianBlur(cv2.imread('ville.jpg',0), 5)
img_th = cv2.adaptiveThreshold(img_filt,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
img_filt, contours, hierarchy = cv2.findContours(img_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

display = cv2.imshow("Objects",img_filt)
wait_time = cv2.waitKey(0)

但我如何用矩形显示图片结果?

非常感谢 !

最佳答案 我猜对象检测,我个人使用并向所有人推荐,是使用SIFT(尺度不变特征变换)或SURF算法,但请注意,这些算法现已获得专利,不再包含在OpenCV 3中,仍然可用于openCV2,作为替代品,我更喜欢使用ORB,它是SIFT / SURF的开源实现.

与SIFT描述符和比率测试的强力匹配

这里我们使用BFMatcher.knnMatch()来获得最佳匹配.在这个例子中,我们将采用k = 2,以便我们可以在他的论文中应用D.Lowe解释的比率测试.

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

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

# Initiate SIFT detector
sift = cv2.SIFT()

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

# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)

# Apply ratio test
good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])

# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,flags=2)

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

《使用OpenCV Python检测对象》

继续使用基于FLANN的Matcher

FLANN stands for Fast Library for Approximate Nearest Neighbors. It
contains a collection of algorithms optimized for fast nearest
neighbor search in large datasets and for high dimensional features.
It works more faster than BFMatcher for large datasets. We will see
the second example with FLANN based matcher.

For FLANN based matcher, we need to pass two dictionaries which
specifies the algorithm to be used, its related parameters etc. First
one is IndexParams. For various algorithms, the information to be
passed is explained in FLANN docs. As a summary, for algorithms like
SIFT, SURF etc.

使用带有SIFT的FLANN的示例代码:

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

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

# Initiate SIFT detector
sift = cv2.SIFT()

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

# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50)   # or pass empty dictionary

flann = cv2.FlannBasedMatcher(index_params,search_params)

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

# Need to draw only good matches, so create a mask
matchesMask = [[0,0] for i in xrange(len(matches))]

# ratio test as per Lowe's paper
for i,(m,n) in enumerate(matches):
    if m.distance < 0.7*n.distance:
        matchesMask[i]=[1,0]

draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = matchesMask,
                   flags = 0)

img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,matches,None,**draw_params)



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

看下面的结果:

《使用OpenCV Python检测对象》

但我推荐的是,与ORB描述符的强力匹配

In this example I used ORB with Bruteforce matcher, this code captures
frames from camera at realtime and computes the keypoints,descriptors
from input frames and compares it with the stored query image, by
doing the same , and returns the matching keypoint lengths, the
same can be applied on above code which uses SIFT algorithm instead of
ORB.

import numpy as np
import cv2
from imutils.video import WebcamVideoStream
from imutils.video import FPS

MIN_MATCH_COUNT = 10

img1 = cv2.imread('input_query.jpg', 0)


orb = cv2.ORB()
kp1, des1 = orb.detectAndCompute(img1, None)

webcam = WebcamVideoStream(src=0).start()
fps = FPS().start()

while True:
    img2 = webcam.read()
    key = cv2.waitKey(10)
    cv2.imshow('',img2)
    if key == 1048603:
        break
    kp2, des2 = orb.detectAndCompute(img2, None)

    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

    matches = bf.match(des1, des2)
    matches = sorted(matches, key=lambda x: x.distance)  # compute the descriptors with ORB

    if not len(matches) > MIN_MATCH_COUNT:
        print "Not enough matches are found - %d/%d" % (len(matches), MIN_MATCH_COUNT)
        matchesMask = None

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

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

    fps.update()

fps.stop()

More descriptive video tutorial on this will be found here,
07002 and one more good thing is
it’s opensource :
07003

点赞