|
| 1 | +import cv2 |
| 2 | +import numpy as np |
| 3 | +import sys |
| 4 | +from PyQt5 import QtWidgets, QtCore, QtGui |
| 5 | + |
| 6 | + |
| 7 | +class QtCapture(QtWidgets.QWidget): |
| 8 | + def __init__(self, *args): |
| 9 | + super(QtWidgets.QWidget, self).__init__() |
| 10 | + |
| 11 | + self.fps = 24 |
| 12 | + #self.cap = cv2.VideoCapture(*args) |
| 13 | + self.read_frames(sys.argv[1]) |
| 14 | + self.frame_nr = 0 |
| 15 | + #print ("cap", self.cap) |
| 16 | + self.video_frame = QtWidgets.QLabel() |
| 17 | + lay = QtWidgets.QVBoxLayout() |
| 18 | + #lay.setContentsMargins(0, 0, 0, 0) |
| 19 | + lay.addWidget(self.video_frame) |
| 20 | + self.setLayout(lay) |
| 21 | + print ("INIT OK") |
| 22 | + |
| 23 | + def read_frames(self, filename): |
| 24 | + cap = cv2.VideoCapture(filename) |
| 25 | + self.rekkari_cascade = cv2.CascadeClassifier('./rekkari.xml') |
| 26 | + |
| 27 | + n_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) |
| 28 | + self.frames = [] |
| 29 | + print ("starting reading: filename", filename) |
| 30 | + while not cap.isOpened(): |
| 31 | + cap = cv2.VideoCapture(filename) |
| 32 | + cv2.waitKey(1000) |
| 33 | + print("Wait for the header") |
| 34 | + |
| 35 | + |
| 36 | + pos_frame = cap.get(cv2.CAP_PROP_POS_FRAMES) |
| 37 | + while True: |
| 38 | + flag, frame = cap.read() |
| 39 | + if flag: |
| 40 | + # The frame is ready and already captured |
| 41 | + #cv2.imshow('video', frame) |
| 42 | + # Convert to RGB for QImage. |
| 43 | + cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, frame) |
| 44 | + frame = cv2.transpose(frame) |
| 45 | + gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) |
| 46 | + rekkaris = self.rekkari_cascade.detectMultiScale(gray, 1.1, 5) |
| 47 | + for (x,y,w,h) in rekkaris: |
| 48 | + cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),5) |
| 49 | + self.frames.append(frame) |
| 50 | + pos_frame = cap.get(cv2.CAP_PROP_POS_FRAMES) |
| 51 | + print (str(pos_frame)+" frames") |
| 52 | + else: |
| 53 | + # The next frame is not ready, so we try to read it again |
| 54 | + cap.set(cv2.CAP_PROP_POS_FRAMES, pos_frame-1) |
| 55 | + print("frame is not ready") |
| 56 | + # It is better to wait for a while for the next frame to be ready |
| 57 | + cv2.waitKey(1000) |
| 58 | + |
| 59 | + if cv2.waitKey(10) == 27: |
| 60 | + break |
| 61 | + if cap.get(cv2.CAP_PROP_POS_FRAMES) == cap.get(cv2.CAP_PROP_FRAME_COUNT): |
| 62 | + # If the number of captured frames is equal to the total number of frames, |
| 63 | + # we stop |
| 64 | + break |
| 65 | + if pos_frame > 15: |
| 66 | + break |
| 67 | + |
| 68 | + |
| 69 | + |
| 70 | + cap.release() |
| 71 | + print("finished reading") |
| 72 | + |
| 73 | + |
| 74 | + def setFPS(self, fps): |
| 75 | + self.fps = fps |
| 76 | + |
| 77 | + def nextFrameSlot(self): |
| 78 | + import sys |
| 79 | + |
| 80 | + print("frameinfo", self.frame_nr, len(self.frames)) |
| 81 | + #sys.exit() |
| 82 | + if self.frame_nr < (len(self.frames) -1): |
| 83 | + self.frame_nr = self.frame_nr + 1 |
| 84 | + else: |
| 85 | + self.frame_nr = 0 |
| 86 | + print("frameinfo2", self.frame_nr, len(self.frames)) |
| 87 | + frame = self.frames[self.frame_nr] |
| 88 | + |
| 89 | + # OpenCV yields frames in BGR format |
| 90 | + #frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2RGB) |
| 91 | + #cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, frame) |
| 92 | + #img = frame["img"] |
| 93 | + if frame is not None: |
| 94 | + print('FRAME', frame) |
| 95 | + #height, width, bytesPerComponent = frame.shape |
| 96 | + #bytesPerLine = bytesPerComponent * width |
| 97 | + #img = QtGui.QImage(self.cv_img.data, width, height, bytesPerLine, QtGui.QImage.Format_RGB888) |
| 98 | + img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888) |
| 99 | + pix = QtGui.QPixmap.fromImage(img) |
| 100 | + self.video_frame.setPixmap(pix) |
| 101 | + |
| 102 | + |
| 103 | + def start(self): |
| 104 | + self.timer = QtCore.QTimer() |
| 105 | + self.timer.timeout.connect(self.nextFrameSlot) |
| 106 | + self.timer.start(1000./self.fps) |
| 107 | + |
| 108 | + def stop(self): |
| 109 | + self.timer.stop() |
| 110 | + |
| 111 | + def deleteLater(self): |
| 112 | + self.cap.release() |
| 113 | + super(QtWidgets.QWidget, self).deleteLater() |
| 114 | + |
| 115 | +class ControlWindow(QtWidgets.QWidget): |
| 116 | + def __init__(self): |
| 117 | + QtWidgets.QWidget.__init__(self) |
| 118 | + self.capture = None |
| 119 | + |
| 120 | + self.start_button = QtWidgets.QPushButton('Start') |
| 121 | + self.start_button.clicked.connect(self.startCapture) |
| 122 | + self.quit_button = QtWidgets.QPushButton('End') |
| 123 | + self.quit_button.clicked.connect(self.endCapture) |
| 124 | + self.end_button = QtWidgets.QPushButton('Stop') |
| 125 | + |
| 126 | + vbox = QtWidgets.QVBoxLayout(self) |
| 127 | + vbox.addWidget(self.start_button) |
| 128 | + vbox.addWidget(self.end_button) |
| 129 | + vbox.addWidget(self.quit_button) |
| 130 | + self.setLayout(vbox) |
| 131 | + self.setWindowTitle('Control Panel') |
| 132 | + self.setGeometry(100,100,200,200) |
| 133 | + self.show() |
| 134 | + |
| 135 | + def startCapture(self): |
| 136 | + if not self.capture: |
| 137 | + self.capture = QtCapture(0) |
| 138 | + self.end_button.clicked.connect(self.capture.stop) |
| 139 | + # self.capture.setFPS(1) |
| 140 | + self.capture.setParent(self) |
| 141 | + self.capture.setWindowFlags(QtCore.Qt.Tool) |
| 142 | + self.capture.start() |
| 143 | + self.capture.show() |
| 144 | + |
| 145 | + def endCapture(self): |
| 146 | + self.capture.deleteLater() |
| 147 | + self.capture = None |
| 148 | + |
| 149 | + |
| 150 | +if __name__ == '__main__': |
| 151 | + import sys |
| 152 | + app = QtWidgets.QApplication(sys.argv) |
| 153 | + window = ControlWindow() |
| 154 | + sys.exit(app.exec_()) |
| 155 | + |
| 156 | + |
| 157 | + |
0 commit comments