亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我想在視頻中定義一個感興趣區域并只處理該區域

我想在視頻中定義一個感興趣區域并只處理該區域

幕布斯6054654 2022-01-11 17:20:44
我在理解 opencv 感興趣的區域時遇到問題。我有一些代碼可以從我的first_frame. 我還可以用我的mouse_draw_rect函數繪制一個矩形?,F在,我希望背景減法只發生在我繪制的矩形內,因為我想加快算法處理速度。我知道我必須設置某種感興趣的區域,但我昨天和今天都嘗試了,但我從教程中嘗試過的都沒有奏效。有人可以幫助指導我完成這個過程嗎?編輯:試圖修復代碼import numpy as npimport cv2import matplotlib.pyplot as pltcap = cv2.VideoCapture(0)_, first_frame = cap.read()def mouse_draw_rect(event, x, y, flags, params):    global point1, point2, drawing, first_frame, x1, x2, y1, y2    if event == cv2.EVENT_LBUTTONDOWN:        if drawing is False:            drawing = True            point1 = (x, y)            x1 = (x)            y1 = (y)        else:            drawing = False    elif event == cv2.EVENT_MOUSEMOVE:        if drawing is True:            point2 = (x, y)            x2 = (x)            y2 = (y)    elif event == cv2.EVENT_MBUTTONDOWN:        first_frame = framedrawing = Falsepoint1 = ()point2 = ()x1 = ()x2 = ()y1 = ()y2 = ()cv2.namedWindow('Original')cv2.setMouseCallback("Original", mouse_draw_rect)while True:    ret, frame = cap.read( )    if point1 and point2:        cv2.rectangle(frame, point1, point2, (0, 0, 0),5)    difference = cv2.absdiff(first_frame[y1:y2, x1:x2], frame[y1:y2, x1:x2])    difference = cv2.GaussianBlur(difference, (3, 3), 0)    _, difference = cv2.threshold(difference, 18, 255, cv2.THRESH_BINARY)    cv2.imshow('first frame (1)', first_frame)    cv2.imshow('Original', frame)    cv2.imshow('difference', difference)    key = cv2.waitKey(30) & 0xff    if key == 27:        breakcap.release()cv2.destroyAllWindows()
查看完整描述

2 回答

?
開滿天機

TA貢獻1786條經驗 獲得超13個贊

只需按您繪制的矩形區域進行裁剪。代替

difference = cv2.absdiff(first_frame, frame)

利用

difference = cv2.absdiff(first_frame[y1:y2, x1:x2], frame[y1:y2, x1:x2])


查看完整回答
反對 回復 2022-01-11
?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

主要問題在于 ROI 選擇事件以及當前如何調用它。當前的實現不是動態的,這意味著我們無法可視化我們正在嘗試選擇的 ROI。此外,我們甚至在選擇 ROI 之前就已經開始處理。

選擇 ROI 的正確方法是,一旦我們捕獲了第一幀,注冊鼠標單擊事件并無限期地可視化該幀imshow,waitKey(n)直到按下某個特定鍵?;蛘?,我們可以通過使用waitKey(0)(未測試)在沒有無限循環的情況下實現相同的效果。

在這個階段,我們應該能夠繪制出想要的 ROI 矩形。這里的關鍵因素是必須通過使用無限循環或waitKey(0). 僅僅注冊活動是不夠的。完成 ROI 選擇后,繼續執行其余代碼。

一些建議如下:

  • 盡可能避免使用全局變量

  • 為 ROI 選擇創建單獨的窗口,然后將其丟棄

  • 為每個單獨的任務創建單獨的函數

以下是演示正確使用鼠標單擊事件來選擇視頻處理的 ROI 的完整代碼:

import numpy as np

import cv2

import matplotlib.pyplot as plt



ORIGINAL_WINDOW_TITLE = 'Original'

FIRST_FRAME_WINDOW_TITLE = 'First Frame'

DIFFERENCE_WINDOW_TITLE = 'Difference'



canvas = None

drawing = False # true if mouse is pressed


#Retrieve first frame

def initialize_camera(cap):

    _, frame = cap.read()

    return frame



# mouse callback function

def mouse_draw_rect(event,x,y,flags, params):

    global drawing, canvas


    if drawing:

        canvas = params[0].copy()


    if event == cv2.EVENT_LBUTTONDOWN:

        drawing = True

        params.append((x,y)) #Save first point


    elif event == cv2.EVENT_MOUSEMOVE:

        if drawing:

            cv2.rectangle(canvas, params[1],(x,y),(0,255,0),2)


    elif event == cv2.EVENT_LBUTTONUP:

        drawing = False

        params.append((x,y)) #Save second point

        cv2.rectangle(canvas,params[1],params[2],(0,255,0),2)



def select_roi(frame):

    global canvas

    canvas = frame.copy()

    params = [frame]

    ROI_SELECTION_WINDOW = 'Select ROI'

    cv2.namedWindow(ROI_SELECTION_WINDOW)

    cv2.setMouseCallback(ROI_SELECTION_WINDOW, mouse_draw_rect, params)

    roi_selected = False

    while True:

        cv2.imshow(ROI_SELECTION_WINDOW, canvas)

        key = cv2.waitKey(10)


        #Press Enter to break the loop

        if key == 13:

            break;



    cv2.destroyWindow(ROI_SELECTION_WINDOW)

    roi_selected = (3 == len(params))


    if roi_selected:

        p1 = params[1]

        p2 = params[2]

        if (p1[0] == p2[0]) and (p1[1] == p2[1]):

            roi_selected = False


    #Use whole frame if ROI has not been selected

    if not roi_selected:

        print('ROI Not Selected. Using Full Frame')

        p1 = (0,0)

        p2 = (frame.shape[1] - 1, frame.shape[0] -1)



    return roi_selected, p1, p2





if __name__ == '__main__':


    cap = cv2.VideoCapture(0)


    #Grab first frame

    first_frame = initialize_camera(cap)


    #Select ROI for processing. Hit Enter after drawing the rectangle to finalize selection

    roi_selected, point1, point2 = select_roi(first_frame)    


    #Grab ROI of first frame

    first_frame_roi = first_frame[point1[1]:point2[1], point1[0]:point2[0], :]


    #An empty image of full size just for visualization of difference

    difference_image_canvas = np.zeros_like(first_frame)


    while cap.isOpened():


        ret, frame = cap.read()


        if ret:


            #ROI of current frame

            roi = frame[point1[1]:point2[1], point1[0]:point2[0], :]


            difference = cv2.absdiff(first_frame_roi, roi)

            difference = cv2.GaussianBlur(difference, (3, 3), 0)


            _, difference = cv2.threshold(difference, 18, 255, cv2.THRESH_BINARY)



            #Overlay computed difference image onto the whole image for visualization

            difference_image_canvas[point1[1]:point2[1], point1[0]:point2[0], :] = difference.copy()



            cv2.imshow(FIRST_FRAME_WINDOW_TITLE, first_frame)

            cv2.imshow(ORIGINAL_WINDOW_TITLE, frame)

            cv2.imshow(DIFFERENCE_WINDOW_TITLE, difference_image_canvas)



            key = cv2.waitKey(30) & 0xff

            if key == 27:

                break

        else:

            break


    cap.release()

    cv2.destroyAllWindows()

專業提示: 有時,在初始化相機時,根據房間內的環境光,它需要一些時間來預熱。您可以考慮跳過一些初始幀,讓相機從初始化階段穩定下來??梢酝ㄟ^initialize_camera在上述代碼中定義函數來完成,如下所示:


def initialize_camera(cap):

    for i in range(0,60): #Skip first 60 frames

        _, frame = cap.read()

    return frame


查看完整回答
反對 回復 2022-01-11
  • 2 回答
  • 0 關注
  • 180 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號