WebcamVideo.getNumOptions() returns 0

I tried this on two different machines, but it works on neither of them. I’m trying to use a webcam with Panda3D. I found this bit of code in the forum (https://discourse.panda3d.org/viewtopic.php?t=5420&highlight=&sid=6d15b415b602b627184284d427d713f6):

from pandac.PandaModules import WebcamVideo

print "Choose a webcam" 
for o in range(WebcamVideo.getNumOptions()): 
  option = WebcamVideo.getOption(o) 
  print "Option %d, '%s' at %f fps with size %dx%d" % (o, option.getName(), option.getFps(), option.getXSize(), option.getYSize()) 

o = int(raw_input("option>")) 
option = WebcamVideo.getOption(o) 
cursor = option.open()

WebcamVideo.getNumOptions() always returns 0. The webcam is functioning correctly and shows up under “Scanners and Cameras” in the Windows XP configuration panel. I’m using a “Quickcam for Notebooks Deluxe” camera.

I’ve also tried to use OpenCVTexture (which I found here: discourse.panda3d.org/viewtopic.php … highlight=) but then I get this message:

ImportError: cannot import name OpenCVTexture

Anybody?

opencv was accidently not included in the 1.5.4 build.
webcamVideo seems to be only semi-finished work.
right now i’m trying to get opencv working myself. there seems to be a few more strange things going on. investigations are ongoing.

Thanks Thomas. I’ll give 1.5.3 a try.

Just tried 1.5.3 and it doesn’t work in this version. According to this thread: https://discourse.panda3d.org/viewtopic.php?p=27333&sid=6fdb6f87c037b56f7c3cf95fda1c5391 it also doesn’t work in 1.5.2.

I guess I’ll have to wait for the next release then.

OpenCV will be included in the upcoming 1.6.0 release.

If you want to use WebcamVideo, you need to downgrade all the way back to 1.5.2, sorry bout that. It will be restored in the upcoming release as well.

Ok, I’ll give 1.5.2 a try then! Thanks.

Yes, that worked. Thanks for your help!

Not quite there yet … :slight_smile:
It shows me all the available webcams, I can pick one and I can use it as a texture. But all I see is a white square.
This is the code I use:

import direct.directbase.DirectStart
from pandac.PandaModules import WebcamVideo
from pandac.PandaModules import PandaSystem
from pandac.PandaModules import Texture
from pandac.PandaModules import CardMaker

print str(PandaSystem.getVersionString())
print "Choose a webcam" 
for o in range(WebcamVideo.getNumOptions()): 
  option = WebcamVideo.getOption(o) 
  print "Option %d, '%s' at %f fps" % (o, option.getName(), option.getFps()) 

o = int(raw_input("option>")) 
option = WebcamVideo.getOption(o) 
cursor = option.open()

tex = Texture('movie') 
cursor.setupTexture(tex) 
cm = CardMaker('card') 
card = aspect2d.attachNewNode(cm.generate()) 
card.setTexture(tex)

run()

This is the output:

1.5.2
Choose a webcam
Added device: DirectShow: QuickCam for Notebooks Deluxe @ 320 x 240  FPS:15
Added device: DirectShow: QuickCam for Notebooks Deluxe @ 176 x 144  FPS:30
Added device: DirectShow: QuickCam for Notebooks Deluxe @ 160 x 120  FPS:30
Added device: DirectShow: QuickCam for Notebooks Deluxe @ 352 x 288  FPS:15
Added device: DirectShow: QuickCam for Notebooks Deluxe @ 640 x 480  FPS:15
Option 0, 'DirectShow: QuickCam for Notebooks Deluxe @ 320 x 240  FPS:15' at 15.000000 fps with size
Option 1, 'DirectShow: QuickCam for Notebooks Deluxe @ 176 x 144  FPS:30' at 30.000000 fps with size
Option 2, 'DirectShow: QuickCam for Notebooks Deluxe @ 160 x 120  FPS:30' at 30.000000 fps with size
Option 3, 'DirectShow: QuickCam for Notebooks Deluxe @ 352 x 288  FPS:15' at 15.000000 fps with size
Option 4, 'DirectShow: QuickCam for Notebooks Deluxe @ 640 x 480  FPS:15' at 15.000000 fps with size
option>4
  IID_IGraphBuilder & IID_ICaptureGraphBuilder2 are established.
  IID_IMediaControl interface is acquired.
  The capture filter is acquired.
  The capture filter has been added to the graph.
  IID_IBaseFilter of CLSID_SampleGrabber is acquired.
  The media type of the sample grabber is set 24-bit RGB.
  The sample grabber has been added to the graph.
  IID_IBaseFilter of CLSID_NullRenderer is acquired.
  The Null Renderer has been added to the graph.
Connected media type 640 x 480
:util(warning): Adjusting global clock's real time by -2.6743 seconds.

Huh. Probably there still needs to be some method called or so. I don’t know beans about MovieVideoCursor.

I’ve tried this with the new 1.6.0 but I still can’t get it to work. This is what I’m trying:

import direct.directbase.DirectStart

from pandac.PandaModules import OpenCVTexture
from pandac.PandaModules import CardMaker

tex = OpenCVTexture() 
tex.fromCamera()
 
cm = CardMaker('card') 
card = aspect2d.attachNewNode(cm.generate()) 
card.setTexture(tex)

run()

When I run it, it selects the right webcam, the panda application locks and uses it but I don’t see anything.

When I add this to the code:

print tex.getTexScale()
print tex.getVideoWidth()
print tex.getVideoHeight()

The output is:

VBase2(0, 0)
0
0

I’m sure I’m missing something. Anybody?

your code works fine for me. so… the problem is somewhere else.thought i dont know where.
i’m runnin 1.6.0 on linux here on a dell laptop +integrated webcam.

i’ve tried to get opencv to run under windows as well, without luck. i get the same error as you do, the camera is opened but with a image size of 0/0.

but i could get it to run under windows using this:

import sys

from pandac.PandaModules import *
from direct.directbase import DirectStart

if sys.platform == 'win32':
  # manually select the video mode
  if False:
    print str(PandaSystem.getVersionString())
    print "Choose a webcam"
    for o in range(WebcamVideo.getNumOptions()):
      option = WebcamVideo.getOption(o)
      print "Option %d, '%s' at %f fps" % (o, option.getName(), option.getFps())
    
    # ask the user which camera to use
    o = int(raw_input("option>"))
    option = WebcamVideo.getOption(o)
  else:
    # just use the option 0
    option = WebcamVideo.getOption(0)
  
  cursor = option.open()
  
  videoTexture = Texture('movie')
  cursor.setupTexture(videoTexture)
  # calculate the same as openCVTexture has as function
  videoTextureScale = Vec2(option.getSizeX()/float(videoTexture.getXSize()), option.getSizeY()/float(videoTexture.getYSize()))
  
  # under windows the webcam must be updated manually
  def updateVideo(task):
    if cursor.ready():
      cursor.fetchIntoTexture(0, videoTexture, 0)
    return task.cont
  taskMgr.add(updateVideo, 'updateVideo')

elif sys.platform == 'linux2':
  # fallback in case something goes wrong (openCVTexture doesnt work under windows yet)
  videoTextureScale = (1,1)
  
  # use the tex-coordinates so the video fills the whole card
  videoTexture = OpenCVTexture()
  print "camera open", videoTexture.fromCamera()
  print "camera video resolution", videoTexture.getVideoWidth(), videoTexture.getVideoHeight()
  # get the texture scale
  videoTextureScale = videoTexture.getTexScale()
  if not videoTexture.getVideoWidth() or not videoTexture.getVideoHeight():
    print "invalid camera texture size", videoTexture.getVideoWidth(), videoTexture.getVideoHeight()
    sys.exit()
  
  # save the opencv video into a image
  #pnmImage0 = PNMImage()
  #openCVTexture.store(pnmImage0)

# generate a card to show the texture on
cardMaker = CardMaker('cardMaker')
# define the card size
#cardMaker.setFrame(-videoTextureScale[1]/2.,videoTextureScale[1]/2.,-videoTextureScale[0]/2.,videoTextureScale[0]/2.)
cardMaker.setFrame(-videoTextureScale[1],videoTextureScale[1],-videoTextureScale[0],videoTextureScale[0])
# set the uv coordinates of the card, y-scale must be reversed
cardMaker.setUvRange(Point2(videoTextureScale[0],0), Point2(0,videoTextureScale[1]))

# create a card and attach to render
card = render.attachNewNode(cardMaker.generate())
card.setTexture(videoTexture)
card.setTwoSided(True)

# rotate it
card.hprInterval(10,Point3(360,0,0)).loop()

base.disableMouse()
base.camera.setPos(0,-3,0)

run()

windows and linux is handled differently, maybe osx runs the same as linux but i dont know. unfortunately the camera output is much worse under windows for me.

I’m using a Logitech quickcam on Windows XP.
Hypnos’ code actually worked for me, thanks a lot!
The image quality isn’t too good though.

i dont really know if this is the way it’s supposed to be done (if somebody encounters problems it may be because of that).

i’ve also posted a bugreport for 1.6, i hope we can get a consistent way of handling camera’s on all supported systems using opencv.

bugs.launchpad.net/panda3d/+bug/357571

Hey all,

I’m trying to get the above code working, but all I get is a white spinning card – no webcam video. If I add print statements to the updateVideo task then I see that cursor.ready() never returns True.

Here’s the output:

DirectStart: Starting the game.
Known pipe types:
wglGraphicsPipe
(all display modules loaded.)
Added device: DirectShow: USB Video Device @ 320 x 240 FPS:15
Added device: DirectShow: USB Video Device @ 160 x 120 FPS:30
Added device: DirectShow: USB Video Device @ 176 x 144 FPS:30
Added device: DirectShow: USB Video Device @ 352 x 288 FPS:15
Added device: DirectShow: USB Video Device @ 640 x 480 FPS:15
IID_IGraphBuilder & IID_ICaptureGraphBuilder2 are established.
IID_IMediaControl interface is acquired.
The capture filter is acquired.
The capture filter has been added to the graph.
IID_IBaseFilter of CLSID_SampleGrabber is acquired.
The media type of the sample grabber is set 24-bit RGB.
The sample grabber has been added to the graph.
IID_IBaseFilter of CLSID_NullRenderer is acquired.
The Null Renderer has been added to the graph.
Connected media type 320 x 240

Thanks for any help you can provide!

I’ve tried getting the above code to work on Ubuntu 9.10 64bit.

The software runs, and I can see opencv style output about my camera:

camera open 1
camera video resolution 320 240
Corrupt JPEG data: 27 extraneous bytes before marker 0xd9
Corrupt JPEG data: premature end of data segment
Corrupt JPEG data: 9 extraneous bytes before marker 0xd9
Corrupt JPEG data: 23 extraneous bytes before marker 0xd9
Corrupt JPEG data: premature end of data segment
Corrupt JPEG data: 53 extraneous bytes before marker 0xd9

but I get nothing but a white texture. I have other python examples working on this machine using the cctypes-opencv wrapper. So I don’t think the error is opencv…

If I try to use WebcamVideo I get:

DirectStart: Starting the game.
Known pipe types:
  glxGraphicsPipe
(all display modules loaded.)
Assertion failed: (n >= 0) && (n < (int)_all_webcams.size()) at line 86 of panda/src/vision/webcamVideo.cxx
Traceback (most recent call last):
  File "WebCamChooserBig.py", line 20, in <module>
    option = WebcamVideo.getOption(0) 
AssertionError: (n >= 0) && (n < (int)_all_webcams.size()) at line 86 of panda/src/vision/webcamVideo.cxx

afaik webcamvideo is a stub on linux. means it’s not implemented at all. and the white texture on webcam video bug is already known and beeing investigated.

I’ve done some testing:

I have it working with XP and Panda 1.6.2 with various cameras USB and Firewire using the WebcamVideo

I also have it working on 64bit Ubuntu 9.10 - again with Panda 1.6.2 but with openCVTexture and ctypes_opencv from Google code.

So from my testing it was 1.7.0 that has the issue, but that seems fair enough since I don’t think it’s been tagged stable yet has it…?

I have an old Logitech QuickCam 4000, running well on Windows XP.

The call WebcamVideo.getNumOptions() returns zero, on panda version 1.6.2 and 1.5.4. Any suggestions ? Thank you !