Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Sincerely I can't find any difference. Keypoints

  • the codec for RAW format is 0
  • the videofile should be created using same FPS as grabbing
  • the videofile must gray or color as grabbing

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;
}

Sincerely I can't find any difference. KeypointsKeypoints:

  • the codec for RAW format is 00 (zero)
  • the videofile should be created using same FPS as grabbing
  • the videofile must be gray or color as grabbing

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;
}

Sincerely I can't find any difference. Keypoints:

  • the codec for RAW format is 0 (zero)
  • the videofile should be created using same FPS as grabbing
  • the videofile must be gray or color as grabbing

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;
}

Sincerely I can't find any difference. Keypoints:

  • the codec FOURCC for RAW format uncompressed video is 0 (zero)
  • the videofile should be created using same FPS as grabbing
  • the videofile must be gray or color as grabbing

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;
}

Sincerely I can't find any difference. Keypoints:Key points:

  • the FOURCC for uncompressed video is 0 (zero)
  • the videofile should be created using same FPS as grabbing
  • the videofile must be gray or color as grabbing

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;
}