1

I was looking for a basic python program which will display webcam feed using OpenCV and PyOpenGL. I did some searches, and came up with a code posted in stackoverflow

  import cv2
  from OpenGL.GL import *
  from OpenGL.GLU import *
  from OpenGL.GLUT import *
  import numpy as np
  import sys


  #window dimensions
  width = 1280
  height = 720
  nRange = 1.0

  global capture
  capture = None

  def cv2array(im): 
    h,w,c=im.shape
    a = np.fromstring( 
       im.tostring(), 
       dtype=im.dtype, 
       count=w*h*c) 
    a.shape = (h,w,c) 
    return a

  def init():
    #glclearcolor (r, g, b, alpha)
    glClearColor(0.0, 0.0, 0.0, 1.0)

    glutDisplayFunc(display)
    glutReshapeFunc(reshape)
    glutKeyboardFunc(keyboard)
    glutIdleFunc(idle)  

  def idle():
    #capture next frame

    global capture
    _,image = capture.read()


    cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    #you must convert the image to array for glTexImage2D to work
    #maybe there is a faster way that I don't know about yet...

    #print image_arr


    # Create Texture
    glTexImage2D(GL_TEXTURE_2D, 
      0, 
      GL_RGB, 
      720,1280,
      0,
      GL_RGB, 
      GL_UNSIGNED_BYTE, 
      image)
    cv2.imshow('frame',image)
    glutPostRedisplay()

  def display():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glEnable(GL_TEXTURE_2D)
    #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    #glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    #glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
    #this one is necessary with texture2d for some reason
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

    # Set Projection Matrix
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluOrtho2D(0, width, 0, height)

    # Switch to Model View Matrix
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    # Draw textured Quads
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0)
    glVertex2f(0.0, 0.0)
    glTexCoord2f(1.0, 0.0)
    glVertex2f(width, 0.0)
    glTexCoord2f(1.0, 1.0)
    glVertex2f(width, height)
    glTexCoord2f(0.0, 1.0)
    glVertex2f(0.0, height)
    glEnd()

    glFlush()
    glutSwapBuffers()

  def reshape(w, h):
    if h == 0:
      h = 1

    glViewport(0, 0, w, h)
    glMatrixMode(GL_PROJECTION)

    glLoadIdentity()
    # allows for reshaping the window without distoring shape

    if w <= h:
      glOrtho(-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange)
    else:
      glOrtho(-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

  def keyboard(key, x, y):
    global anim
    if key == chr(27):
      sys.exit()

  def main():
    global capture
    #start openCV capturefromCAM
    capture = cv2.VideoCapture(0)
    print capture
    capture.set(3,1280)
    capture.set(4,720)
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
    glutInitWindowSize(width, height)
    glutInitWindowPosition(100, 100)
    glutCreateWindow("OpenGL + OpenCV")

    init()
    glutMainLoop()

  main()

What i'm trying to do is to use OpenGL to display the camera-feed (in full screen) instead of cv2.imshow. I have a hope that it might be faster than imshow.

Can anyone please explain to me display, reshape and idle functions also i cant run this code because it expects some argument which i still cant figure out.

PunyCode
  • 373
  • 4
  • 18
  • How exactly do you want to display it? Add some example, or an illustration of what sort of result you want. | "seemed too complex to me" in what sense? Elaborate. – Dan Mašek Apr 23 '18 at 12:29
  • Docs [here](https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html), once you capture the frame, you can just convert it to RGB, flip y coordinate (PIL) and finally uploading the texture to the gpu so you can display it in the way you want. – BPL Apr 23 '18 at 12:29
  • @BPL PIL to just flip a numpy array around its axis? [Why?](https://docs.scipy.org/doc/numpy/reference/generated/numpy.flip.html) – Dan Mašek Apr 23 '18 at 12:37
  • 1
    @DanMašek Because PIL's tobytes routine not only support RGB conversion but also does flipping for free... I assume (haven't tested) as fast as numpy's flip – BPL Apr 23 '18 at 12:43
  • @BPL I suppose... although IMHO it's an overkill to bring in another dependency/library just to do something you can achieve using tools that cv2 and numpy already provide. I've seen a number of questions here where people stubbed their toes because of doing that unnecessarily. – Dan Mašek Apr 23 '18 at 13:00
  • 2
    @DanMašek Well, as usual, it depends... for example, one old project of mine uses a custom c++ opengl engine wrapped to python (it doesn't use numpy at all for doing maths) so when i needed webcam support i found it convenient to use PIL (which was been used for other tasks). So in my case, I wouldn't say overkill is a problem at all, now... if you tell me by using directly numpy's you can gain a little bit of extra frames per second, then yeah, for me that'd be a valid point – BPL Apr 23 '18 at 13:06
  • @DanMašek sorry mate. hope its clear now. – PunyCode Apr 24 '18 at 05:02
  • @AnuragJk [This script](https://pastebin.com/z42n8qD3) runs quite nicely here, using a video, but it should be trivial to change for a camera. I just took your sample, removed unnecessary bits and pieces, and refactored it into a class to avoid the need for globals. – Dan Mašek Apr 25 '18 at 00:06
  • `cvtColor` is unnecessary, you can tell `glTexImage2D` that the pixel data is `GL_BGR`. | `cv2array` function is dead code. | `cv2.imshow` seems counterproductive. | The script in previous post resizes nicely, but it doesn't yet run automatically full-screen. I'll lot into that tomorrow. – Dan Mašek Apr 25 '18 at 00:14
  • @Dan Mašek program expects some argument which i cant figure out. – PunyCode Apr 25 '18 at 06:23
  • @AnuragJk What? Does it not run? Does it produce an error? Or what do you mean? The command line argument parsing done by [`glutInit()`](https://www.opengl.org/resources/libraries/glut/spec3/node10.html) ? – Dan Mašek Apr 25 '18 at 08:56
  • I get following error `odroid@odroid:~/ogl$ python ogl.py Traceback (most recent call last): File "ogl.py", line 110, in glutInit(sys.argv) File "/usr/local/lib/python2.7/dist-packages/OpenGL/GLUT/special.py", line 333, in glutInit _base_glutInit( ctypes.byref(count), holder ) File "/usr/local/lib/python2.7/dist-packages/OpenGL/platform/baseplatform.py", line 407, in __call__ self.__name__, self.__name__, OpenGL.error.NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling` – PunyCode Apr 26 '18 at 04:35
  • @Dan Mašek what does `glutInit()` do ? – PunyCode Apr 26 '18 at 04:38
  • @AnuragJk As the documentation page I linked to says, it initializes the [OpenGL Utility Toolkit (GLUT)](https://en.wikipedia.org/wiki/OpenGL_Utility_Toolkit) library. | Regarding that error you will need to search around... you're [not the first who encountered it](https://stackoverflow.com/questions/26700719/pyopengl-glutinit-nullfunctionerror). Can't give you any more specific help, I don't use odroid. – Dan Mašek Apr 26 '18 at 10:26

0 Answers0