我OpenCV
真的很新。我正在阅读一些教程和文档,以便制作我的第一个小脚本。
我有一张图片,我想detect objects
这张照片:路灯,垃圾桶......
我的图片如下:
我写了这个剧本:
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)
但是如何用矩形显示图片结果?
非常感谢你!
答案 0 :(得分:2)
我猜对象检测,我个人使用并向所有人推荐,是使用SIFT(Scale-Invariant Feature Transform)或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()
继续使用基于FLANN的匹配器
FLANN代表近似最近邻居的快速图书馆。它 包含一组针对快速最近的算法优化的算法 邻居搜索大型数据集和高维特征。 对于大型数据集,它比BFMatcher更快。我们会看到 基于FLANN的匹配器的第二个例子。
对于基于FLANN的匹配器,我们需要传递两个词典 指定要使用的算法,其相关参数等 一个是IndexParams。对于各种算法,信息是 传递在FLANN文档中解释。作为总结,对于像这样的算法 SIFT,SURF等。
使用带有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()
请参阅以下结果:
但我推荐的是,与ORB描述符的强力匹配
在此示例中,我将ORB与Bruteforce matcher一起使用,此代码捕获 来自摄像机的实时帧,并计算关键点,描述符 从输入框架中将其与存储的查询图像进行比较 做同样的事情,并返回匹配的关键点长度, 同样可以应用于使用SIFT算法代替的上述代码 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()
更多描述性视频教程可在此处找到, https://www.youtube.com/watch?v=ZW3nrP2OyLQ还有一件好事 它的开源: https://gitlab.com/josemariasoladuran/object-recognition-opencv-python.git
答案 1 :(得分:0)
我发布了代码作为答案,但它只显示过滤器检索到的轮廓。如果您的图像是B&amp; W并且不是超级复杂,那么这种类型的过滤器有利于轮廓检索。否则我认为你在寻找的是物体周围的边界框。这需要比一些过滤器更多。
我还添加了matplotlib显示,因为这是你最初要求的,但是你可以这样做不是很有用。
import cv2
import matplotlib.pyplot as plt
img_orig = cv2.imread('ville.jpg',0)
img_filt = cv2.medianBlur(img_orig, 5)
img_th = cv2.adaptiveThreshold(img_filt,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
contours, hierarchy = cv2.findContours(img_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
plt.imshow(img_orig)
cv2.drawContours(img_orig,contours,-1,(128,255,0),1)
display = cv2.imshow("Objects",img_orig)
wait_time = cv2.waitKey(0)
cv2.destroyAllWindows()
其他有用的链接: http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html
稍后编辑一些有用的文献,可以帮助您开始进行高级对象检测,您可以在此处找到:http://www.cs.utoronto.ca/~fidler/teaching/2015/CSC2523.html
注意:这更多地涉及有意义的物体检测,而不仅仅是检测描述形状的简单轮廓。