1 | initial version |
Sincerely I can't find any difference. Keypoints
below is my test code
/**
\brief Check for difference in frame with VideoCapture and VideoWriter using RAW encoding
*/
int VideoRawReadWriteTest()
{
std::vector<cv::Mat> framebuffer;
cv::VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
double fps = cap.get(CV_CAP_PROP_FPS); // <<<<<< GET GRABBING FPS (IF IT'S WORK)
cv::namedWindow("frame");
cv::Mat frame;
cap >> frame; // get a new frame from camera
cv::VideoWriter outputVideo;
std::string VideoName = "../bin/test_raw.avi";
int codec = 0;// <<<<<<<<<<< RAW UNCOMPRESSED CODEC REQUIRES FOURCC=0
bool isColor = (frame.type() == CV_8UC3); //<<<<<<<<<<< GRAY OR COLOR VIDEO FILE ?
outputVideo.open(VideoName, 0, fps, frame.size(), isColor);
if (!outputVideo.isOpened())
{
std::cout << "Could not open the output video for write: " << VideoName << std::endl;
return -1;
}
//--------------------------
//GRAB 10 FRAMES FROM CAMERA
int cc;
for (cc = 0; cc<10; cc++)
{
framebuffer.push_back(cv::Mat(frame.size(), frame.type())); // size and type must never change
cap >> framebuffer.back(); // grab directly into the buffer
if (framebuffer.back().empty())
{
std::cout << std::endl << "ERROR:Empty frame received!";
break;
}
outputVideo << framebuffer.back(); //save the frame into the videofile
cv::imshow("frame", frame);
if (cv::waitKey(1) >= 0) break;
}
outputVideo.release();
cap.release();
// ---------------------
// TEST FOR DIFFERENCE
cap.open(VideoName); // open the videofile
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat diff;
for (cc = 0; cc < framebuffer.size(); cc++)
{
cap >> frame; //get a frame from the videofile
if (frame.empty())
{
std::cout << std::endl << "ERROR:Empty frame in file!";
break;
}
diff = frame - framebuffer[cc]; //check for difference
if (frame.type() == CV_8UC3)
{
cvtColor(diff, diff, CV_BGR2GRAY);
}
/* show the difference image
normalize(diff, diff, 0, 255, NORM_MINMAX); //enhance differences for display
cv::imshow("Difference for frame:" + std::to_string(cc), diff);
*/
int nonZero = cv::countNonZero(diff); //count differences
std::cout << std::endl
<< "Different pixels count for frame "
<< std::to_string(cc) << ": " << nonZero;
}
std::cout << std::endl << "Press Enter to terminate "; std::cin.get();
return 0;
}
2 | No.2 Revision |
Sincerely I can't find any difference. KeypointsKeypoints:
below is my test code
/**
\brief Check for difference in frame with VideoCapture and VideoWriter using RAW encoding
*/
int VideoRawReadWriteTest()
{
std::vector<cv::Mat> framebuffer;
cv::VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
double fps = cap.get(CV_CAP_PROP_FPS); // <<<<<< GET GRABBING FPS (IF IT'S WORK)
cv::namedWindow("frame");
cv::Mat frame;
cap >> frame; // get a new frame from camera
cv::VideoWriter outputVideo;
std::string VideoName = "../bin/test_raw.avi";
int codec = 0;// <<<<<<<<<<< RAW UNCOMPRESSED CODEC REQUIRES FOURCC=0
bool isColor = (frame.type() == CV_8UC3); //<<<<<<<<<<< GRAY OR COLOR VIDEO FILE ?
outputVideo.open(VideoName, 0, codec, fps, frame.size(), isColor);
if (!outputVideo.isOpened())
{
std::cout << "Could not open the output video for write: " << VideoName << std::endl;
return -1;
}
//--------------------------
//GRAB 10 FRAMES FROM CAMERA
int cc;
for (cc = 0; cc<10; cc++)
{
framebuffer.push_back(cv::Mat(frame.size(), frame.type())); // size //size and type must never change
cap >> framebuffer.back(); // grab directly into the buffer
if (framebuffer.back().empty())
{
std::cout << std::endl << "ERROR:Empty frame received!";
break;
}
outputVideo << framebuffer.back(); //save the frame into the videofile
cv::imshow("frame", frame);
if (cv::waitKey(1) >= 0) break;
}
outputVideo.release();
cap.release();
// ---------------------
// TEST FOR DIFFERENCE
cap.open(VideoName); // open the videofile
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat diff;
for (cc = 0; cc < framebuffer.size(); cc++)
{
cap >> frame; //get a frame from the videofile
if (frame.empty())
{
std::cout << std::endl << "ERROR:Empty frame in file!";
break;
}
diff = frame - framebuffer[cc]; //check for difference
if (frame.type() == CV_8UC3)
{
cvtColor(diff, diff, CV_BGR2GRAY);
}
/* show the difference image
normalize(diff, diff, 0, 255, NORM_MINMAX); //enhance differences for display
cv::imshow("Difference for frame:" + std::to_string(cc), diff);
*/
int nonZero = cv::countNonZero(diff); //count differences
std::cout << std::endl
<< "Different pixels count for frame "
<< std::to_string(cc) << ": " << nonZero;
}
std::cout << std::endl << "Press Enter to terminate "; std::cin.get();
return 0;
}
3 | No.3 Revision |
Sincerely I can't find any difference. Keypoints:
below is my test code
/**
\brief Check for difference in frame with VideoCapture and VideoWriter using RAW encoding
*/
int VideoRawReadWriteTest()
{
std::vector<cv::Mat> framebuffer;
cv::VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
double fps = cap.get(CV_CAP_PROP_FPS); // <<<<<< GET GRABBING FPS (IF IT'S WORK)
cv::namedWindow("frame");
cv::Mat frame;
cap >> frame; // get a new frame from camera
cv::VideoWriter outputVideo;
std::string VideoName = "../bin/test_raw.avi";
int codec = 0;// <<<<<<<<<<< RAW UNCOMPRESSED CODEC REQUIRES FOURCC=0
bool isColor = (frame.type() == CV_8UC3); //<<<<<<<<<<< GRAY OR COLOR VIDEO FILE ?
outputVideo.open(VideoName, codec, fps, frame.size(), isColor);
if (!outputVideo.isOpened())
{
std::cout << "Could not open the output video for write: " << VideoName << std::endl;
return -1;
}
//--------------------------
//GRAB 10 FRAMES FROM CAMERA
int cc;
for (cc = 0; cc<10; cc++)
{
framebuffer.push_back(cv::Mat(frame.size(), frame.type())); //size and type must never change
cap >> framebuffer.back(); // grab directly into the buffer
if (framebuffer.back().empty())
{
std::cout << std::endl << "ERROR:Empty frame received!";
break;
}
outputVideo << framebuffer.back(); //save the frame into the videofile
cv::imshow("frame", frame);
if (cv::waitKey(1) >= 0) break;
}
outputVideo.release();
cap.release();
// ---------------------
// TEST FOR DIFFERENCE
cap.open(VideoName); // open the videofile
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat diff;
for (cc = 0; cc < framebuffer.size(); cc++)
{
cap >> frame; //get a frame from the videofile
if (frame.empty())
{
std::cout << std::endl << "ERROR:Empty frame in file!";
break;
}
diff = frame - framebuffer[cc]; //check for difference
cv::absdiff(frame, framebuffer[cc], diff); //dst(i) = saturate( abs( src1(i) - src2(i) ))
if (frame.type() == CV_8UC3)
{
cvtColor(diff, diff, CV_BGR2GRAY);
}
/* show the difference image
normalize(diff, diff, 0, 255, NORM_MINMAX); //enhance differences for display
cv::imshow("Difference for frame:" + std::to_string(cc), diff);
*/
int nonZero = cv::countNonZero(diff); //count differences
std::cout << std::endl
<< "Different pixels count for frame "
<< std::to_string(cc) << ": " << nonZero;
}
std::cout << std::endl << "Press Enter to terminate "; std::cin.get();
return 0;
}
4 | No.4 Revision |
Sincerely I can't find any difference. Keypoints:
below is my test code
/**
\brief Check for difference in frame with VideoCapture and VideoWriter using RAW encoding
*/
int VideoRawReadWriteTest()
{
std::vector<cv::Mat> framebuffer;
cv::VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
double fps = cap.get(CV_CAP_PROP_FPS); // <<<<<< GET GRABBING FPS (IF IT'S WORK)
cv::namedWindow("frame");
cv::Mat frame;
cap >> frame; // get a new frame from camera
cv::VideoWriter outputVideo;
std::string VideoName = "../bin/test_raw.avi";
int codec = 0;// <<<<<<<<<<< RAW UNCOMPRESSED CODEC REQUIRES FOURCC=0
bool isColor = (frame.type() == CV_8UC3); //<<<<<<<<<<< GRAY OR COLOR VIDEO FILE ?
outputVideo.open(VideoName, codec, fps, frame.size(), isColor);
if (!outputVideo.isOpened())
{
std::cout << "Could not open the output video for write: " << VideoName << std::endl;
return -1;
}
//--------------------------
//GRAB 10 FRAMES FROM CAMERA
int cc;
for (cc = 0; cc<10; cc++)
{
framebuffer.push_back(cv::Mat(frame.size(), frame.type())); //size and type must never change
cap >> framebuffer.back(); // grab directly into the buffer
if (framebuffer.back().empty())
{
std::cout << std::endl << "ERROR:Empty frame received!";
break;
}
outputVideo << framebuffer.back(); //save the frame into the videofile
cv::imshow("frame", frame);
if (cv::waitKey(1) >= 0) break;
}
outputVideo.release();
cap.release();
// ---------------------
// TEST FOR DIFFERENCE
cap.open(VideoName); // open the videofile
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat diff;
for (cc = 0; cc < framebuffer.size(); cc++)
{
cap >> frame; //get a frame from the videofile
if (frame.empty())
{
std::cout << std::endl << "ERROR:Empty frame in file!";
break;
}
//check for difference
cv::absdiff(frame, framebuffer[cc], diff); //dst(i) = saturate( abs( src1(i) - src2(i) ))
if (frame.type() == CV_8UC3)
{
cvtColor(diff, diff, CV_BGR2GRAY);
}
/* show the difference image
normalize(diff, diff, 0, 255, NORM_MINMAX); //enhance differences for display
cv::imshow("Difference for frame:" + std::to_string(cc), diff);
*/
int nonZero = cv::countNonZero(diff); //count differences
std::cout << std::endl
<< "Different pixels count for frame "
<< std::to_string(cc) << ": " << nonZero;
}
std::cout << std::endl << "Press Enter to terminate "; std::cin.get();
return 0;
}
5 | No.5 Revision |
Sincerely I can't find any difference. Keypoints:Key points:
EDIT: adding details
With fourcc=0
OpenCV doesn't use codec and stores video as frame sequence without any compression. The test confirm this on my Win7 ? Please confirm on your Mac.
Using fourcc='raw '
you are selecting a QuickTime codec (may be is Still-Image Formats ?) that could have different byte per pixel and performs some TemporalCompression... Only info I've found is The Raw Compressor is simply a conversion program that increases (pads) or reduces (decimates) the number of bits in a pixel... in this case, storing to "raw " and restoring to BGR could produce some artefacts !
Fps should not have any effect on frame quality, just change overall duration/speed in the output video file. If you grab at 20fps but create the video with fps=10 you will have slow motion at 1/2 of speed. That's why storing fps should be same as grabbing fps.
Anyway to reduce all possible variable during test I suggest to use same fps for grab and store.
Finally, if you need of 100% quality I suggest to use fourcc=0 or some LossLess codec available on Mac.
below is my test codecode:
/**
\brief Check for difference in frame with VideoCapture and VideoWriter using RAW encoding
*/
int VideoRawReadWriteTest()
{
std::vector<cv::Mat> framebuffer;
cv::VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
double fps = 20;
cap.set(CV_CAP_PROP_FPS,fps); // set wanted fps
fps = cap.get(CV_CAP_PROP_FPS); // <<<<<< GET GRABBING FPS (IF IT'S WORK)
cv::namedWindow("frame");
cv::Mat frame;
cap >> frame; // get a new frame from camera
cv::VideoWriter outputVideo;
std::string VideoName = "../bin/test_raw.avi";
int codec = 0;// <<<<<<<<<<< RAW 100% UNCOMPRESSED CODEC REQUIRES FOURCC=0
bool isColor = (frame.type() == CV_8UC3); //<<<<<<<<<<< GRAY OR COLOR VIDEO FILE ?
outputVideo.open(VideoName, codec, fps, frame.size(), isColor);
if (!outputVideo.isOpened())
{
std::cout << "Could not open the output video for write: " << VideoName << std::endl;
return -1;
}
//--------------------------
//GRAB 10 FRAMES FROM CAMERA
int cc;
for (cc = 0; cc<10; cc++)
{
framebuffer.push_back(cv::Mat(frame.size(), frame.type())); //size and type must never change
framebuffer.push_back(cv::Mat()); //Create a new empty Mat
cap >> framebuffer.back(); // grab directly into the buffer
if (framebuffer.back().empty())
{
std::cout << std::endl << "ERROR:Empty frame received!";
break;
}
outputVideo << framebuffer.back(); //save the frame into the videofile
cv::imshow("frame", frame);
framebuffer.back());
if (cv::waitKey(1) >= 0) break;
}
outputVideo.release();
cap.release();
// ---------------------
// TEST FOR DIFFERENCE
cap.open(VideoName); // open the videofile
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat diff;
for (cc = 0; cc < framebuffer.size(); cc++)
{
cap >> frame; //get a frame from the videofile
if (frame.empty())
{
std::cout << std::endl << "ERROR:Empty frame in file!";
break;
}
//check for difference
cv::absdiff(frame, framebuffer[cc], diff); //dst(i) = saturate( abs( src1(i) - src2(i) ))
if (frame.type() == CV_8UC3)
{
cvtColor(diff, diff, CV_BGR2GRAY);
}
/* show the difference image
normalize(diff, diff, 0, 255, NORM_MINMAX); //enhance differences for display
cv::imshow("Difference for frame:" + std::to_string(cc), diff);
*/
int nonZero = cv::countNonZero(diff); //count differences
std::cout << std::endl
<< "Different pixels count for frame "
<< std::to_string(cc) << ": " << nonZero;
}
std::cout << std::endl << "Press Enter to terminate "; std::cin.get();
return 0;
}