python - 在 python openCV 的网络摄像头视频上选择静态 ROI

标签 python opencv computer-vision snapshot roi

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

本页https://www.learnopencv.com/how-to-select-a-bounding-box-roi-in-opencv-cpp-python/有一个用于绘制 ROI 的代码,但仅限于图像,而不是实时视频。

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()

此代码使用空格键拍摄快照但不绘制 ROI 区域。 提前致谢!

最佳答案

enter image description here

这是一个从视频帧中选择静态 ROI 的小部件。本质上,这个想法是使用 cv2.setMouseCallback() 和事件处理程序来检测鼠标是否被单击或释放。对于此实现,您可以通过按住鼠标左键并拖动以选择所需的 ROI 来提取坐标。您可以使用鼠标右键重置 ROI。要使用该小部件,请按 c 暂停视频并开始裁剪。然后您可以自由选择投资返回率。选择 ROI 后,再次按 c 以裁剪所需的部分。要继续播放视频,请按 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 - 在 python openCV 的网络摄像头视频上选择静态 ROI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56467902/

相关文章:

Python 排除实例创建

python - 需要从curl迁移到pycurl的帮助

javascript - Python 中访问可能不存在的 k/v 对值的最佳实践?

matlab - 如何将此图像处理从 Matlab 转换为 OpenCV?

java - 什么是最好的开源纯java计算机视觉库?

python - 更好地替代添加前缀和后缀的巨大 "if x==2/if x==3/if x==4"链?

android - Imgproc.FindContours 不填充 List<MatOfPoint> 的轮廓 Opencv Android

python - 无法使用 OpenCV 和 Python 编写和保存视频文件

opencv - 可以将 OpenCV 与 Processing 和 Openframeworks 一起使用吗?

python - 在 PyTorch 中使用焦点损失处理不平衡数据集