我有一些检测情绪和面部表情的代码。我在笔记本电脑上开发了它,并且运行良好。 我放在树莓派上,现在代码没有显示视频,面部识别或情绪数据。
我从此链接为树莓派运行了命令,以查看打开的CV中的相机模块:VideoCapture.open(0) won't recognize pi cam
以及此链接:I am trying make the raspberry pi camera work with opencv。
这是我的代码:
# -*- coding: utf-8 -*-
import os
import cv2
import numpy as np
from PyQt4 import QtCore, QtGui, uic
from keras.engine.saving import load_model
from keras_preprocessing.image import img_to_array
from picamera.array import PiRGBArray
from picamera import PiCamera
# parameters for loading data and images
dir_path = os.path.dirname(os.path.realpath(__file__))
detection_model_path = os.path.join("xxxx")
emotion_model_path = os.path.join("xxxx")
# hyper-parameters for bounding boxes shape
# loading models
face_detection = cv2.CascadeClassifier(detection_model_path)
emotion_classifier = load_model(emotion_model_path, compile=False)
EMOTIONS = ["angry", "disgust", "scared", "happy", "sad", "surprised", "neutral"]
emotion_classifier._make_predict_function()
running = False
capture_thread = None
form_class, _ = uic.loadUiType("simple2.ui")
def NumpyToQImage(img):
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
qimg = QtGui.QImage(rgb.data, rgb.shape[1], rgb.shape[0], QtGui.QImage.Format_RGB888)
return qimg
class CaptureWorker(QtCore.QObject):
imageChanged = QtCore.pyqtSignal(np.ndarray)
def __init__(self, properties, parent=None):
super(CaptureWorker, self).__init__(parent)
self._running = False
self._capture = None
self._properties = properties
@QtCore.pyqtSlot()
def start(self):
if self._capture is None:
self._capture = cv2.VideoCapture(self._properties["index"])
self._capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, self._properties["width"])
self._capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, self._properties["height"])
self._capture.set(cv2.cv.CV_CAP_PROP_FPS, self._properties["fps"])
self._running = True
self.doWork()
@QtCore.pyqtSlot()
def stop(self):
self._running = False
def doWork(self):
while self._running:
self._capture.grab()
ret, img = self._capture.retrieve(0)
if ret:
self.imageChanged.emit(img)
self._capture.release()
self._capture = None
class ProcessWorker(QtCore.QObject):
resultsChanged = QtCore.pyqtSignal(np.ndarray)
imageChanged = QtCore.pyqtSignal(np.ndarray)
@QtCore.pyqtSlot(np.ndarray)
def process_image(self, img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_detection.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE)
canvas = np.zeros((250, 300, 3), dtype="uint8")
if len(faces) > 0:
face = sorted(faces, reverse=True, key=lambda x: (x[2] - x[0]) * (x[3] - x[1]))[0]
(fX, fY, fW, fH) = face
roi = gray[fY:fY + fH, fX:fX + fW]
roi = cv2.resize(roi, (64, 64))
roi = roi.astype("float") / 255.0
roi = img_to_array(roi)
roi = np.expand_dims(roi, axis=0)
preds = emotion_classifier.predict(roi)[0]
label = EMOTIONS[preds.argmax()]
cv2.putText(img, label, (fX, fY - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
cv2.rectangle(img, (fX, fY), (fX+fW, fY+fH), (255, 0, 0), 2)
self.imageChanged.emit(img)
for i, (emotion, prob) in enumerate(zip(EMOTIONS, preds)):
text = "{}: {:.2f}%".format(emotion, prob * 100)
w = int(prob * 300)
cv2.rectangle(canvas, (7, (i * 35) + 5),
(w, (i * 35) + 35), (0, 0, 255), -1)
cv2.putText(canvas, text, (10, (i * 35) + 23),
cv2.FONT_HERSHEY_SIMPLEX, 0.45,
(255, 255, 255), 2)
cv2.putText(img, label, (fX, fY - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
cv2.rectangle(img, (fX, fY), (fX + fW, fY + fH),
(0, 0, 255), 2)
self.resultsChanged.emit(canvas)
class MyWindowClass(QtGui.QMainWindow, form_class):
def __init__(self, parent=None):
super(MyWindowClass, self).__init__(parent)
self.setupUi(self)
self._thread = QtCore.QThread(self)
self._thread.start()
self._capture_obj = CaptureWorker({"index": 0, "width": 640, "height": 480, "fps": 30})
self._process_obj = ProcessWorker()
self._capture_obj.moveToThread(self._thread)
self._process_obj.moveToThread(self._thread)
self._capture_obj.imageChanged.connect(self._process_obj.process_image)
self._process_obj.imageChanged.connect(self.on_video_changed)
self._process_obj.resultsChanged.connect(self.on_emotional_changed)
self.startButton.clicked.connect(self.start_clicked)
@QtCore.pyqtSlot()
def start_clicked(self):
QtCore.QMetaObject.invokeMethod(self._capture_obj, "start", QtCore.Qt.QueuedConnection)
self.startButton.setEnabled(False)
self.startButton.setText('Starting...')
@QtCore.pyqtSlot(np.ndarray)
def on_emotional_changed(self, im):
img = NumpyToQImage(im)
pix = QtGui.QPixmap.fromImage(img)
self.emotional_label.setFixedSize(pix.size())
self.emotional_label.setPixmap(pix)
@QtCore.pyqtSlot(np.ndarray)
def on_video_changed(self, im):
img = NumpyToQImage(im)
pix = QtGui.QPixmap.fromImage(img)
self.video_label.setPixmap(pix.scaled(self.video_label.size()))
def closeEvent(self, event):
self._capture_obj.stop()
self._thread.quit()
self._thread.wait()
super(MyWindowClass, self).closeEvent(event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MyWindowClass()
w.show()
sys.exit(app.exec_())
当我启动我的应用程序并单击“启动相机”按钮时,相机的电源确实打开了(我看到树莓派上连接的相机模块上的红色LED)。
如何更改代码以使视频流和统计窗口显示在GUI中?
我的系统: python 2.7 最新版本的Rasbian OS 连接到Raspbery Pi 3B +的串行摄像机 使用pyqt4开发的GUI