2011-03-21 83 views
4

我从我的网络摄像头(内置于HP dv5)中捕获图像时遇到问题。唯一的结果是灰色屏幕。代码如下:使用OpenCV从相机捕获灰色屏幕

#include "StdAfx.h" 
#include "cv.h" 
#include "highgui.h" 
#include <stdio.h> // A Simple Camera Capture Framework 
int main() { 
    CvCapture* capture; 
    for (int i = -1;i < 100;i++) { 
     capture = cvCaptureFromCAM(i); 
     if(!capture) { 
      fprintf(stderr, "ERROR: capture is NULL \n"); 

     } else { 
      break; 
     } 
    } 
    //cvSetCaptureProperty(capture, CV_CAP_PROP_FPS,15); 
    //cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 160); 
    //cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 120); 
    // Create a window in which the captured images will be presented 
    cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE); // Show the image captured from the camera in the window and repeat 
    while(1) {  // Get one frame  
     IplImage* frame = cvQueryFrame(capture); 
     cvGrabFrame(capture); 
     frame = cvRetrieveFrame(capture); 

     if(!frame) { 
      fprintf(stderr, "ERROR: frame is null...\n"); 
      getchar(); 
      break; 
     } else { 
      fprintf(stderr, "OK\n"); 
     } 
     cvShowImage("mywindow", frame);  // Do not release the frame!  
     //If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),  //remove higher bits using AND operator  
     int c = cvWaitKey(100); 
    } // Release the capture device housekeeping 
    cvReleaseCapture(&capture); 
    cvDestroyWindow("mywindow"); 
    return 0; 
} 

它是来自OpenCV wiki的修改代码。我知道以这种方式发现相机很疯狂,但它不适用于-1或0.我添加了一些额外的属性(已评论),但它无法正常工作。在此先感谢:) 问候, 克里斯

回答

0

这是解决您的问题的错误方法。所以我在这里:首先,隔离哪个camera_id当前正在工作。哪一个? -1,0,1?

二:请检查函数的返回值,求求你!如果有什么不对,你永远不会知道。

CvCapture* capture = NULL; 
if ((capture = cvCaptureFromCAM(-1)) == NULL) 
{ 
    fprintf(stderr, "ERROR: capture is NULL \n"); 
    return -1; 
} 

cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE); 

cvQueryFrame(capture); // Sometimes needed to get correct data 

while (1) 
{  
    IplImage* frame = cvQueryFrame(capture); // check return 
    { 
     fprintf(stderr, "ERROR: cvQueryFrame failed\n"); 
     break; 
    } 

    // At this point you already have the frame! There's no need to 
    // repeat the thing 10x with cvGrabFrame and cvRetrieveFrame. 
    // You are probably sabotaging yourself doing this multiple times. 

    cvShowImage("mywindow", frame); // Do not release the frame! 

    int key = cvWaitKey(10); 
    if (key == 0x1b) 
     break; 
}  

cvReleaseCapture(&capture); 
cvDestroyWindow("mywindow"); 

return 0; 
+0

我试图camera_id隔离,但其很奇怪......我用正确的id添加了我的循环cout,但是如果我把它放在cvCaptureFromCAM中,我就不起作用了。它只有当我把线翻倍(它没有第一次找到相机)时才起作用。当我第一次运行该程序时,它发现设备没有任何问题。 使用您的代码时,输​​出显示“错误:cvQueryFrame失败”相机与其他应用程序正常工作。我使用Win 7. – 2011-03-22 17:50:11

+0

@SyntaxError您正在使用哪种OpenCV版本? – karlphillip 2011-03-22 18:02:04

+0

2.2 - 我认为最新的。随着Visual Studio 2010. – 2011-03-22 18:20:40

1

我将图像捕捉封装到类Capture中,也许你可以试试看。下面是main.cpp中,capture.h中和capture.cpp,享受它:)

的main.cpp

#include "capture.h" 
#include <string> 
using namespace std; 

    int main(int argc, char* argv[]) { 

     // --- read file --- // 
     //Capture capture("test.wmv", windowSize, windowSize); 

     // --- read camera --- // 
     CvSize windowSize = cvSize(640, 480); 
     Capture capture(2, windowSize, windowSize); 

     while (1) { 

      capture.captureNext(); 

      for (int i = 0; i < capture.channelNum; ++i) { 

       ostringstream oss; 
       oss << i; 
       string winName = "WINDOW-" + (oss.str()); 

       cvShowImage(winName.c_str(), capture.channelframeList[i]); 

      } 

      int c = cvWaitKey(30); 
      if ((char) c == 27) { // 'Esc' to terminate 

       break; 
      } 

     } 

     return 0; 

    } 

caputure.h

#ifndef _CAPTURE_H_ 
#define _CAPTURE_H_ 

#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
#include <string> 
#include <vector> 
#include <iostream> 
using namespace std; 

enum VIDEO_TYPE { 
    CAMMERA = 0, 
    VIDEOFILE 
}; 

class Capture { 

public: 

    Capture(int num, CvSize dispSize, CvSize resolutionSize); 
    Capture(string fileName, CvSize dispSize, CvSize resolutionSize); 

    int channelNum; 
    vector<IplImage*> channelframeList; 

    void captureNext(); 

    ~Capture(); 

private: 

    string m_fileName; 
    vector<CvCapture*> m_channelList; 

    CvSize m_resolutioSize; 
    CvSize m_displaySize; 

    void initChannelList(VIDEO_TYPE type); 
    void initChannelImgList(CvSize sz); 
    IplImage* getNextVideoFrame(CvCapture* pCapture); 


}; 

#endif 

capture.cpp

#include "capture.h" 

Capture::Capture(int num, CvSize dispSize, CvSize resolutionSize) { 

    channelNum = num; 
    m_fileName = ""; 
    m_resolutioSize = resolutionSize; 

    m_channelList.resize(channelNum); 
    channelframeList.resize(channelNum); 

    initChannelList(CAMMERA); 
    initChannelImgList(dispSize); 

} 

Capture::Capture(string fileName, CvSize dispSize, CvSize resolutionSize) { 

    channelNum = 1; 
    m_fileName = fileName; 
    m_resolutioSize = resolutionSize; 

    m_channelList.resize(channelNum); 
    channelframeList.resize(channelNum); 

    initChannelList(VIDEOFILE); 
    initChannelImgList(dispSize); 

} 

void Capture::captureNext() { 

    for (int i = 0; i < channelNum; ++i) { 

     IplImage* nextFrame = getNextVideoFrame(m_channelList[i]); 
     IplImage* channelFrame = channelframeList[i]; 
     cvResize(nextFrame, channelFrame); 

    } 
} 

void Capture::initChannelList(VIDEO_TYPE type) { 

    if (type == CAMMERA) { 

     for (int i = 0; i < channelNum; ++i) { 

      m_channelList[i] = cvCreateCameraCapture(i); 

      //set resolution 
      cvSetCaptureProperty(m_channelList[i], CV_CAP_PROP_FRAME_WIDTH, m_resolutioSize.width); 
      cvSetCaptureProperty(m_channelList[i], CV_CAP_PROP_FRAME_HEIGHT, m_resolutioSize.height); 

      if (!(m_channelList[i])) { 
       cout << "failed to initialize video capture" << endl; 
       exit(EXIT_FAILURE); 

      } 
     } 

    } else if (type == VIDEOFILE) { 

     const char* fileNameChar = m_fileName.c_str(); 
     m_channelList[0] = cvCreateFileCapture(fileNameChar); 

     if (!(m_channelList[0])) { 
      cout << "failed to initialize video capture" << endl; 
      exit(EXIT_FAILURE); 
     } 

    } 

} 

void Capture::initChannelImgList(CvSize sz) { 

    for (int i = 0; i < channelNum; ++i) 
     channelframeList[i] = cvCreateImage(sz, 8, 3); 

} 

IplImage* Capture::getNextVideoFrame(CvCapture* pCapture) { 

    IplImage* nextFrame = cvQueryFrame(pCapture); 

    if (!nextFrame) { 
     cout << "failed to get a video frame" << endl; 
     exit(EXIT_FAILURE); 
    } 

    return nextFrame; 

} 

Capture::~Capture() { 

    for (int i = 0; i < channelNum; ++i) { 
     cvReleaseImage(&(channelframeList[i])); 
     cvReleaseCapture(&m_channelList[i]); 
    } 

} 
+0

我的更正之前和之后它不起作用:/ – 2011-03-23 16:01:09

+0

显示了什么错误? – 2011-03-25 16:41:02

+0

grey sreen :)但现在我使用inputVideo与opencv和一切工作正常。 – 2011-03-25 22:01:54

1

当我试图在Windows中使用摄像头和OpenCV的Python包装时,屏幕上出现灰色屏幕。

使用调试器跟踪我发现它发现了两个名为“Google相机适配器0”和“Google相机适配器1”的相机接口。

我能够通过固定摄像机输入:

  1. 要“添加/删除程序”,卸载“谷歌Talk插件”
  2. 拔掉摄像头和重新插回,让新驱动程序已安装。

它现在对我来说很好。

(请注意,我不知道第1步中是否很重要,它可能会导致其他的东西打破,所以我建议你尝试第2步第一...)