[PYTHON] Make an effector for video conferencing with Spout + OpenCV + dlib (Part 1)

Spout can be selected as a camera from a video conferencing system such as Zoom, so if you select Web camera → Spout (Gonyogonyo in Python) → Zoom, you do not want to show your face as it is when working from home, but you want to show your face etc. , You can easily apply an effect to the face, or conversely erase the background other than the face. I wrote "easily", but in fact the original article is old, so it will not work if the version of each module is incompatible, so that Shioume is the know-how.

First, click here for the Spout head family, https://spout.zeal.co/ Install Spout from here.

Then download Spout for Python from:

https://github.com/spiraltechnica/Spout-for-Python

If each code in the Example in this Spout-for-Python-master works, you can use SpoutSDK.pyd in Libs as it is, but if it doesn't work, you have to build it yourself.

When building for Python, the following site will be helpful. According to the original above, It takes a lot of time because it builds all the libraries other than Python.

https://rusin.work/vjing/tools/spout-for-python/

One of the working version combinations in that case is as follows. This is all platforms It is unknown whether it works with. It may or may not actually work on your PC. Especially opencv etc. may not work properly. If you copy the working version of the Python folder to the non-working PC, it will work.

Python 3.74 PyOpenGL 3.15 pygame 1.18.2 opencv_python 4.2.0.34

Now, build it to create SpoutSDK.dll, which you renamed to SpoutSDK.pyd. Available from Python with the import SpoutSDK.

If the following code works on a PC equipped with WebCam, it's okay for the time being. In other words, you can receive the video from WebCam with SpoutReceive in the DEMO folder of Spout. Please check. If you can receive it, use Spout as a camera from Zoom etc. If selected, you can send the video to a video conference.

I'll show you how to make an effect on this in the next post.

import sys
sys.path.append('../Library')
import cv2
import numpy as np
import SpoutSDK
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

def main():

    # window details
    width = 640 
    height = 480 
    display = (width,height)
    
    # window setup
    pygame.init() 
    pygame.display.set_caption('Spout Python Sender')
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8)

    cap = cv2.VideoCapture(0)
    if cap.isOpened() is False:
        raise("IO Error")
    cap.set(cv2.CAP_PROP_FPS, 30)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

    cap.set(3, width)
    cap.set(4, height)

      # OpenGL init
    glMatrixMode(GL_PROJECTION)
    glOrtho(0,width,height,0,1,-1)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glDisable(GL_DEPTH_TEST)
    glClearColor(0.0,0.0,0.0,0.0)
    glEnable(GL_TEXTURE_2D)
   
    # init spout sender
    spoutSender = SpoutSDK.SpoutSender()
    spoutSenderWidth = width
    spoutSenderHeight = height
    # Its signature in c++ looks like this: bool CreateSender(const char *Sendername, unsigned int width, unsigned int height, DWORD dwFormat = 0);
    spoutSender.CreateSender('Spout for Python Webcam Sender Example', width, height, 0)
    
    # create texture id for use with Spout
    senderTextureID = glGenTextures(1)

    # initalise our sender texture
    glBindTexture(GL_TEXTURE_2D, senderTextureID)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glBindTexture(GL_TEXTURE_2D, 0)

    # loop
    while True:

        for event in pygame.event.get():
           if event.type == pygame.QUIT:
               pygame.quit()
               quit()
        
        ret, frame = cap.read() #read camera image
        #img = cv2.imread('image.png') # if use the image file
        frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) #BGR-->RGB
        h, w = frame.shape[:2]
        glBindTexture(GL_TEXTURE_2D, senderTextureID)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, frame)

        spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0)
        #glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        # Clear screen
        glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT )
        # reset the drawing perspective
        glLoadIdentity()

        # Draw texture to screen
        glBegin(GL_QUADS)
        ##
        glTexCoord(0,0)        
        glVertex2f(0,0)
        #
        glTexCoord(1,0)
        glVertex2f(width,0)
        #
        glTexCoord(1,1)
        glVertex2f(width,height)
        #
        glTexCoord(0,1)
        glVertex2f(0,height)
        ##
        glEnd()
        
        pygame.display.flip()
        # unbind our sender texture
        glBindTexture(GL_TEXTURE_2D, 0)
      #  pygame.time.wait(10)

if __name__ == '__main__':
    main()


Recommended Posts

Make an effector for video conferencing with Spout + OpenCV + dlib (Part 1)
Make thumbnails easily with opencv from the erotic video folder
Loop video loading with opencv
Let's make a WEB application for phone book with flask Part 1
Make a cat detector with Google Colabratory (Part 2) [Python] ~ Use OpenCV ~
Let's make a WEB application for phone book with flask Part 3
Let's make a WEB application for phone book with flask Part 4
Let's make an IoT shirt with Lambda, Kinesis, Raspberry Pi [Part 1]
I tried to make an image similarity function with Python + OpenCV
Search for homeomorphic idioms with opencv
Draw an illustration with Python + OpenCV
Make Scrapy an exe with Pyinstaller
Make an MQTT Publisher Box Part 2