from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import cv2 # OpenCV
import qimage2ndarray # for a memory leak
from dialog import *
class VideoWidget(QWidget):
def __init__(self, root, **kwargs):
super().__init__(root, **kwargs)
self.main=root
self.dialogOpenFromCamera = Dialog(self)
self.initUI()
@Slot(QImage)
def setImage (self, image):
self.label.setPixmap(QPixmap.fromImage(image))
def initUI(self):
self.setFixedSize(640,480)
self.label = QLabel(self)
self.label.setText("Загрузите видео")
self.label.setAlignment(Qt.AlignCenter)
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(0,0,0,0)
self.layout.addWidget(self.label)
self.setLayout(self.layout)
self.th = Thread(self)
self.th.changePixmap.connect(self.setImage)
def open(self):
fileDialog = QFileDialog(self)
supportedMimeTypes = ["video", "*.*"]
fileDialog.setMimeTypeFilters(supportedMimeTypes)
moviesLocation = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation)
fileDialog.setDirectory(moviesLocation)
if fileDialog.exec_() == QDialog.Accepted:
if (self.th.way != fileDialog.selectedUrls()[0].toDisplayString()): # если выбран не тот же файл
print ("\nВыбран новый файл: ", fileDialog.selectedUrls()) # проверка — выведем название выбранного файла
if (self.th.way != None): #и если это не первый запуск (кажется, это избыточное условие, но пока проверяю всё)
self.th.exit(0) #!!!прерывание потока
print ("Старый th.way: ", self.th.way) # проверка старого пути
self.th.way = fileDialog.selectedUrls()[0].toDisplayString() #меняем путь в классе потока, чтобы следующий поток запустился с новым источником видео
print ("Теперь th.way =", self.th.way) #проверка нынешнего пути в потоке
self.th.start() # запуск потока снова
def open_from_camera(self):
self.dialogOpenFromCamera.exec_() # запуск формочки для ввода порта камеры (позже будет получение адреса ip-камеры). Сейчас self.dialogOpenFromCamera.way = 0
if (self.th.way != self.dialogOpenFromCamera.way): # если путь потока и путь формы не совпадают
if (self.th.way != None): #и если это не первый запуск потока
self.th.exit(0) #!!!завершить поток
self.th.way = self.dialogOpenFromCamera.way #изменить его путь
self.th.start() #и запустить
class Thread (QThread):
changePixmap = Signal(QImage)
def __init__(self, root, **kwargs):
super().__init__(root, **kwargs)
self.main=root
self.way=None
def run(self):
cap = cv2.VideoCapture(self.way)#"video_file.mp4")#0)
while True:
face_cascade= cv2.CascadeClassifier(r'face_cascade.xml')
ret, frame = cap.read()
if (ret == True):
cap.set(3,640)
cap.set(4, 480)
frame = cv2.cvtColor (frame, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
image = qimage2ndarray.array2qimage(frame)
self.changePixmap.emit(image)
import sys
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import cv2 # OpenCV
import qimage2ndarray # for a memory leak
class ThreadCamera(QThread):
status = True
changePixmap = Signal(QImage)
def __init__(self):
super().__init__()
self.capture = cv2.VideoCapture(0)
def setStatus(self, status):
self.status = status
def captureRelease(self):
self.capture.release()
def run(self):
while self.status:
face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')
ret, frame = self.capture.read()
if (ret == True):
self.capture.set(3,640)
self.capture.set(4, 480)
frame = cv2.cvtColor (frame, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
image = qimage2ndarray.array2qimage(frame)
self.changePixmap.emit(image)
class ThreadVideoFile(QThread):
status = True
changePixmap = Signal(QImage)
def __init__(self, path):
super().__init__()
self.capture = cv2.VideoCapture(path)
def set_status(self, status):
self.status = status
def captureRelease(self):
self.capture.release()
def run(self):
while self.status:
face_cascade = cv2.CascadeClassifier(r'haarcascade_frontalface_default.xml')
ret, frame = self.capture.read()
if (ret == True):
self.capture.set(3,640)
self.capture.set(4, 480)
frame = cv2.cvtColor (frame, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = frame[y:y+h, x:x+w]
image = qimage2ndarray.array2qimage(frame)
self.changePixmap.emit(image)
class Dialog(QDialog):
def __init__(self, parent):
super().__init__()
self.resize(400, 100)
self.label = QLabel()
self.label.setText("<center><h1>Выберите действие</h1></center>")
self.button_open_camera = QPushButton('Камера')
self.button_open_camera.clicked.connect(parent.open_camera)
self.button_open_file = QPushButton('Видео файл')
self.button_open_file.clicked.connect(parent.open_file)
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.button_open_camera)
layout.addWidget(self.button_open_file)
self.setLayout(layout)
class VideoWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.thread_camera = ThreadCamera()
self.thread_video = ThreadVideoFile("videoplayback.mp4")
@Slot(QImage)
def setImage (self, image):
self.label.setPixmap(QPixmap.fromImage(image))
def initUI(self):
self.setFixedSize(640, 480)
self.label = QLabel(self)
self.label.setText("Загрузите видео")
self.label.setAlignment(Qt.AlignCenter)
self.label.installEventFilter(self)
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.label)
self.setLayout(self.layout)
def eventFilter(self, obj, event):
# Только фильтровать событие label, переписать его поведение,
# другие события будут проигнорированы
if obj == self.label:
# здесь отфильтруйте событие mouse и перепишите его поведение
if event.type() == QEvent.MouseButtonPress:
if event.buttons() == Qt.LeftButton:
self.dialog = Dialog(self)
self.dialog.exec_()
return False
def open_file(self):
if self.thread_video.isRunning() is True:
self.thread_video.set_status(False)
self.thread_video.captureRelease()
self.dialog.hide()
self.thread_camera.setStatus(False)
self.thread_camera.captureRelease()
self.label.setText("Загрузите видео")
fileDialog = QFileDialog(self)
supportedMimeTypes = ["video", "*.*"]
fileDialog.setMimeTypeFilters(supportedMimeTypes)
moviesLocation = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation)
fileDialog.setDirectory(moviesLocation)
if fileDialog.exec_() == QDialog.Accepted:
self.file = fileDialog.selectedUrls()[0].toDisplayString()
self.thread_video = ThreadVideoFile(self.file)
self.thread_video.changePixmap.connect(self.setImage)
self.thread_video.start()
def open_camera(self):
self.dialog.hide()
self.thread_video.set_status(False)
self.thread_video.captureRelease()
self.label.setText("Загрузите видео")
self.thread_camera = ThreadCamera()
self.thread_camera.changePixmap.connect(self.setImage)
self.thread_camera.start()
def main():
app = QApplication([])
video_widget = VideoWidget()
video_widget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()