Saurabh Fegade
Saurabh Fegade

Reputation: 83

How to play the output of OpenCV to Kivy VideoPlayer or any other player?

I want to make a face detection video player. I have the following dlib code for face detection. I want the output of the OpenCV video to be played on my Kivy Video Player. Can anyone tell me how can I do it?

main.py

from detect_face import FaceDetector
import cv2
import argparse
from imutils import resize




# PROTOTXT_PATH = './models/MobileNetSSD_deploy.prototxt'
# CAFFE_MODEL_PATH = './models/MobileNetSSD_deploy.caffemodel'
# person.detect_(image)
# image = person.display_person_nn(image)
# person = PersonDetector(0.4, PROTOTXT_PATH, CAFFE_MODEL_PATH)




if __name__ == '__main__':

    #ap = argparse.ArgumentParser()
    #ap.add_argument('-v', '--video', required=True)
    #args = vars(ap.parse_args())

    #video_files_path = args['video']
    video_files_path = "test.mp4"

    cap = cv2.VideoCapture(video_files_path)
    # Initialised a face detector
    face = FaceDetector()
    while True:

        success, image = cap.read()

        if success:
            image = resize(image, width=512)
            f = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
            #Do something
            print(f)

            _ = face.detect_(image)
            face.display_face(image)


            cv2.imshow('', image)
            k = cv2.waitKey(1) & 0xFF
            if k == 27:
                break
        else:
            break

    cv2.destroyAllWindows()
    cap.release()

There's a separate detect_face.py file for the actual face detection code.
Please tell me if you require the kivy videoplayer code too.

Upvotes: 2

Views: 2491

Answers (1)

eyllanesc
eyllanesc

Reputation: 244182

You do not have a video as output but some arrays that represent an image,so we can place those arrays as Texture, and then set it to an Image.

from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
import cv2

class KivyCV(Image):
    def __init__(self, capture, fps, **kwargs):
        Image.__init__(self, **kwargs)
        self.capture = capture
        Clock.schedule_interval(self.update, 1.0 / fps)

    def update(self, dt):
        ret, frame = self.capture.read()
        if ret:
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            faceCascade = cv2.CascadeClassifier("lbpcascade_frontalface.xml")
            faces = faceCascade.detectMultiScale(
                gray,
                scaleFactor=1.1,
                minNeighbors=5,
                minSize=(30, 30),
                flags = cv2.CASCADE_SCALE_IMAGE
            )

            for (x, y, w, h) in faces:
                cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

            buf = cv2.flip(frame, 0).tostring()
            image_texture = Texture.create(
                size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
            image_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
            # display image from the texture
            self.texture = image_texture


class OpenCVApp(App):
    def build(self):
        self.capture = cv2.VideoCapture("/path/of/filename_or_device")
        my_camera = KivyCV(capture=self.capture, fps=60)
        return my_camera

    def on_stop(self):
        self.capture.release()


if __name__ == '__main__':
    OpenCVApp().run()

The complete example can be found in the following link.

Upvotes: 4

Related Questions