简体   繁体   English

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

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

I'am developing a plate number detection application using opencv and c++. 我正在使用opencv和c ++开发板号检测应用程序。

For the detection trial, I want to capture real time video from my webcam using VideoCapture() function like this: 对于检测试用,我想使用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);
}

But after running the code, the video shown from my webcam is stuck, like it just showing the very first frame and then stop. 但是在运行代码之后,从我的网络摄像头显示的视频被卡住了,就像它只是显示第一帧然后停止一样。 So I can't detect anything because the video is stuck. 因此我无法检测到任何东西,因为视频卡住了。

Anyone facing the same problem? 有人面临同样的问题吗?

Generally, when reading from a camera the steps are as follows : 通常,从相机读取时, 步骤如下

  1. Open the cv::VideoCapture object and call isOpened() to verify successful open. 打开cv :: VideoCapture对象,然后调用isOpened()以验证是否成功打开。 I generally prefer declaring the capture object separately and then using open(0) to open it, but test what works for you. 我通常更喜欢分别声明捕获对象,然后使用open(0)打开它,但是请测试适合您的对象。
  2. Read a frame into a cv::Mat object. 将框架读入cv::Mat对象。 You can use read() or you could implement an approaching using the << operator 您可以使用read()或使用<<操作符来实现逼近
  3. Verify that the frame is not empty using empty() . 使用empty()验证框架是否为空。
  4. Process the image in your loop. 在循环中处理图像。

Using waitKey() 使用waitKey()

Remember that waitKey(0) will halt your program until the user presses a key. 请记住, waitKey(0)将暂停程序,直到用户按下某个键为止。 Placing waitKey(30) once at then end of your loop will display the images in the processed and queued up using imshow() . 在循环的末尾放置一次waitKey(30)将使用imshow()在已处理和排队的图像中显示图像。 You do not need to use waitKey() multiple times throughout the loop and may want to you some other timer for timing purposes. 您不需要在整个循环中多次使用waitKey() ,并且可能需要其他一些计时器来进行计时。

Possible Error Points 可能的错误点

Your code may be hanging on your first if statement. 您的代码可能挂在第一个if语句上。 You are calling cap.read(frame) back to back which may be too fast for the webcam to process... causing it to return false after the first iteration. 您正在cap.read(frame)调用cap.read(frame) ,这对于网络摄像头来说可能太快了,无法处理...导致其在第一次迭代后返回false。 Instead, try an implementation that uses frame.empty() instead to check if you have an image to process after calling cap.read(frame) . 相反,请尝试使用使用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);

Update Log: 更新日志:

  • Per @api55's comment, added the isOpened() check for completeness 根据@ api55的评论,添加了isOpened()检查是否完整
  • Added discussion for waitkey() 添加了关于waitkey()的讨论
  • Suggested commenting out sections that break the loop for now 建议注释掉暂时中断循环的部分

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

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