Detect frame drop in OpenCV - opencv

How can I detect a dropped frame in OpenCV? Right now I am doing a check like the following:
int main() {
VideoCapture cap(-1);
if (!cap.isOpened()) {
cout << "Webcam is not open." << endl;
return -1;
}
Mat frame;
while (true) {
cap.read(frame);
if (!frame.empty()) {
imshow("frame", frame);
}
else {
cout << "No captured frame" << endl;
break;
}
}
}
But I still get messages saying "Camera frame dropped!" without my "No captured frame" message. What conditions result in the camera frame being dropped/how can I check for those conditions?

You can use this opencv function cap.get(CV_CAP_PROP_POS_MSEC) to obtain the presentation timestamp of a videoframe. This function returns an integer in multiples of time interval. If any frame drop, the timestamp would have skipped to (N+2)*time_interval instead of (N+1)*time_interval where N is your current frame number.

Related

Azure Kinect Recording Color Format

I'm attempting to read an Azure Kinect recording and save images from the frames. But, it is not possible to set the color_format, which causes problems when using imwrite.
I have read the recording documentation here: https://learn.microsoft.com/en-us/azure/Kinect-dk/azure-kinect-recorder.
By default, the format seems to be K4A_IMAGE_FORMAT_COLOR_MJPG. But I am unsure what parameter to pass in when creating the material. For BGRA32 it is CV_8UC4 and for depth images it is CV_16U.
I assume there are two ways to solve this problem, either by setting the color_format or figuring out what parameter is correct for the default format made by the recording.
You can access the rgb with OpenCV as if it were a normal webcam:
VideoCapture cap(0); // open the default camera
cap.set(CV_CAP_PROP_FRAME_WIDTH, 3840);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 2160);
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat frame, img;
for (;;)
{
cap >> frame; // get a new frame from camera
cout << frame.cols << " x " << frame.rows << endl;
resize(frame, img, Size(), 0.25, 0.25);
imshow("frame", img);
if (waitKey(30) >= 0) break;
}
No k4a function is called, no need to set the color format.
If you want to use their SDK with jpeg format, they provide a function in one of their sample codes:
long WriteToFile(const char *fileName, void *buffer, size_t bufferSize)
{
cout << bufferSize << endl;
assert(buffer != NULL);
std::ofstream hFile;
hFile.open(fileName, std::ios::out | std::ios::trunc | std::ios::binary);
if (hFile.is_open())
{
hFile.write((char *)buffer, static_cast<std::streamsize>(bufferSize));
hFile.close();
}
std::cout << "[Streaming Service] Color frame is stored in " << fileName << std::endl;
return 0;
}
You just call:
image = k4a_capture_get_color_image(capture);
WriteToFile("color.jpg", k4a_image_get_buffer(image), k4a_image_get_size(image));
Finally, you can set the format to RGBA32:
config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;
and convert it into a OpenCV Mat:
color_image = k4a_capture_get_color_image(capture);
if (color_image)
{
uint8_t* buffer = k4a_image_get_buffer(color_image); // get raw buffer
cv::Mat colorMat(Hrgb, Wrgb, CV_8UC4, (void*)buffer, cv::Mat::AUTO_STEP);
//do something with colorMat
k4a_image_release(color_image);
}
More details on the last option here: How to convert k4a_image_t to opencv matrix? (Azure Kinect Sensor SDK)
The data is slightly better with the last solution, but the buffer is significantly larger (33M vs ~1.5M) for 3840x2160.

Error while capturing video for a pre-defined time period

This program captures video until I press Esc. But I need to modify this program and capture video for 30s.
After recording the video it plays very fast and the video length reduces. I tried to add waitKey at the end, but it still doesn't work. After recording the video length should be the same. How can I do that? Any suggestions?
int main( int argc, const char** argv )
{
using namespace std;
using namespace cv;
VideoCapture cap(0);
while(!(cap.isOpened() && cap.grab()))
{
cout << "Camera not ready" << endl;
}
VideoWriter Writer("D:/MyVideo.avi", CV_FOURCC('P','I','M','1'),20,Size(640,480), true);
while (waitKey(30)!= 27)
{
Mat frame;
cap >> frame;
Writer.write(frame);
imshow("D:/MyVideo", frame);
}
}
int64 t0 = cv::getTickCount();
while (waitKey(30)!= 27)
{
Mat frame;
cap >> frame; // read a new frame from video
Writer.write(frame); //writer the frame into the file
double t = (cv::getTickCount() - t0) / cv::getTickFrequency();
if (t > 30)
break;
...
// now, we need to adjust to the desired framerate of 20fps,
// so we need to sleep for 1000/20 = 50 milliseconds
// either have a window, and use waitKey():
// imshow("lalala", frame);
// waitKey(50);
// or just sleep(), unfortunately system dependant ;(
// win:
// Sleep(50);
// linux, etc.:
// usleep(50);
}

ip camera foscam jpeg streaming in opencv, only reads first frame from video

I am using opencv 2.4.7, windows 7 and vc++2010 to stream mjpeg from a foscam ip camera. cap.isOpened is not null but only the first frame is displayed and breaks from loop in the second round. this is part of the code I am using:
VideoCapture cap("http://IP:PORT/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=X&pwd=Y&.mjpg"); // open the video file for reading
if ( !cap.isOpened() ) // if not success, exit program
{
std::cout << "Cannot open the video file" << std::endl;
return -1;
}
cap.set(CV_CAP_PROP_POS_MSEC, 30); //start the video at 300ms
double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
std::cout << "Frame per seconds : " << fps << std::endl;
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
int cnt=0;
Mat frame;
for(;;)
{
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
std::cout << "Cannot read the frame from video file" << std::endl;
break;
}
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if(waitKey(33) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
std::cout << "esc key is pressed by user" << std::endl;
break;
}
}
}
I appreciate any help in advance.
look at your url:
"IP:PORT/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=X&pwd=Y&.mjpg"
snapPicture2 looks suspicious, no ?
i'm pretty sure, there's no problem with your opencv code,
it's more like the url you choose only retrieves 1 frame
please lookup your manual for the correct stream url
http://www.ispyconnect.com/man.aspx?n=foscam

using cvRetrieveFrame get strange image

I am reading a avi file, and do some background subtrcation work. The wierd thing is when I use cvRetrieveFrame, I got a strange image, like below:
origin:
cvRetrieveFrame returns:
I don't know what's the problem. Here is my code snippet.
CvCapture* readerAvi = cvCaptureFromAVI( filename.c_str() );
if(readerAvi == NULL)
{
std::cerr << "Could not open AVI file." << std::endl;
return 0;
}
// retrieve information about AVI file
cvQueryFrame(readerAvi); //....get some information, width, height, ....
// grad next frame from input video stream
if(!cvGrabFrame(readerAvi))
{
std::cerr << "Could not grab AVI frame." << std::endl;
return 0;
}
frame_data = cvRetrieveFrame(readerAvi);

After reading multiple frames from a camera, OpenCV suddenly always fails to read frames. How do I diagnose this?

I run a program similar to the one in this question: https://stackoverflow.com/a/8719192/26070
#include <opencv/highgui.h>
#include <iostream>
/** #function main */
int main( int argc, char** argv )
{
cv::VideoCapture vcap;
cv::Mat image;
const std::string videoStreamAddress = "rtsp://192.0.0.1:8081/live.sdp";
//open the video stream and make sure it's opened
if(!vcap.open(videoStreamAddress)) {
std::cout << "Error opening video stream or file" << std::endl;
return -1;
}
for(;;) {
if(!vcap.read(image)) {
std::cout << "No frame" << std::endl;
cv::waitKey(500);
} else {
cv::imshow("Output Window", image);
}
if(cv::waitKey(1) >= 0) break;
}
}
The program runs fine for a certain amount of time (about one minute or so) and then the call to read() (method from cv::VideoCapture) always returns false.
The output is as follows:
[mpeg4 # 00da27a0] ac-tex damaged at 22 7
[mpeg4 # 00da27a0] Error at MB: 309
No frame
No frame
No frame
Note: the first two lines are not always present.
So, how can I determine what the root of the problem is?

Resources