Python Forum
How to receive webcam capture on spout? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: How to receive webcam capture on spout? (/thread-36035.html)



How to receive webcam capture on spout? - buzzdarkyear - Jan-12-2022

I'm trying to let Spout receive a webcam capture done with OpenCV but I keep getting errors. How can I approach this problem in the best way?

Error:
C:\Users\User\Desktop\Spout-for-Python-master2\venv\Scripts\python.exe C:/Users/User/Desktop/Spout-for-Python-master2/spout_webcam_sender_example.py pygame 2.1.2 (SDL 2.0.18, Python 3.6.0) Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "C:/Users/User/Desktop/Spout-for-Python-master2/spout_webcam_sender_example.py", line 125, in <module> main() File "C:/Users/User/Desktop/Spout-for-Python-master2/spout_webcam_sender_example.py", line 94, in main spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0) Boost.Python.ArgumentError: Python argument types in SpoutSender.SendTexture(SpoutSender, numpy.uintc, IntConstant, int, int, bool, int) did not match C++ signature: SendTexture(class SpoutSender {lvalue}, unsigned int, unsigned int, unsigned int, unsigned int, bool, unsigned int) [ WARN:[email protected]] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (539) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
Code:
import sys
import os

sys.path.append('{}/Library/3{}'.format(os.getcwd(), sys.version_info[1]))

import argparse
import cv2
import SpoutSDK
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

"""parsing and configuration"""
def parse_args():
    desc = "Spout for Python webcam sender example"
    parser = argparse.ArgumentParser(description=desc)

    parser.add_argument('--camSize', nargs = 2, type=int, default=[640, 480], help='File path of content image (notation in the paper : x)')

    parser.add_argument('--camID', type=int, default=1, help='Webcam Device ID)')

    return parser.parse_args()


"""main"""
def main():

    # parse arguments
    args = parse_args()

    # window details
    width = args.camSize[0]
    height = args.camSize[1]
    display = (width,height)

    # window setup
    pygame.init()
    pygame.display.set_caption('Webcam')
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8)

    # init capture & set size
    #cap = cv2.VideoCapture(args.camID)
    cap = cv2.VideoCapture(0)
    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()
        frame = cv2.flip(frame, 1 )
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        # Copy the frame from the webcam into the sender texture
        glBindTexture(GL_TEXTURE_2D, senderTextureID)
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, frame )

        # Send texture to Spout
        # Its signature in C++ looks like this: bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0);
        spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0)

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

        # update window
        pygame.display.flip()

        # unbind our sender texture
        glBindTexture(GL_TEXTURE_2D, 0)

if __name__ == "__main__":
    main()



RE: How to receive webcam capture on spout? - SheeppOSU - Jan-12-2022

Add a print statement on a line before the error occurs and print the type of each variable that is being used as arguments for spoutSender.SendTexture. Then make sure they are all correct since that's what the error seems to be fussing about.


RE: How to receive webcam capture on spout? - buzzdarkyear - Jan-12-2022

(Jan-12-2022, 07:54 AM)SheeppOSU Wrote: Add a print statement on a line before the error occurs and print the type of each variable that is being used as arguments for spoutSender.SendTexture. Then make sure they are all correct since that's what the error seems to be fussing about.

Thank you i've managed to fix it!

For some reason the variable senderTextureID wasn't giving the right value so I gave it manually one which for me is alright, I'm able to broadcoast my capture through Spout.

spoutSender.SendTexture(2, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0)
Instead of:
spoutSender.SendTexture(senderTextureID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0)
I really appreciate your help!