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

发布于 2024-09-01 22:57:12 字数 1266 浏览 6 评论 0原文

通常我们在 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;
    }
   }

我尝试使用 pictureBox 成功地以窗口形式显示图像:

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

但是当我尝试显示从视频中捕获的图像时,它不起作用,这里是来源:

            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;
    }
   }

有吗无论如何使用 Windows 窗体而不是 opencv Windows 来显示视频或网络摄像头?

或者我的代码有问题吗? 感谢您的帮助.. :)

generally we display webcam or video motion in opencv windows with :

      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 :

 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?

or is there something wrong with my code?
thanks for your help.. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

榕城若虚 2024-09-08 22:57:12

一条建议:使用 VideoInput 而不是 CvCapture (CvCapture 是 highgui 库的一部分,不适用于生产用途,仅用于快速测试)。是的,VideoInput 主页看起来很奇怪,但是这个库非常值得。

以下是 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);

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). Yes the VideoInput homepage looks strange, but the library is quite worthwhile.

Here is a quick sample for the usage of VideoInput (extracted from the VideoInput.h file):

//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);
始终不够 2024-09-08 22:57:12

当您从相机捕获图像时,应该知道像素格式,它很可能是 24 位 BGR 的格式。 System::Drawing::Imaging::PixelFormat::Format24bppRgb 将是最接近的格式,但您可能会得到奇怪的颜色显示。重新排列颜色分量将解决这个问题。

实际上,这里有.net版本的opencv库:
http://code.google.com/p/opencvdotnet/
在这里:
http://www.emgu.com/wiki/index.php/Main_Page

希望有帮助!

The pixel format should be known when you capture images from a camera, it's very likely the format of 24-bit BGR. System::Drawing::Imaging::PixelFormat::Format24bppRgb will be the closest format but you might get weird color display. 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

Hope it helps!

昨迟人 2024-09-08 22:57:12

我不知道你是否会喜欢这个,但是你可以使用 OpenGL 在 opencv 提供的窗口之外的其他窗口中显示视频流。 (捕获帧并将其显示在矩形上..或类似的东西..)

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. (Capture the frame and display it on a rectangle.. or something like that..)

月光色 2024-09-08 22:57:12

您可能要考虑的另一个选择是使用 emgu。这是带有 winforms 控件的 opencv 的 .Net 包装器。

Another option you might want to consider is using emgu. This is a .Net wrapper for opencv with winforms controlls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文