繁体   English   中英

在C ++中使用OpenCV捕获实时视频?

[英]Capturing real time video with opencv in c++?

我正在使用opencv和c ++开发板号检测应用程序。

对于检测试用,我想使用VideoCapture()函数从网络摄像头捕获实时视频,如下所示:

int main(void)
{
  // input image
  cv::Mat imgOriginalScene;      

  cv::VideoCapture cap = cv::VideoCapture(0); 

  for (;;) {
    cv::Mat frame;
    cap.read(frame);
    double timestamp = cap.get(CV_CAP_PROP_POS_MSEC);

    if (cap.read(frame)) {
      imgOriginalScene = frame;
      cv::Size size(1000, 600);
      resize(imgOriginalScene, imgOriginalScene, size);

      if (imgOriginalScene.empty()) {              
        std::cout << "error: image not read from file\n\n";   
        return(0);                        
      }

      std::vector<PossiblePlate> vectorOfPossiblePlates = 
          detectPlatesInScene(imgOriginalScene);    
      vectorOfPossiblePlates = detectCharsInPlates(vectorOfPossiblePlates);                 

      cv::imshow("imgOriginalScene", imgOriginalScene);      

      if (vectorOfPossiblePlates.empty()) {                         
        std::cout << std::endl << "no license plates were detected" << std::endl;    
      }
      else {                                      
        std::sort(vectorOfPossiblePlates.begin(), vectorOfPossiblePlates.end(), 
            PossiblePlate::sortDescendingByNumberOfChars);

        // suppose the plate with the most recognized chars
        // (the first plate in sorted by string length descending order) 
        // is the actual plate
        PossiblePlate licPlate = vectorOfPossiblePlates.front();

        cv::imshow("imgPlate", licPlate.imgPlate);      
        cv::imshow("imgThresh", licPlate.imgThresh);

        // if no chars were found in the plate
        if (licPlate.strChars.length() == 0) {                            
          // show message
          std::cout << std::endl << "no characters were detected" << std::endl << std::endl;    
        }

        // draw red rectangle around plate
        drawRedRectangleAroundPlate(imgOriginalScene, licPlate);        

        // write license plate text to std out
        std::cout << std::endl << "license plate read from image = " << licPlate.strChars << std::endl;   
        std::cout << std::endl << "-----------------------------------------" << std::endl;
        outfile << licPlate.strChars << "  " << timestamp / 1000 << " Detik" << std::endl;

        // write license plate text on the image
        writeLicensePlateCharsOnImage(imgOriginalScene, licPlate);        

        // re-show scene image
        cv::imshow("imgOriginalScene", imgOriginalScene);             

        // write image out to file
        cv::imwrite("imgOriginalScene.png", imgOriginalScene);          
      }
      cvWaitKey(34);
    }
    else {
      cap.set(CV_CAP_PROP_POS_FRAMES, 1.0);
      cvWaitKey(1000);
    }
    if (cap.get(CV_CAP_PROP_POS_FRAMES) == cap.get(CV_CAP_PROP_FRAME_COUNT)) {
      break;
    }
  }

  outfile.close();

  // hold windows open until user presses a key
  cv::waitKey(0);         

  return(0);
}

但是在运行代码之后,从我的网络摄像头显示的视频被卡住了,就像它只是显示第一帧然后停止一样。 因此我无法检测到任何东西,因为视频卡住了。

有人面临同样的问题吗?

通常,从相机读取时, 步骤如下

  1. 打开cv :: VideoCapture对象,然后调用isOpened()以验证是否成功打开。 我通常更喜欢分别声明捕获对象,然后使用open(0)打开它,但是请测试适合您的对象。
  2. 将框架读入cv::Mat对象。 您可以使用read()或使用<<操作符来实现逼近
  3. 使用empty()验证框架是否为空。
  4. 在循环中处理图像。

使用waitKey()

请记住, waitKey(0)将暂停程序,直到用户按下某个键为止。 在循环的末尾放置一次waitKey(30)将使用imshow()在已处理和排队的图像中显示图像。 您不需要在整个循环中多次使用waitKey() ,并且可能需要其他一些计时器来进行计时。

可能的错误点

您的代码可能挂在第一个if语句上。 您正在cap.read(frame)调用cap.read(frame) ,这对于网络摄像头来说可能太快了,无法处理...导致其在第一次迭代后返回false。 相反,请尝试使用使用frame.empty()的实现,在调用cap.read(frame)之后检查是否有要处理的图像。

cv::Mat imgOriginalScene;           // input image

cv::VideoCapture cap = cv::VideoCapture(0); 

if(!cap.isOpened()){
    cerr << "Error Opening Capture Device" << endl; //Use cerr for basic debugging statements
    return -1;
}

for (;;) {
    cv::Mat frame;
    cap.read(frame);
    double timestamp = cap.get(CV_CAP_PROP_POS_MSEC);

    if (frame.empty()) {
         /*... do something ...*/
    }
    else {
        cap.set(CV_CAP_PROP_POS_FRAMES, 1.0);
        cvWaitKey(1000);
    }
     //Try removing this for debug...
/*
    if (cap.get(CV_CAP_PROP_POS_FRAMES) == cap.get(CV_CAP_PROP_FRAME_COUNT)) {
        //break;

    }
*/  
    cv::waitKey(0);                 // hold windows open until user presses a key
}

outfile.close();
cv::waitKey(0);                 // hold windows open until user presses a key

return(0);

更新日志:

  • 根据@ api55的评论,添加了isOpened()检查是否完整
  • 添加了关于waitkey()的讨论
  • 建议注释掉暂时中断循环的部分

暂无
暂无

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

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