def acquire(camera_index=0,
            keep_connection=False,
            rgb=False,
            device: VideoCapture = None):
    """
    Acquires an image from the computer's webcam and returns it.
    If the computer has multiple cameras, you can specify the index as parameter.

    Parameters
    ----------
    camera_index: int
        zero based camera inde
    keep_connection: bool
        if true, the connection will be kept open making the next acquisition faster
    rgb : bool
        return an RGB image if true, single channel grey scale otherwise
    device : VideoCapture
        an acquisition device, optional

    Returns
    -------
        2d (single channel) or 3d (RGB) numpy array / image
    """
    import cv2

    if device is None:
        if not hasattr(acquire, "video_source"):
            acquire.video_source = cv2.VideoCapture(camera_index)
        device = acquire.video_source

    _, picture = device.read()
    if picture is None:
        return

    if not keep_connection:
        device.release()
        del acquire.video_source

    if rgb:
        picture[:, :, 0], picture[:, :, 2] = picture[:, :, 2], picture[:, :, 0]
    else:
        from skimage.color import rgb2gray
        picture = rgb2gray(picture)

    return picture
Beispiel #2
0
def _extract_faces_tracked_from_video(video_folder: Path, bounding_boxes: Path,
                                      face_images: Path) -> bool:
    with open(str((bounding_boxes / video_folder.name).with_suffix(".json")),
              "r") as f:
        face_bb = json.load(f)

    face_images = face_images / video_folder.with_suffix("").name
    face_images.mkdir(exist_ok=True)

    cap = VideoCapture(str(video_folder))
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    tracked_bb, relative_bb = _face_bb_to_tracked_bb(face_bb,
                                                     image_size=(height,
                                                                 width),
                                                     scale=1)

    # extract all faces and save it
    frame_num = 0
    while cap.isOpened():
        success, image = cap.read()
        if not success:
            break

        face = tracked_bb[f"{frame_num:04d}"]
        _extract_face(image, face, face_images, frame_num)

        frame_num += 1
    cap.release()

    # save relative face positions as well
    with open(face_images / "relative_bb.json", "w") as f:
        json.dump(relative_bb, f)

    with open(face_images / "tracked_bb.json", "w") as f:
        json.dump(tracked_bb, f)

    return True
Beispiel #3
0
class Video:
    def __init__(self, path):
        self._path = path
        self._handler = VideoHandler(self)

    def __enter__(self):
        if exists(self._path):
            self.cap = VideoCapture(self._path)
            return self
        else:
            raise FileNotFoundError

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cap.release()

    def detect(self, element):

        elements = []

        for i in tqdm(range(self.length)):

            frame = self.frames.read(i)
            contours = element.detect(frame)

            if contours:
                elements.append((i, contours))

        return elements

    def _detect(self, element):

        elements = []

        key_frame = self.frames.read(0)
        contours = element.detect(key_frame)

        for i in tqdm(range(self.length)):

            frame = self.frames.read(i)
            mse = frame.metrics.mse(key_frame)

            if mse > 1500:
                key_frame = frame
                contours = element.detect(key_frame)

            if contours:
                elements.append((i, contours))

        return elements

    @property
    def framerate(self):
        return self.cap.get(5)

    @property
    def width(self):
        return int(self.cap.get(3))

    @property
    def height(self):
        return int(self.cap.get(4))

    @property
    def dimension(self):
        return self.width, self.height

    @property
    def codec(self):
        return unhexlify('%x' % int(self.cap.get(6)))[::-1].decode()

    @property
    def length(self):
        return int(self.cap.get(7))

    @property
    def frames(self):
        return self._handler.frames

    @staticmethod
    def create_image(image):
        return Image(image)

    def write(self, frames, path, codec=None, framerate=None, dimension=None):
        # raise NotImplementedError

        codec = codec if codec else self.codec
        framerate = framerate if framerate else self.framerate
        dimension = dimension if dimension else self.dimension

        with Writer(path, codec, framerate, dimension) as vw:
            vw.write(frames)
Beispiel #4
0
class CamShow(QMainWindow, Ui_Camera):
    def __init__(self, parent=None):  #ui部分
        super(CamShow, self).__init__(parent)
        self.setupUi(self)
        self.Mix()  #条和Box的值匹配
        self.Btn()  #按钮初始化
        self.Var()  #变量初始化
        self.Func()  #控件功能集合
        self.Timer = QTimer()  #计时器
        self.Timer.timeout.connect(self.TimerOutFun)  #计时器

    def Mix(self):  #条和Box的值匹配    #ui部分
        self.RSld.valueChanged.connect(self.RBx.setValue)
        self.RBx.valueChanged.connect(self.RSld.setValue)
        self.GSld.valueChanged.connect(self.GBx.setValue)
        self.GBx.valueChanged.connect(self.GSld.setValue)
        self.BSld.valueChanged.connect(self.BBx.setValue)
        self.BBx.valueChanged.connect(self.BSld.setValue)

        self.BGSld.valueChanged.connect(self.BGBx.setValue)
        self.BGBx.valueChanged.connect(self.BGSld.setValue)
        self.ZYSld.valueChanged.connect(self.ZYBx.setValue)
        self.ZYBx.valueChanged.connect(self.ZYSld.setValue)
        self.LDSld.valueChanged.connect(self.LDBx.setValue)
        self.LDBx.valueChanged.connect(self.LDSld.setValue)
        self.DBSld.valueChanged.connect(self.DBBx.setValue)
        self.DBBx.valueChanged.connect(self.DBSld.setValue)

    def Btn(self):  #按钮初始化 #ui部分
        self.PrepCamera()
        self.Stop.setEnabled(False)
        self.Record.setEnabled(False)
        self.Die.setEnabled(False)
        self.RSld.setEnabled(False)
        self.RBx.setEnabled(False)
        self.GSld.setEnabled(False)
        self.GBx.setEnabled(False)
        self.BSld.setEnabled(False)
        self.BBx.setEnabled(False)
        self.BGSld.setEnabled(False)
        self.BGBx.setEnabled(False)
        self.ZYSld.setEnabled(False)
        self.ZYBx.setEnabled(False)
        self.LDSld.setEnabled(False)
        self.LDBx.setEnabled(False)
        self.DBSld.setEnabled(False)
        self.DBBx.setEnabled(False)
        self.quick.setEnabled(False)
        self.Local.setEnabled(False)
        self.Pic.setEnabled(False)

    def PrepCamera(self):  #准备一下照相机   #功能部分
        for ID in range(5000):
            self.camera = VideoCapture(ID)
            success, frame = self.camera.read()
            if success:
                break
        if not success:
            msg = QMessageBox.warning(self,
                                      u"Warning",
                                      u"请检测相机与电脑是否连接正确",
                                      buttons=QMessageBox.Ok,
                                      defaultButton=QMessageBox.Ok)
        return success

    def PrepVideo(self):  #准备一下检测视频
        self.camera = VideoCapture(self.RecordPath)
        success, frame = self.camera.read()
        if success:
            pass
        if not success:
            msg = QMessageBox.warning(self,
                                      u"Warning",
                                      u"文件不可读取,请重新选择路径",
                                      buttons=QMessageBox.Ok,
                                      defaultButton=QMessageBox.Ok)
        return success

    def PrepPicture(self):
        success = imread(self.RecordPath)
        if type(success) == type(None):
            success = False
        else:
            success = True
        if success:
            pass
        if not success:
            msg = QMessageBox.warning(self,
                                      u"Warning",
                                      u"图片不可读取,请重新选择路径",
                                      buttons=QMessageBox.Ok,
                                      defaultButton=QMessageBox.Ok)
        return success

    def Var(self):  #参数初始化 #ui部分
        self.RecordFlag = 0
        self.RecordPath = 'D:/'
        self.LJTx.setText(self.RecordPath)
        self.Image_num = 0
        self.R = 1
        self.G = 1
        self.B = 1

        self.BGSld.setValue(self.camera.get(15))
        self.SetBG()
        self.ZYSld.setValue(self.camera.get(14))
        self.SetZY()
        self.LDSld.setValue(self.camera.get(10))
        self.SetLD()
        self.DBSld.setValue(self.camera.get(11))
        self.SetDB()
        self.Info.clear()

        self.temp = 0
        self.count = 0

    def Func(self):  #控件功能合集 #ui部分
        self.LJBut.clicked.connect(self.SetFilePath)
        self.Start.clicked.connect(self.StartCamera)
        self.Stop.clicked.connect(self.StopCamera)
        self.Record.clicked.connect(self.RecordCamera)
        self.Exit.clicked.connect(self.close)
        self.Die.stateChanged.connect(self.setDie)
        self.BGSld.valueChanged.connect(self.SetBG)
        self.ZYSld.valueChanged.connect(self.SetZY)
        self.LDSld.valueChanged.connect(self.SetLD)
        self.DBSld.valueChanged.connect(self.SetDB)
        self.RSld.valueChanged.connect(self.SetR)
        self.GSld.valueChanged.connect(self.SetG)
        self.BSld.valueChanged.connect(self.SetB)
        self.Local.stateChanged.connect(self.LocalFun)
        self.Pic.stateChanged.connect(self.PicFun)

    def StartCamera(self):  #界面按钮准备工作   #ui部分
        self.Local.setEnabled(True)
        self.Start.setEnabled(False)
        self.Stop.setEnabled(True)
        self.Record.setEnabled(True)
        self.Die.setEnabled(True)
        if self.Die.isChecked() == 0:
            self.RSld.setEnabled(True)
            self.RBx.setEnabled(True)
            self.GSld.setEnabled(True)
            self.GBx.setEnabled(True)
            self.BSld.setEnabled(True)
            self.BBx.setEnabled(True)
        self.BGSld.setEnabled(True)
        self.BGBx.setEnabled(True)
        self.ZYSld.setEnabled(True)
        self.ZYBx.setEnabled(True)
        self.LDSld.setEnabled(True)
        self.LDBx.setEnabled(True)
        self.DBSld.setEnabled(True)
        self.DBBx.setEnabled(True)
        self.quick.setEnabled(True)
        self.Pic.setEnabled(True)
        self.Record.setText('录像')

        self.Timer.start(1)
        self.timelb = time.time()

    def StopCamera(self):  #暂停界面   #ui部分
        if self.Stop.text() == '暂停':
            self.Stop.setText('继续')
            self.Record.setText('保存')
            self.Timer.stop()
            self.camera.release()
        elif self.Stop.text() == '继续':
            if self.Local.isChecked():
                success = self.PrepVideo()
            elif self.Pic.isChecked():
                success = self.PrepPicture()
            else:
                success = self.PrepCamera()
            if not success:
                pass
            else:
                self.Stop.setText('暂停')
                self.Record.setText('录像')
                self.Timer.start(1)

    def TimerOutFun(
            self):  #读取图像    #功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分
        '''单帧图片功能'''
        time_interval = self.quick.value()
        zero = time.time()
        sec = 1  #
        if self.Pic.isChecked():
            img = imread(self.RecordPath)
            success = True
        else:
            success, img = self.camera.read()  #读取图像!!!img为图像,如果要拿去加框框,可以在这里截胡
        if success:  #如果成功读取
            self.Image = self.ColorAdjust(img)  #调整图像参数(RGB或者遗像)

            if self.Image_num % time_interval == 0:
                result = inference_detector(model, self.Image)
                self.temp = result
                self.count = show_result(self.Image,
                                         result,
                                         CLASSES,
                                         show=False,
                                         out_file="~/0.jpg")
                self.Image = imread("~/0.jpg")
                #img1_array.append(img)
                #imwrite("%d.jpg" % count, image)
                # print(count)
            elif self.Image_num != 1:
                result = self.temp
                self.count = show_result(self.Image,
                                         result,
                                         CLASSES,
                                         show=False,
                                         out_file="~/0.jpg")
                self.Image = imread("~/0.jpg")

            if self.count != 0 and self.Image_num % sec == 0:
                #if 1==1 :
                Text1 = '有%d名员工未佩戴安全帽' % self.count
                self.Info_2.setHtml(
                    QCoreApplication.translate(
                        "Camera",
                        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                        "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                        "p, li { white-space: pre-wrap; }\n"
                        "</style></head><body style=\" font-family:\'微软雅黑\'; font-size:14pt; font-weight:600; font-style:normal;\">\n"
                        "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
                        "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><img src=\"./warning.jpg\" /></p>\n"
                        "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-weight:72; color:#ff0000;\">%s</span></p></body></html>"
                    ) % (Text1))
            else:
                Text1 = '正常'
                self.Info_2.setHtml(
                    QCoreApplication.translate(
                        "Camera",
                        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                        "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                        "p, li { white-space: pre-wrap; }\n"
                        "</style></head><body style=\" font-family:\'微软雅黑\'; font-size:14pt; font-weight:600; font-style:normal;\">\n"
                        "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
                        "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
                        "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:18pt;\">%s</span></p></body></html>"
                    ) % Text1)

            self.DispImg()  #显示
            finish = time.time()
            self.Image_num += 1  #计算帧数
            if self.RecordFlag:  #开始录像
                self.video_writer.write(self.Image)  #录像存入
            if self.Image_num % 10 == 9:  #计算帧率
                frame_rate = 10 / (time.time() - self.timelb)
                Text1 = '延迟:' + str(
                    round(1000 * (finish - zero) / time_interval, 1)) + '  MS'
                Text2 = '帧率:' + str(round(frame_rate, 1)) + ' FPS'
                self.Info.setHtml(
                    QCoreApplication.translate(
                        "Camera",
                        "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
                        "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
                        "p, li { white-space: pre-wrap; }\n"
                        "</style></head><body style=\" font-family:\'微软雅黑\'; font-size:12pt; font-weight:400; font-style:normal;\">\n"
                        "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
                        "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
                        "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:14pt;\">%s</span></p>\n"
                        "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:14pt;\">%s</span></p></body></html>"
                    ) % (Text1, Text2))
                self.timelb = time.time()
        elif self.Local.isChecked:  #无法读取图像
            msg = QMessageBox.warning(self,
                                      u"Warning",
                                      u"视频已播放并检测完毕",
                                      buttons=QMessageBox.Ok,
                                      defaultButton=QMessageBox.Ok)
            self.StopCamera()
        else:
            msg = QMessageBox.warning(self,
                                      u"Warning",
                                      u"请检测相机是否被其他应用占用",
                                      buttons=QMessageBox.Ok,
                                      defaultButton=QMessageBox.Ok)
            self.StopCamera()

    def DispImg(self):  #功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分#功能部分

        #颜色调整
        img = cvtColor(self.Image, COLOR_BGR2RGB)
        #显示图像
        a = QPixmap(array2qimage(img))
        self.cam.setPixmap(a)
        self.cam.show()

    def setDie(self):  #ui部分     灰度模式按钮
        if self.Die.isChecked():
            self.RSld.setEnabled(False)
            self.RBx.setEnabled(False)
            self.GSld.setEnabled(False)
            self.GBx.setEnabled(False)
            self.BSld.setEnabled(False)
            self.BBx.setEnabled(False)
        else:
            self.RSld.setEnabled(True)
            self.RBx.setEnabled(True)
            self.GSld.setEnabled(True)
            self.GBx.setEnabled(True)
            self.BSld.setEnabled(True)
            self.BBx.setEnabled(True)

    def SetR(self):  #ui部分 R
        R = self.RSld.value()
        self.R = R / 255

    def SetG(self):  #ui部分  G
        G = self.GSld.value()
        self.G = G / 255

    def SetB(self):  #ui部分 B
        B = self.BSld.value()
        self.B = B / 255

    def ColorAdjust(self, img):  #调整颜色
        try:
            B = img[:, :, 0]
            G = img[:, :, 1]
            R = img[:, :, 2]
            B = B * self.B
            G = G * self.G
            R = R * self.R
            img1 = img
            img1[:, :, 0] = B
            img1[:, :, 1] = G
            img1[:, :, 2] = R
            if self.Die.isChecked():
                img1 = cvtColor(img1, COLOR_BGR2GRAY)
            return img1
        except Exception as e:
            self.label.setText(str(e))

    def SetBG(self):  #调整曝光
        try:
            exposure_time_toset = self.BGSld.value()
            self.camera.set(22, exposure_time_toset)
            self.camera.set(10, exposure_time_toset)
        except Exception as e:
            self.label.setText(e)

    def SetZY(self):  #调整增益
        gain_toset = self.ZYSld.value()
        try:
            self.camera.set(22, gain_toset)
        except Exception as e:
            self.label.setText(e)

    def SetLD(self):  #调整亮度
        brightness_toset = self.LDSld.value()
        try:
            self.camera.set(10, brightness_toset)
        except Exception as e:
            self.label.setText(e)

    def SetDB(self):  #调整对比度
        contrast_toset = self.DBSld.value()
        try:
            self.camera.set(11, contrast_toset)
        except Exception as e:
            self.label.setText(e)

    def SetFilePath(self):  #选择保存路径
        if self.Local.isChecked() or self.Pic.isChecked():
            dirname = QFileDialog.getOpenFileName(self, "浏览", '.')[0]
        else:
            dirname = QFileDialog.getExistingDirectory(self, "浏览", '.')
        if dirname:
            self.LJTx.setText(dirname)
        if self.Local.isChecked() or self.Pic.isChecked():
            self.RecordPath = dirname
        else:
            self.RecordPath = dirname + '/'

    def LocalFun(self):
        if self.Local.isChecked():
            self.Pic.setEnabled(False)
            self.BGSld.setEnabled(False)
            self.BGBx.setEnabled(False)
            self.ZYSld.setEnabled(False)
            self.ZYBx.setEnabled(False)
            self.LDSld.setEnabled(False)
            self.LDBx.setEnabled(False)
            self.DBSld.setEnabled(False)
            self.DBBx.setEnabled(False)
            self.LJ.setText('检测路径')
            self.StopCamera()
            msg = QMessageBox.information(self,
                                          u"Tip",
                                          u"请选择文件路径,单击继续以开始检测",
                                          buttons=QMessageBox.Ok,
                                          defaultButton=QMessageBox.Ok)
        else:
            self.LJ.setText('保存路径')
            self.Pic.setEnabled(True)
            self.BGSld.setEnabled(True)
            self.BGBx.setEnabled(True)
            self.ZYSld.setEnabled(True)
            self.ZYBx.setEnabled(True)
            self.LDSld.setEnabled(True)
            self.LDBx.setEnabled(True)
            self.DBSld.setEnabled(True)
            self.DBBx.setEnabled(True)
            self.StopCamera()

    def PicFun(self):
        if self.Pic.isChecked():
            self.Local.setEnabled(False)
            self.BGSld.setEnabled(False)
            self.BGBx.setEnabled(False)
            self.ZYSld.setEnabled(False)
            self.ZYBx.setEnabled(False)
            self.LDSld.setEnabled(False)
            self.LDBx.setEnabled(False)
            self.DBSld.setEnabled(False)
            self.DBBx.setEnabled(False)
            self.LJ.setText('检测路径')
            self.StopCamera()
            msg = QMessageBox.information(self,
                                          u"Tip",
                                          u"请选择图片路径,单击继续以开始检测",
                                          buttons=QMessageBox.Ok,
                                          defaultButton=QMessageBox.Ok)
        else:
            self.LJ.setText('保存路径')
            self.Local.setEnabled(True)
            self.BGSld.setEnabled(True)
            self.BGBx.setEnabled(True)
            self.ZYSld.setEnabled(True)
            self.ZYBx.setEnabled(True)
            self.LDSld.setEnabled(True)
            self.LDBx.setEnabled(True)
            self.DBSld.setEnabled(True)
            self.DBBx.setEnabled(True)
            self.StopCamera()

    def RecordCamera(self):  #录像功能
        tag = self.Record.text()
        if tag == '保存':
            try:
                image_name = self.RecordPath + 'image' + time.strftime(
                    '%Y%m%d%H%M%S', time.localtime(time.time())) + '.jpg'
                self.label.setText(image_name)
                imwrite(image_name, self.Image)
            except Exception as e:
                self.label.setText(e)
        elif tag == '录像':
            self.Record.setText('停止')
            video_name = self.RecordPath + 'video' + time.strftime(
                '%Y%m%d%H%M%S', time.localtime(time.time())) + '.avi'
            fps = 24 / self.quick.value()
            size = (self.Image.shape[1], self.Image.shape[0])
            fourcc = VideoWriter_fourcc('M', 'J', 'P', 'G')
            self.video_writer = VideoWriter(video_name, fourcc,
                                            self.camera.get(5), size)
            self.RecordFlag = 1
            self.label.setAlignment(Qt.AlignCenter)
            self.label.setText('录像中...')
            self.Stop.setEnabled(False)
            self.Exit.setEnabled(False)
        elif tag == '停止':
            self.Record.setText('录像')
            self.video_writer.release()
            self.RecordFlag = 0
            self.label.setText('录像已保存')
            self.Stop.setEnabled(True)
            self.Exit.setEnabled(True)

    def closeEvent(self, event):  #关闭事件
        ok = QPushButton()
        cacel = QPushButton()

        msg = QMessageBox(QMessageBox.Warning, u"关闭", u"是否关闭!")

        msg.addButton(ok, QMessageBox.ActionRole)
        msg.addButton(cacel, QMessageBox.RejectRole)
        ok.setText(u'确定')
        cacel.setText(u'取消')
        # msg.setDetailedText('sdfsdff')
        if msg.exec_() == QMessageBox.RejectRole:
            event.ignore()
        else:
            #             self.socket_client.send_command(self.socket_client.current_user_command)
            if self.camera.isOpened():
                self.camera.release()
            if self.Timer.isActive():
                self.Timer.stop()
            event.accept()
Beispiel #5
0
class Player:
    writer: VideoWriter
    tracker: Tracker

    def __init__(self, input_filename: str, output_filename: str, codec: str,
                 window_name: str) -> None:

        # OPTIONS
        self.input_filename = input_filename
        self.output_filename = output_filename
        self.window_name = window_name

        self.state = PlayerState()
        self.hud = HUD(self.state)

        self.writer = None
        if self.output_filename:
            codec = VideoWriter_fourcc(*(codec or 'XVID'))
            self.writer = VideoWriter(output_filename, codec, 30, (1280, 720))

        self.capture = VideoCapture(input_filename)
        if not self.capture.isOpened():
            raise Exception("The capture could not be opened")

        ok, self.frame = self.capture.read()
        if not ok:
            raise Exception("The capture could not be read")

        self.state.target_fps = self.state.original_fps = self.capture.get(
            CAP_PROP_FPS)

        imshow(self.window_name, self.frame)

        self.selector = Selector(self.window_name)
        self.selector.on_selecting = self.on_selecting
        self.selector.on_selected = self.on_selected

        self.label_uppercase = False

        self.meter = TickMeter()

    def update(self):
        if not self.state.paused:
            ok, self.frame = self.capture.read()
            if not ok:
                return self._close()
            for tracking_object in self.state.tracking_objects:
                tracking_object.update(self.frame)
            if self.writer:
                self.writer.write(self.hud.render_output(self.frame))

        imshow(self.window_name, self.hud.render(self.frame))

        self.meter.stop()
        self.state.fps = 1 / (self.meter.getTimeSec() or 1)
        wait_ms = max(
            1, 1000.0 / self.state.target_fps - self.meter.getTimeMilli())
        self.meter.reset()
        self.meter.start()

        key = waitKey(int(wait_ms)) & 0xff
        if key == 255:
            pass
        elif len(
                self.state.tracking_objects
        ) > 0 and self.state.tracking_objects[-1].label_typing_in_progress:
            print(key)
            if key == 27:  # ESC
                self.state.tracking_objects[-1].label = ""
                self.state.tracking_objects[
                    -1].label_typing_in_progress = False
            elif key == 8:
                if len(self.state.tracking_objects[-1].label) > 0:
                    self.state.tracking_objects[
                        -1].label = self.state.tracking_objects[-1].label[:-1]
            elif key == 13:  # ENTER
                self.state.tracking_objects[
                    -1].label_typing_in_progress = False
            elif key == 229:  # CAPS LOCK
                self.label_uppercase = not self.label_uppercase
            elif key in range(32, 127):
                self.state.tracking_objects[-1].label += chr(
                    key) if not self.label_uppercase else chr(key).upper()
        elif key == 27:  # ESC
            return self._close()
        elif key == 32:  # SPACE
            self.state.paused = not self.state.paused
        elif key == 81:  # LARROW
            self.state.target_fps = self.state.target_fps / 2
        elif key == 83:  # RARROW
            self.state.target_fps = self.state.target_fps * 2

    def on_selecting(self, rect):
        self.state.selection = rect

    def on_selected(self, rect):
        if rect[2] != 0 or rect[3] != 0:
            self.state.tracking_objects += [TrackingObject(self.frame, rect)]
        self.state.selection = None

    def _close(self):
        self.capture.release()
        if self.writer:
            self.writer.release()
        return -1
Beispiel #6
0
class Streamer(Player):
    def __init__(self, grabber, source=0):
        Player.__init__(self)
        self._flip_state = False
        self._source = source
        self._video_cap = VideoCapture(source)
        self._frame_counter = 0
        self.grab = grabber
        self._thread = None
        self._paused = False

    def set_grabber(self, grabber):
        self.grab = grabber

    def get_fps(self):
        return self._video_cap.get(CAP_PROP_FPS)

    def pause_toggle(self):
        self._paused = not self._paused

    def set_source(self, source):
        self._video_cap.release()
        self._frame_counter = 0
        self._source = source
        self._video_cap.open(source)

    def get_source(self):
        return self._source

    def get_shape(self):
        if self._video_cap.isOpened():
            w = int(self._video_cap.get(WIDTH_PROPERTY))
            h = int(self._video_cap.get(HEIGHT_PROPERTY))
            shape = (w, h)
        else:
            self._video_cap.open(self._source)
            w = int(self._video_cap.get(WIDTH_PROPERTY))
            h = int(self._video_cap.get(HEIGHT_PROPERTY))
            shape = (w, h)
            self._video_cap.release()
        return shape

    def flip_toggle(self):
        self._flip_state = not self._flip_state

    def get_property(self, PROP):
        return self._video_cap.get(PROP)

    def set_property(self, PROP, value):
        self._video_cap.set(PROP, value)

    def run(self):
        from time import sleep, clock
        delay = 1. / self._speed if self._speed != 0 \
            else 1. / self.get_fps() if self._source != 0 else None
        total_frames = self._video_cap.get(CAP_PROP_FRAME_COUNT)
        while self._signal.value():
            if not self._paused:
                time_start = clock()
                if self._source != 0:
                    if self._frame_counter == total_frames:
                        self.set_source(self._source)
                _, frame = self._video_cap.read()
                if frame is None:
                    continue
                self._frame_counter += 1
                self.grab(flip(frame, 1) if self._flip_state else frame)
                if delay is not None:
                    sleep(max(delay + time_start - clock(), 0))

    def __play__(self):
        self._video_cap.open(self._source)
        self._thread = FastThread(func=self.run, parent=self)
        self._thread.start()

    def __stop__(self):
        self._video_cap.release()

    def __close__(self):
        self._signal.set(False)
        self._video_cap.release()
        if self._thread is not None:
            self._thread.exit(0)