簡體   English   中英

python opencv實時攝像機提要,縮放對象

[英]python opencv live camera feed, scale object

我有以下代碼可識別對象/符號。 我的問題是,當物體靠近或遠離物體時,我該如何改進我的代碼以識別物體? 可以說我加載了一個符號,並且需要在不同范圍內對其進行識別。

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代碼的絕佳指南: 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在下面的評論進行了編輯!

為了解決您的第二個代碼段,有一些問題,但是您比想像中要親密得多!

  1. 它使用Canny邊緣作為視頻幀,但不使用模板。 應該為兩者都做Canny,或者兩者都不做。 在該示例中,他使用Canny,這對於查找文本徽標非常有用,但如果您的模板是隨處可見的基本形狀,就不會那么好。 例如,我在紙上畫了一個加號用作模板,它也想選擇圖像中的每個角。 僅使用常規圖像而不是邊緣圖像,對我的模板效果更好。
  2. 您仍在使用loc = np.where(result >= threshold) ,但是已經將最大值及其對應的位置存儲在found 您需要做的就是在maxVal >= 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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM