Python Forum
glTexImage2D is having problem loading img [update]
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
glTexImage2D is having problem loading img [update]
#1
I'm trying to upload a image trough glTexImage2D (line 125) so I can output it on a broadcasting network (Spout). I've added some filters to the img and because of this I cannot load it trough glTexImage2D. How can I fix this?

Full code:
import sys
import os

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

from Frame import *
import numpy as np
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 = "Output"
    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=0, 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)

    box = BoundingBox(-1, -1, -1, -1)

    # loop
    while(True):
        for event in pygame.event.get():
           if event.type == pygame.QUIT:
               pygame.quit()
               quit()

        ZOOM = 0.75
        SHOW_BOX = True  # Show detection box around the largest detected face
        SCALE_FACTOR = 1.2
        MIN_NEIGHBORS = 8
        MINSIZE = (60, 60)

        face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")

        ret, img = cap.read(0)
        img = cv2.flip(img, 1)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        face = face_cascade.detectMultiScale(
            img,
            scaleFactor=SCALE_FACTOR,
            minNeighbors=MIN_NEIGHBORS,
            minSize=MINSIZE,
        )

        boxes = np.array(face)

        # Linear interpolate bounding box to dimensions of largest detected box
        if boxes.size > 0:
            boxLrg = largestBox(boxes)
            if box.dim[0] == -1:
                box = boxLrg
            else:
                box.lerpShape(boxLrg)

        # Setup frame properties and perform filter
        img = Frame(img, box)
        img.boxIsVisible = SHOW_BOX
        img.setZoom(ZOOM)
        img.filter()
        box = img.box

        # Copy the img 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, img)

        # 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)
        spoutSender.SendTexture(2, 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()
When this part is removed everything is fine and I can broadcast:
        # Setup frame properties and perform filter
        img = Frame(img, box)
        img.boxIsVisible = SHOW_BOX
        img.setZoom(ZOOM)
        img.filter()
        box = img.box
When I print img without above filters this is what I get:
  [ 44  42  56]
  [ 44  42  57]
  [ 45  43  58]]

 [[ 32  41  72]
  [ 35  44  75]
  [ 35  45  74]
  ...
  [ 44  42  55]
  [ 44  42  56]
  [ 46  44  59]]]
When with filters:
<Frame.Frame object at 0x0000012574EB4BA8>
dict_keys([<class 'numpy.ndarray'>])
Full error:
Error:
Traceback (most recent call last): File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\latebind.py", line 43, in __call__ return self._finalCall( *args, **named ) TypeError: 'NoneType' object is not callable During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:/Users/User/Desktop/Spout-for-Python-master2/spout_webcam_sender_example.py", line 163, in <module> main() File "C:/Users/User/Desktop/Spout-for-Python-master2/spout_webcam_sender_example.py", line 127, in main glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img) File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\latebind.py", line 47, in __call__ return self._finalCall( *args, **named ) File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\wrapper.py", line 879, in wrapperCall pyArgs = tuple( calculate_pyArgs( args )) File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\wrapper.py", line 450, in calculate_pyArgs yield converter(args[index], self, args) File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\GL\images.py", line 456, in __call__ return arrayType.asArray( arg ) File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\arrays\arraydatatype.py", line 154, in asArray return cls.getHandler(value).asArray( value, typeCode or cls.typeConstant ) File "C:\Users\User\Desktop\Spout-for-Python-master2\venv\lib\site-packages\OpenGL\arrays\arraydatatype.py", line 58, in __call__ typ.__module__, typ.__name__, repr(value)[:50] TypeError: ('No array-type handler for type Frame.Frame (value: <Frame.Frame object at 0x0000012574EB4BA8>) registered', <OpenGL.GL.images.ImageInputConverter object at 0x000001256D9D2B38>) <Frame.Frame object at 0x0000012574EB4BA8> dict_keys([<class 'numpy.ndarray'>]) [ 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
How can I fix this problem? What is the best approach? In what should I research to be able to solve this?

UPDATE:

Full code to create zoom:
https://raw.githubusercontent.com/kailau...n/Frame.py

Does this have something to do with the problem? Much this be changed? This function is responsible for merging the image together with the filters
class Frame:
    boxIsVisible = False

    def __init__(self, img, box):
        self.zoom = 0.4
        self.img = img
        self.box = box
        x, y, w, h = box.dim
        self.postFilterBox = BoundingBox(x, y, w, h)

    def setZoom(self, amount):
        self.zoom = min(max(amount, 0.01), 0.99)

    def filter(self):

        # Declare basic variables
        screenHeight = self.img.shape[0]
        screenWidth = self.img.shape[1]
        screenRatio = float(screenWidth) / screenHeight

        (boxX, boxY, boxW, boxH) = self.box.dim
        distX1 = boxX
        distY1 = boxY                               # dist refers to the distances in front of and
        distX2 = screenWidth - distX1 - boxW        # behind the face detection box
        distY2 = screenHeight - distY1 - boxH       # EX: |---distX1----[ :) ]--distX2--|

        # Equalize x's and y's to shortest length
        if distX1 > distX2:
            distX1 = distX2
        if distY1 > distY2:
            distY1 = distY2

        distX = distX1      # Set to an equal distance value
        distY = distY1

        # Trim sides to match original aspect ratio
        centerX = distX + (boxW / 2.0)
        centerY = distY + (boxH / 2.0)
        distsRatio = centerX / centerY

        if screenRatio < distsRatio:
            offset = centerX - (centerY * screenRatio)
            distX -= offset
        elif screenRatio > distsRatio:
            offset = centerY - (centerX / screenRatio)
            distY -= offset

        # Make screen to box ratio constant
        # (constant can be changed as ZOOM in main.py)
        if screenWidth > screenHeight:
            distX = min(0.5 * ((boxW / self.zoom) - boxW), distX)
            distY = min(((1.0 / screenRatio) * (distX + (boxW / 2.0))) - (boxH / 2.0), distY)
        else:
            distY = min(0.5 * ((boxH / self.zoom) - boxH), distY)
            distX = min((screenRatio * (distY + (boxH / 2.0))) - (boxW / 2.0), distX)

        # Crop image to match distance values
        newX = int(boxX - distX)
        newY = int(boxY - distY)
        newW = int(2 * distX + boxW)
        newH = int(2 * distY + boxH)
        self.crop([newX, newY, newW, newH])

        # Resize image to fit original resolution
        resizePercentage = float(screenWidth) / newW
        self.img = cv2.resize(self.img, (screenWidth, screenHeight))
        for i in range(4):
            self.postFilterBox.dim[i] = int(self.postFilterBox.dim[i] * resizePercentage)

        # Flip Filtered image on y-axis
        self.img = cv2.flip(self.img, 2)

    def drawBox(self):
        (x, y, w, h) = self.postFilterBox.dim
        if x > 0:
            cv2.rectangle(self.img, (x, y), (x + w, y + h), (255, 255, 255), 2)

    def crop(self, dim):
        x, y, w, h = dim
        self.img = self.img[y:y + h, x:x + w]
        self.postFilterBox.dim[0] -= x
        self.postFilterBox.dim[1] -= y

    def show(self):
        if self.boxIsVisible:
            self.drawBox()
        cv2.imshow("Dolly Zoom", self.img)
UPDATE 2:

Basicly what need to be done is that the output of img + filter get converted to an array that glTextImage2D can handle I guess.. Does someone know how I can achieve this?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to make IMG + FILTER object convertable for glTexImage2D buzzdarkyear 0 909 Jan-12-2022, 05:15 PM
Last Post: buzzdarkyear
Question Python + Google Sheet | Best way to update specific cells in a single Update()? Vokofe 1 2,700 Dec-16-2020, 05:26 AM
Last Post: Vokofe
  Problem loading an image dataset into Tensorflow MohammedSohail 1 1,760 Jun-09-2020, 02:09 PM
Last Post: nuffink
  problem with select and update the data into the database chris0147 1 3,196 Aug-18-2017, 09:38 PM
Last Post: chris0147

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020