简体   繁体   English

OpenCV:如何在Windows窗体应用程序中显示网络摄像头捕获?

[英]OpenCV : How to display webcam capture in windows form application?

generally we display webcam or video motion in opencv windows with : 通常我们在opencv窗口中显示网络摄像头或视频动作:

      CvCapture* capture = cvCreateCameraCapture(0);
            cvNamedWindow( "title", CV_WINDOW_AUTOSIZE );
   cvMoveWindow("title",x,y);
   while(1) 
   {
    frame = cvQueryFrame( capture );
    if( !frame )
    {
     break;
    }
    cvShowImage( "title", frame );
    char c = cvWaitKey(33);
    if( c == 27 )
    {
     break;
    }
   }

i tried to use pictureBox that is successful to display image in windows form with this : 我尝试使用成功以windows形式显示图像的pictureBox:

 pictureBox1->Image = gcnew System::Drawing::Bitmap( image->width,image->height,image->widthStep,System::Drawing::Imaging::PixelFormat::Undefined, ( System::IntPtr ) image-> imageData);

but when im trying to display captured image from video it wont works, here is the source : 但是当我试图从视频中显示捕获的图像它不会起作用时,这里是源:

            CvCapture* capture = cvCreateCameraCapture(0);
   while(1) 
   {
    frame = cvQueryFrame( capture );
    if( !frame )
    {
     break;
    }
    pictureBox1->Image = gcnew System::Drawing::Bitmap( frame->width,frame->height,frame->widthStep,System::Drawing::Imaging::PixelFormat::Undefined, ( System::IntPtr ) frame-> imageData);
    char c = cvWaitKey(33);
    if( c == 27 )
    {
     break;
    }
   }

is there anyway to use windows form instead opencv windows to show video or webcam? 无论如何使用Windows窗体而不是opencv窗口来显示视频或网络摄像头?

or is there something wrong with my code? 或者我的代码有问题吗? thanks for your help.. :) 谢谢你的帮助.. :)

Piece of advice : use VideoInput instead of CvCapture (CvCapture is a part of highgui a library that is not intended for production use, but just for quick testing). 建议:使用VideoInput而不是CvCapture(CvCapture是highgui库的一部分,不是用于生产用途,而是用于快速测试)。 Yes the VideoInput homepage looks strange, but the library is quite worthwhile. 是的VideoInput主页看起来很奇怪,但是这个库非常值得。

Here is a quick sample for the usage of VideoInput (extracted from the VideoInput.h file): 以下是VideoInput用法的快速示例(从VideoInput.h文件中提取):

//create a videoInput object
videoInput VI;

//Prints out a list of available devices and returns num of devices found
int numDevices = VI.listDevices();  

int device1 = 0;  //this could be any deviceID that shows up in listDevices
int device2 = 1;  //this could be any deviceID that shows up in listDevices

//if you want to capture at a different frame rate (default is 30) 
//specify it here, you are not guaranteed to get this fps though.
//VI.setIdealFramerate(dev, 60);    

//setup the first device - there are a number of options:

VI.setupDevice(device1);                          //setup the first device with the default settings
//VI.setupDevice(device1, VI_COMPOSITE);              //or setup device with specific connection type
//VI.setupDevice(device1, 320, 240);                  //or setup device with specified video size
//VI.setupDevice(device1, 320, 240, VI_COMPOSITE);  //or setup device with video size and connection type

//VI.setFormat(device1, VI_NTSC_M);                 //if your card doesn't remember what format it should be
                                                    //call this with the appropriate format listed above
                                                    //NOTE: must be called after setupDevice!

//optionally setup a second (or third, fourth ...) device - same options as above
VI.setupDevice(device2);                          

//As requested width and height can not always be accomodated
//make sure to check the size once the device is setup

int width   = VI.getWidth(device1);
int height  = VI.getHeight(device1);
int size    = VI.getSize(device1);

unsigned char * yourBuffer1 = new unsigned char[size];
unsigned char * yourBuffer2 = new unsigned char[size];

//to get the data from the device first check if the data is new
if(VI.isFrameNew(device1)){
    VI.getPixels(device1, yourBuffer1, false, false);   //fills pixels as a BGR (for openCV) unsigned char array - no flipping
    VI.getPixels(device1, yourBuffer2, true, true);     //fills pixels as a RGB (for openGL) unsigned char array - flipping!
}

//same applies to device2 etc

//to get a settings dialog for the device
VI.showSettingsWindow(device1);


//Shut down devices properly
VI.stopDevice(device1);
VI.stopDevice(device2);

The pixel format should be known when you capture images from a camera, it's very likely the format of 24-bit BGR. 从相机捕获图像时应该知道像素格式,它很可能是24位BGR的格式。 System::Drawing::Imaging::PixelFormat::Format24bppRgb will be the closest format but you might get weird color display. System::Drawing::Imaging::PixelFormat::Format24bppRgb将是最接近的格式,但您可能会得到奇怪的颜色显示。 A re-arrange of the color component will solve this problem. 重新排列颜色组件将解决此问题。

Actually, there are .net version opencv library available here: http://code.google.com/p/opencvdotnet/ and here: http://www.emgu.com/wiki/index.php/Main_Page 实际上,这里有.net版本的opencv库: http//code.google.com/p/opencvdotnet/ ,这里: http//www.emgu.com/wiki/index.php/Main_Page

Hope it helps! 希望能帮助到你!

I don't know if you will like this, but you could use OpenGL to show the video stream in other windows than the ones provided with opencv. 我不知道你是否会喜欢这个,但你可以使用OpenGL在其他窗口中显示视频流,而不是opencv提供的视频流。 (Capture the frame and display it on a rectangle.. or something like that..) (捕捉框架并将其显示在矩形......或类似的东西......)

Another option you might want to consider is using emgu. 您可能要考虑的另一个选项是使用emgu。 This is a .Net wrapper for opencv with winforms controlls. 这是一个带有winforms控件的opencv的.Net包装器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM