1

I have some code that detects emotions and faces. I developed it on my laptop and it runs fine. I placed on my raspberry pi and now the code isn't displaying the video, facial recognition or the emotional stats.

I ran the command from this link for my raspberry pi to see my camera module in open CV: VideoCapture.open(0) won't recognize pi cam

and this link: I am trying make the raspberry pi camera work with opencv.

Here is my code:

# -*- 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_())

The camera does turn on when I start my app and click the start camera button (I see the red LED on the camera module attached to my raspberry pi).

How do I change my code in order to get the video stream and the stats window to show up in the GUI?

My system: python 2.7 latest version of Rasbian OS serial camera attached to Raspbery Pi 3B+ GUI developed using pyqt4

ironmantis7x
  • 799
  • 2
  • 14
  • 49
  • Have you checked this... https://stackoverflow.com/a/48298625/2836621 – Mark Setchell Jan 07 '19 at 11:53
  • 2
    Maybe you could be a bit more specific about what the problem is? Maybe you could add some debugging `print` commands at critical places to see if you are actually initialising the camera successfully? Or print the dimensions of each acquired image... – Mark Setchell Jan 07 '19 at 12:02
  • When the program was developed on my laptop, it works fine. When I plugged a USB camera to the Raspberry pi, it works fine. I am now using a serial interface camera (a camera module that connects to the Raspberry pi by a ribbon cable connected to the camera interface on the actual board). When I press the start button. No videonshows up and there is no error message displayed in the console. Can some one help me with my code please?? – ironmantis7x Jan 07 '19 at 13:04
  • And yes I tried what is in the link you posted @MarkSetchell. It still is not displaying the video. The camera module works when I start the camera using the command line. It works fine. In my python program the raspberry pi camera module is not displaying the camera feed. How can I get open CV to display the camera feed (video) in my GUI with the code I have written? This is my question. – ironmantis7x Jan 07 '19 at 13:09
  • I have justbeen through something very similar - please include the traceback of errors an I may be able to help – Jamie Lindsey Jan 13 '19 at 22:29
  • At first, you must be sure your camera perfectly works with any dedicated software. – sancelot Jan 14 '19 at 07:34
  • @sancelots that was the first thing I checked and the camera works 100% fine. My post stated I needed a coding solution so I can understand the problem. So far user Jack Herer has really provided a real help. I listed what I did as my efforts and what input I took from StackOverflow and shared the links. Simple responses like this don't help as I need more help than that. Thanks. – ironmantis7x Jan 14 '19 at 10:14
  • @JackHererJac how to I get a full traveling sir? I am hoping you can help me. – ironmantis7x Jan 14 '19 at 10:18
  • When I just throw a quick look at the code, I am wondering where you use the imported "picamera" at all... It is nowhere in the code. I would assume you have to use it somewhere... If you have problems with the camera, the whole code is unneeded. You should just concentrate on the camera itself and not on facial detection. Get the camera to run with opencv without all that code and if it works you know how to modify the code. – andi8086 Jan 14 '19 at 10:28
  • I would recommend including some prints inside the `doWork` loop printing ret and img at least. By the looks of it, OpenCV succesfully opens the camera(the led is probably signaling that), but it is failing to retrieve the images. That return code `ret` may contain insight, the `img` may contain some pixels, and if nothing is printed, you will know the program is blocking in `grab` or `retrieve` call, and this should be easier to look up. – Arthur Moraes Do Lago Jan 14 '19 at 11:06
  • @andi8086 the camera works fine. The image does not update at all. It opens when the start button is clicked. I see an image with the facial recognition box and emotion stats. The issue now is that the image does not update at all and its extremely slow. – ironmantis7x Jan 14 '19 at 14:59
  • I came across this tutorial and it helped some, but my current issues are still present. https://pythonprogramming.net/raspberry-pi-camera-opencv-face-detection-tutorial/. – ironmantis7x Jan 14 '19 at 15:00
  • I think the pyqt4 gui isn't updating like it should – ironmantis7x Jan 14 '19 at 15:00

0 Answers0