【问题标题】:python opencv live camera feed, scale objectpython opencv live camera feed,缩放对象
【发布时间】:2017-05-16 07:12:03
【问题描述】:

我有以下代码用于识别对象/符号。 我的问题是如何改进我的代码以在物体更近或更远时识别它们? 假设我加载了一个符号,我需要在不同的范围内识别它。

import cv2
import numpy as np

#Camera
cap = cv2.VideoCapture(0)

#symbool inladen
symbool = cv2.imread('klaver.jpg',0)
w, h = symbool.shape[::-1]

while(1):

    res, frame = cap.read()
    img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    res = cv2.matchTemplate(img_gray,symbool,cv2.TM_CCOEFF_NORMED)

    threshold = 0.9
    loc = np.where( res >= threshold)
    for pt in zip(*loc[::-1]):
       # print "hallo"
        cv2.rectangle(img_gray, pt, (pt[0] + w, pt[1] + h), (0,255,255), 1)
    cv2.imshow('Resultaat', img_gray)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

更新:

我已经尝试了下面的教程并想出了以下内容。 问题是识别对象,这个方法是随机绘制矩形,并不关注它自己的对象/符号

import cv2
import numpy as np
import imutils

#Camera
cap = cv2.VideoCapture(0)

#symbool inladen
symbool = cv2.imread('klaver.jpg',0)
w, h = symbool.shape[::-1]

while(1):

    res, frame = cap.read()
    img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    found = None
    #res = cv2.matchTemplate(img_gray,symbool,cv2.TM_CCOEFF_NORMED)
    for scale in np.linspace(0.2, 1.0, 20)[::-1]:

            resized = imutils.resize(img_gray, width = int(img_gray.shape[1] * scale))
            r = img_gray.shape[1] / float(resized.shape[1])

            if resized.shape[0] < h or resized.shape[1] < w:
                break

            edged = cv2.Canny(resized, 50, 200)
            result = cv2.matchTemplate(edged, symbool, cv2.TM_CCOEFF_NORMED)
            (_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)

            clone = np.dstack([edged, edged, edged])
            cv2.rectangle(clone, (maxLoc[0], maxLoc[1]),
            (maxLoc[0] + w, maxLoc[1] + h), (0, 0, 255), 2)

            if found is None or maxVal > found[0]:
                    found = (maxVal, maxLoc, r)

    (_, maxLoc, r) = found
    (startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
    (endX, endY) = (int((maxLoc[0] + w) * r), int((maxLoc[1] + h) * r))


    threshold = 0.9
    loc = np.where( result >= threshold)
    for pt in zip(*loc[::-1]):
       # print "hallo"
       # cv2.rectangle(img_gray, pt, (pt[0] + w, pt[1] + h), (0,255,255), 1)
        cv2.rectangle(img_gray, (startX, startY), (endX, endY), (0, 255, 255), 1)
    cv2.imshow('Resultaat', img_gray)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

【问题讨论】:

    标签: python opencv camera


    【解决方案1】:

    在同一框架内工作的最简单方法是实施金字塔方法。只需以多种分辨率加载图像(或模板)并循环播放。这是一个很好的 Python+OpenCV 代码指南:http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/

    这个方法是提供尺度不变模板匹配。通过使用特征检测(关键点),您可以获得更强大的功能,它允许您为模板进行缩放和旋转不变性。有关使用 SURF 的示例,请参阅 http://robocv.blogspot.com/2012/02/real-time-object-detection-in-opencv.html


    根据以下 OP 的评论进行编辑!

    要解决您的第二个代码 sn-p,存在一些问题,但您可能比您想象的更接近!

    1. 它将 Canny 边缘用于视频帧,但不用于模板。应该为两者都做 Canny,或者不做。在示例中,他使用了 Canny,它非常适合查找文本徽标,但如果您的模板是随处可见的基本形状,则不是很好。例如,我在纸上画了一个加号作为模板,它也想选择我图像中的每个角落。仅使用常规图像而不是边缘图像更适合我的模板。
    2. 您仍在使用loc = np.where(result &gt;= threshold),但您已经将最大值及其对应位置存储在found 中。您只需在maxVal &gt;= threshold 时绘制一个框。
    3. 您的门槛对于这项任务来说太高了。当模板可以是任何比例并且您只计算几个离散比例时,您不应该期望 90% 的匹配,尤其是因为您的模板可能不会每次都完全笔直。

    import cv2
    import numpy as np
    
    #Camera
    cap = cv2.VideoCapture(0)
    
    #symbool inladen
    symbool = cv2.imread('klaver.jpg',0)
    w, h = symbool.shape[::-1]
    
    while(1):
    
        res, frame = cap.read()
        img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        found = None
        #res = cv2.matchTemplate(img_gray,symbool,cv2.TM_CCOEFF_NORMED)
        for scale in np.linspace(0.2, 1.0, 20)[::-1]:
    
                resized = cv2.resize(img_gray, None, fx=scale, fy=scale)
                r = img_gray.shape[1] / float(resized.shape[1])
    
                if resized.shape[0] < h or resized.shape[1] < w:
                    break
    
                result = cv2.matchTemplate(resized, symbool, cv2.TM_CCOEFF_NORMED)
                (_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
    
                if found is None or maxVal > found[0]:
                        found = (maxVal, maxLoc, r)
    
        (maxVal, maxLoc, r) = found
        (startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
        (endX, endY) = (int((maxLoc[0] + w) * r), int((maxLoc[1] + h) * r))
    
    
        threshold = 0.5
        if maxVal >= threshold: 
           cv2.rectangle(img_gray, (startX, startY), (endX, endY), (0, 255, 255), 1)
        cv2.imshow('Resultaat', img_gray)
        k = cv2.waitKey(5) & 0xFF
        if k == 27:
            print(maxVal)
            break
    
    cap.release()
    cv2.destroyAllWindows()
    

    【讨论】:

    • 感谢您的建议,我已经更新了我的帖子。有什么建议吗? surf 方法对我不起作用,因为我无法安装它
    • 此方法使用 Canny 边缘检测器并匹配图像和模板的边缘图。但是,您还没有创建模板的边缘图,只有您的视频帧!再看一下教程中的前几行代码:) 但是,Canny 特别适合使命召唤示例,但您的原始图像可能会更好。我让你的代码工作了,我会把它发回我原来的答案。
    • @P.B,这是运行答案中代码的两个示例:farther templatenearer template
    • 我们仍然需要将阈值设置为 0.8 以仅检测我们需要的对象。感谢您的回复和回答。有用。 @亚历山大雷诺兹
    • Reynold,我还有一个问题,希望您能帮帮我。 symbool = cv2.imread('klaver.jpg',0) 这是一个模板,我想在这里加载4个模板来检测它们。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2019-02-24
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多