Get the count of cameras( Problem and Solution )
Posted: 19 March 2011 07:14 AM   [ Ignore ]
Avatar
Rank
Joined  2011-01-19
Total Posts:  35
New Member

++++++++++++++++++++
+ PROBLEM
++++++++++++++++++++
A few days ago, when i clicked the [Next camera] button in CCV 1.4, the screen freezed with no more camera for “next”.
Then i checked the code of the method(ofxNCoreVision::handleGui() in gui.h file):

case sourcePanel_nextCam:
            if(
length == sizeof(bool))
            
{
                
if(*(bool*)data)
                
{
                    
if(bcamera && vidGrabber != NULL){
                        deviceID 
+= 1;    // <-- [1]
                          
vidGrabber->close();
                        
vidGrabber->setDeviceID(deviceID);   // <--[2]
                        
vidGrabber->setVerbose(false);
                        
vidGrabber->initGrabber(camWidth,camHeight);
                        
filter->exposureStartTime ofGetElapsedTimeMillis();
                        
filter_fiducial->exposureStartTime ofGetElapsedTimeMillis();
                    
}
                }
            }
            
break;

As the mark[1] shows, the deviceID pluses one. And then setDeviceID - mark[2].
What if there are no more cameras? maybe it is this that made the freezing happen.

So, what we need is to get the count of the cameras.
And in Windows platform, the getDeviceCount() method of CameraUtils class uses the code below to get the count:

#ifdef OF_VIDEO_CAPTURE_DIRECTSHOW
         return VI.devicesFound;
#endif

but using the test code below in the end of ofxNCoreVision::_setup:

CameraUtils util;
printf"Camera Count: %d\n"util.getDeviceCount() );

it prints:

***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****
Camera Count: 0

But at the beginning of the output, it prints:

SETUP: Looking For Capture Devices
SETUP: 0) HP Webcam [2 MP Fixed]
SETUP: 1) PS3Eye Camera
SETUP: 2 Device(s) found

So there must be some mistakes.

Profile
 
 
Posted: 19 March 2011 07:21 AM   [ Ignore ]   [ # 1 ]
Avatar
Rank
Joined  2011-01-19
Total Posts:  35
New Member

++++++++++++++++++++++++++++++
+ SOLUTION:
++++++++++++++++++++++++++++++
<ul>
<li>videoInput lib:
<ol>
<li>Go to http://muonics.net/school/spring05/videoInput/, download the lib and src</a>.</li>
<li>Unzip the file, open videoInput.sln(\videoInputSrcAndDemos\VC2008-videoInputcompileAsLib) by VS2008.</li>
<li>Add new public method int getCameraCount(); in videoInput.h</li>
<li>Add the definition of the method in videoInput.cpp:

int videoInput::getCameraCount() {
    
return this->getDeviceCount();
}

<li>Build the solution and get the videoInput.lib file.

You may need the follow links as references:
<ul>
<li>http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35AEDA01-421D-4BA5-B44B-543DC8C33A20</li>
<li>http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=3021d52b-514e-41d3-ad02-438a3ba730ba</li>
<li>http://opencv.willowgarage.com/wiki/faq#WhenItrytobuildoneoftheapps.2CIgetanerror.2Cstreams.hnotfound.</li>
<li>http://social.msdn.microsoft.com/forums/en-US/windowssdk/thread/ed097d2c-3d68-4f48-8448-277eaaf68252/</li>
</ul>

</li>
</ol>
</li>
<li>CameraUtils.h file:
<ol>
<li>Copy the new videoInput.lib file to [CCV folder]\libs\videoInput\lib\vs2008\ , replace the older one.</li>
<li>Copy the new videoInput.h file to [CCV folder]\libs\videoInput\include , replace the older one.</li>
<li>Open the CameraUtils.h file, and change the getDeviceCount method,
from:

#ifdef OF_VIDEO_CAPTURE_DIRECTSHOW
//---------------------------------
        return VI.devicesFound;
//---------------------------------
#endif

to

#ifdef OF_VIDEO_CAPTURE_DIRECTSHOW
//---------------------------------
        return VI.getCameraCount();
//---------------------------------
#endif

</li>
<li>Rebuild the CCV solution, and test the code:

CameraUtils util;
printf"Camera Count: %d\n"util.getDeviceCount() );

it prints:

***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****

Camera Count: 2

</li>
<li>it works!</li>
</ol>
</li>
<li>“Next Camera” code
<ol>
<li>Change the handleGui method in gui.h file,
from:

case sourcePanel_nextCam:
            if(
length == sizeof(bool))
            
{
                
if(*(bool*)data)
                
{
                    
if(bcamera && vidGrabber != NULL){
                        deviceID 
+= 1;
                          
vidGrabber->close();
                        
vidGrabber->setDeviceID(deviceID);
                        
vidGrabber->setVerbose(false);
                        
vidGrabber->initGrabber(camWidth,camHeight);
                        
filter->exposureStartTime ofGetElapsedTimeMillis();
                        
filter_fiducial->exposureStartTime ofGetElapsedTimeMillis();
                    
}
                }
            }
            
break;

to:

case sourcePanel_nextCam:
            if(
length == sizeof(bool))
            
{
                
if(*(bool*)data)
                
{
                    
if(bcamera && vidGrabber != NULL){
                        deviceID
++;
                        if ( 
deviceID >= getCameraCount() ) {  // you can definite the method in ofxNCoreVision by yourself.
                            
deviceID getCameraCount() - 1;
                            break;
                        
}
                        
if ( deviceID {
                            deviceID 
0;
                        
else {
                            vidGrabber
->close();
                            
vidGrabber->setDeviceID(deviceID);
                            
vidGrabber->setVerbose(false);
                            
vidGrabber->initGrabber(camWidth,camHeight);
                            
filter->exposureStartTime ofGetElapsedTimeMillis();
                            
filter_fiducial->exposureStartTime ofGetElapsedTimeMillis();
                        
}
                    }
                }
            }
            
break;

</li>
<li>and change the “previous camera” code,
from:

case sourcePanel_previousCam:
            if(
length == sizeof(bool))
            
{
                
if(*(bool*)data)
                
{
                    
if(bcamera && vidGrabber != NULL)
                    
{
                        deviceID 
-= 1;
                        if(
deviceID 0{
                            deviceID 
0;
                        
}
                        else{
                            vidGrabber
->close();
                            
vidGrabber->setDeviceID(deviceID);
                            
vidGrabber->setVerbose(false);
                            
vidGrabber->initGrabber(camWidth,camHeight);
                            
filter->exposureStartTime ofGetElapsedTimeMillis();
                            
filter_fiducial->exposureStartTime ofGetElapsedTimeMillis();
                        
}
                    }
                }
            }
            
break;

to:

case sourcePanel_previousCam:
            if(
length == sizeof(bool))
            
{
                
if(*(bool*)data)
                
{
                    
if(bcamera && vidGrabber != NULL)
                    
{
                        deviceID 
-= 1;
                        if( 
deviceID >= getCameraCount() ) {    // if the XML file setting fault.
                            
deviceID getCameraCount() - 1;
                        
}
                        
if (deviceID 0{
                            deviceID 
0;
                        
} else{
                            vidGrabber
->close();
                            
vidGrabber->setDeviceID(deviceID);
                            
vidGrabber->setVerbose(false);
                            
vidGrabber->initGrabber(camWidth,camHeight);
                            
filter->exposureStartTime ofGetElapsedTimeMillis();
                            
filter_fiducial->exposureStartTime ofGetElapsedTimeMillis();
                        
}
                    }
                }
            }
            
break;

</li>
</ol>
</li>
</ul>

P.S. there is another way to get the count of camera, using the return value of listDevices() method in videoInput class.

but this will print the list every time. if you do not want to compile the videoInput library by yourself, you can use the listDevices() method. smile

Profile