在python openCV的网络摄像头视频上选择静态ROI [英] Select a static ROI on webcam video on python openCV

查看:80
本文介绍了在python openCV的网络摄像头视频上选择静态ROI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从网络摄像头的实时视频中选择一个ROI(感兴趣区域)或工作区域,并仅拍摄此工作区域或ROI的快照,但我找不到执行该操作的方法.

在此页面中

这是一个小部件,用于从视频帧中选择静态ROI.本质上,这个想法是使用 cv2.setMouseCallback()和事件处理程序来检测是否单击或释放了鼠标.对于此实现,您可以通过按住鼠标左键并拖动以选择所需的ROI来提取坐标.您可以使用鼠标右键重置ROI.要使用该小部件,请按 c 暂停视频并开始裁剪.然后,您可以自由选择ROI.选择了ROI后,再次按 c 即可裁剪所需的部分.要恢复视频,请按 r .

  import cv2class staticROI(object):def __init __():self.capture = cv2.VideoCapture('fedex.mp4')#边界框参考点和布尔值(如果要提取坐标)self.image_coordinates = []self.extract =错误self.selected_ROI = Falseself.update()def更新(自己):而True:如果self.capture.isOpened():#阅读框架(self.status,self.frame)= self.capture.read()cv2.imshow('image',self.frame)键= cv2.waitKey(2)#裁剪图像如果键== ord('c'):self.clone = self.frame.copy()cv2.namedWindow('image')cv2.setMouseCallback('image',self.extract_coordinates)而True:键= cv2.waitKey(2)cv2.imshow('image',self.clone)#裁剪并显示裁剪的图像如果键== ord('c'):self.crop_ROI()self.show_cropped_ROI()#恢复视频如果键== ord('r'):休息#用键盘'q'关闭程序如果键== ord('q'):cv2.destroyAllWindows()出口(1)别的:经过def extract_coordinates(自我,事件,x,y,标志,参数):#记录鼠标左键单击的开始(x,y)坐标如果事件== cv2.EVENT_LBUTTONDOWN:self.image_coordinates = [(x,y)]self.extract =真#记录鼠标左键释放的结尾(x,y)坐标elif事件== cv2.EVENT_LBUTTONUP:self.image_coordinates.append((x,y))self.extract =错误self.selected_ROI =真#在ROI周围绘制矩形cv2.rectangle(self.clone,self.image_coordinates [0],self.image_coordinates [1],(0,255,0),2)#单击鼠标右键清除绘图框elif事件== cv2.EVENT_RBUTTONDOWN:self.clone = self.frame.copy()self.selected_ROI = Falsedef crop_ROI():如果self.selected_ROI:self.cropped_image = self.frame.copy()x1 = self.image_coordinates [0] [0]y1 = self.image_coordinates [0] [1]x2 = self.image_coordinates [1] [0]y2 = self.image_coordinates [1] [1]self.cropped_image = self.cropped_image [y1:y2,x1:x2]print('裁剪的图像:{} {}'.format(self.image_coordinates [0],self.image_coordinates [1]))别的:打印(选择要在裁剪前裁剪的ROI")def show_cropped_ROI():cv2.imshow('裁剪图像',self.cropped_image)如果__name__ =='__main__':static_ROI = staticROI() 

I need to selec a ROI (region of interest), or work area, on a live video from my webcam and take a snapshot of ONLY this work area or ROI, but I can't found how to do this.

In this page https://www.learnopencv.com/how-to-select-a-bounding-box-roi-in-opencv-cpp-python/ have a code for draw a ROI but only with images, not a live video.

import cv2
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
cv2.namedWindow("test")

img_counter = 0

while True:
    ret, frame = cam.read()
    cv2.imshow("test", frame)
    if not ret:
        break
    k = cv2.waitKey(1)

    if k % 256 == 27:
        # ESC pressed
        print("Escape hit, closing...")
        break
    elif k % 256 == 32:
        # SPACE pressed
        img_name = "opencv_frame_{}.png".format(img_counter)
        cv2.imwrite(img_name, frame)
        print("{} written!".format(img_name))
        img_counter += 1

cam.release()

cv2.destroyAllWindows()

This code take a snapshot with space key but not draw a ROI area. Thanks in advance!

解决方案

Here's a widget to select static ROIs from a video frame. Essentially the idea is to use cv2.setMouseCallback() and event handlers to detect if the mouse has been clicked or released. For this implementation, you can extract coordinates by holding down the left mouse button and dragging to select the desired ROI. You can reset the ROI using the right mouse button. To use the widget, press c to pause the video and start cropping. Then you are free to select the ROI. Once you have selected your ROI, press c again to crop the desired section. To resume the video, press r.

import cv2

class staticROI(object):
    def __init__(self):
        self.capture = cv2.VideoCapture('fedex.mp4')

        # Bounding box reference points and boolean if we are extracting coordinates
        self.image_coordinates = []
        self.extract = False
        self.selected_ROI = False

        self.update()

    def update(self):
        while True:
            if self.capture.isOpened():
                # Read frame
                (self.status, self.frame) = self.capture.read()
                cv2.imshow('image', self.frame)
                key = cv2.waitKey(2)

                # Crop image
                if key == ord('c'):
                    self.clone = self.frame.copy()
                    cv2.namedWindow('image')
                    cv2.setMouseCallback('image', self.extract_coordinates)
                    while True:
                        key = cv2.waitKey(2)
                        cv2.imshow('image', self.clone)

                        # Crop and display cropped image
                        if key == ord('c'):
                            self.crop_ROI()
                            self.show_cropped_ROI()

                        # Resume video
                        if key == ord('r'):
                            break
                # Close program with keyboard 'q'
                if key == ord('q'):
                    cv2.destroyAllWindows()
                    exit(1)
            else:
                pass

    def extract_coordinates(self, event, x, y, flags, parameters):
        # Record starting (x,y) coordinates on left mouse button click
        if event == cv2.EVENT_LBUTTONDOWN:
            self.image_coordinates = [(x,y)]
            self.extract = True

        # Record ending (x,y) coordintes on left mouse bottom release
        elif event == cv2.EVENT_LBUTTONUP:
            self.image_coordinates.append((x,y))
            self.extract = False

            self.selected_ROI = True

            # Draw rectangle around ROI
            cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)

        # Clear drawing boxes on right mouse button click
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.clone = self.frame.copy()
            self.selected_ROI = False

    def crop_ROI(self):
        if self.selected_ROI:
            self.cropped_image = self.frame.copy()

            x1 = self.image_coordinates[0][0]
            y1 = self.image_coordinates[0][1]
            x2 = self.image_coordinates[1][0]
            y2 = self.image_coordinates[1][1]

            self.cropped_image = self.cropped_image[y1:y2, x1:x2]

            print('Cropped image: {} {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
        else:
            print('Select ROI to crop before cropping')

    def show_cropped_ROI(self):
        cv2.imshow('cropped image', self.cropped_image)

if __name__ == '__main__':
    static_ROI = staticROI()

这篇关于在python openCV的网络摄像头视频上选择静态ROI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆