From 35c19442a781e0ada035d1c98905f99d8b073706 Mon Sep 17 00:00:00 2001 From: Alexander Reshetnikov Date: Sat, 11 Feb 2012 15:28:03 +0000 Subject: [PATCH] updated 3 highgui tests --- modules/highgui/test/test_framecount.cpp | 3 + modules/highgui/test/test_positioning.cpp | 3 + modules/highgui/test/test_video_io.cpp | 444 +++++++++++++++++++++++++++++- 3 files changed, 437 insertions(+), 13 deletions(-) diff --git a/modules/highgui/test/test_framecount.cpp b/modules/highgui/test/test_framecount.cpp index 0b473ac..095fe31 100644 --- a/modules/highgui/test/test_framecount.cpp +++ b/modules/highgui/test/test_framecount.cpp @@ -42,6 +42,7 @@ #include "test_precomp.hpp" #include "opencv2/highgui/highgui.hpp" +#include using namespace cv; using namespace std; @@ -72,6 +73,8 @@ void CV_FramecountTest::run(int) string file_path = src_dir+"video/big_buck_bunny."+ext[i]; + printf("\nReading video file in %s...\n", file_path.c_str()); + CvCapture *cap = cvCreateFileCapture(file_path.c_str()); if (!cap) { diff --git a/modules/highgui/test/test_positioning.cpp b/modules/highgui/test/test_positioning.cpp index 4d3a9f0..72b708d 100644 --- a/modules/highgui/test/test_positioning.cpp +++ b/modules/highgui/test/test_positioning.cpp @@ -42,6 +42,7 @@ #include "test_precomp.hpp" #include "opencv2/highgui/highgui.hpp" +#include using namespace cv; using namespace std; @@ -131,6 +132,8 @@ void CV_VideoPositioningTest::run_test(int method) { string file_path = src_dir + "video/big_buck_bunny." + ext[i]; + printf("\nReading video file in %s...\n", file_path.c_str()); + CvCapture* cap = cvCreateFileCapture(file_path.c_str()); if (!cap) diff --git a/modules/highgui/test/test_video_io.cpp b/modules/highgui/test/test_video_io.cpp index fd7caa1..841f98f 100644 --- a/modules/highgui/test/test_video_io.cpp +++ b/modules/highgui/test/test_video_io.cpp @@ -42,7 +42,6 @@ #include "test_precomp.hpp" #include "opencv2/highgui/highgui.hpp" - #include "stdio.h" using namespace cv; using namespace std; @@ -50,19 +49,73 @@ using namespace std; class CV_HighGuiTest : public cvtest::BaseTest { protected: - void ImagesTest(const string& dir); + void ImageTest(const string& dir); void VideoTest (const string& dir, int fourcc); + void SpecificImageTest (const string& dir); + void SpecificVideoFileTest (const string& dir, const char codecchars[4]); + void SpecificVideoCameraTest (const string& dir, const char codecchars[4]); public: + CV_HighGuiTest(); + ~CV_HighGuiTest(); + virtual void run(int) = 0; +}; + +class CV_ImageTest : public CV_HighGuiTest +{ +public: + CV_ImageTest(); + ~CV_ImageTest(); + void run(int); +}; + +class CV_SpecificImageTest : public CV_HighGuiTest +{ +public: + CV_SpecificImageTest(); + ~CV_SpecificImageTest(); void run(int); }; -class CV_PositioningTest : public cvtest::BaseTest +class CV_VideoTest : public CV_HighGuiTest { public: -void run(int); + CV_VideoTest(); + ~CV_VideoTest(); + void run(int); }; +class CV_SpecificVideoFileTest : public CV_HighGuiTest +{ +public: + CV_SpecificVideoFileTest(); + ~CV_SpecificVideoFileTest(); + void run(int); +}; + +class CV_SpecificVideoCameraTest : public CV_HighGuiTest +{ +public: + CV_SpecificVideoCameraTest(); + ~CV_SpecificVideoCameraTest(); + void run(int); +}; + +CV_HighGuiTest::CV_HighGuiTest() {} +CV_HighGuiTest::~CV_HighGuiTest() {} + +CV_ImageTest::CV_ImageTest() : CV_HighGuiTest() {} +CV_VideoTest::CV_VideoTest() : CV_HighGuiTest() {} +CV_SpecificImageTest::CV_SpecificImageTest() : CV_HighGuiTest() {} +CV_SpecificVideoFileTest::CV_SpecificVideoFileTest() : CV_HighGuiTest() {} +CV_SpecificVideoCameraTest::CV_SpecificVideoCameraTest() : CV_HighGuiTest() {} + +CV_ImageTest::~CV_ImageTest() {} +CV_VideoTest::~CV_VideoTest() {} +CV_SpecificImageTest::~CV_SpecificImageTest() {} +CV_SpecificVideoFileTest::~CV_SpecificVideoFileTest() {} +CV_SpecificVideoCameraTest::~CV_SpecificVideoCameraTest() {} + double PSNR(const Mat& m1, const Mat& m2) { Mat tmp; @@ -74,7 +127,7 @@ double PSNR(const Mat& m1, const Mat& m2) return 20 * log10(255.0 / sqrt(MSE)); } -void CV_HighGuiTest::ImagesTest(const string& dir) +void CV_HighGuiTest::ImageTest(const string& dir) { string _name = dir + string("../cv/shared/baboon.jpg"); ts->printf(ts->LOG, "reading image : %s\n", _name.c_str()); @@ -125,7 +178,7 @@ void CV_HighGuiTest::ImagesTest(const string& dir) fseek(f, 0, SEEK_SET); from_file.resize(fread(&from_file[0], 1, from_file.size(), f)); fclose(f); - + vector buf; imencode("." + exts[i], image, buf); @@ -239,37 +292,402 @@ void CV_HighGuiTest::VideoTest(const string& dir, int fourcc) ts->printf(ts->LOG, "end test function : ImagesVideo \n"); } -void CV_PositioningTest::run(int) +void CV_HighGuiTest::SpecificImageTest(const string& dir) { + const size_t IMAGE_COUNT = 10; + + for (size_t i = 0; i < IMAGE_COUNT; ++i) + { + stringstream s; s << i; + string file_path = dir+"../python/images/QCIF_0"+s.str()+".bmp"; + Mat image = imread(file_path); + + if (image.empty()) + { + ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); + return; + } + + cv::resize(image, image, cv::Size(968, 757), 0.0, 0.0, cv::INTER_CUBIC); + + stringstream s_digit; s_digit << i; + + string full_name = dir + "img_"+s_digit.str()+".bmp"; + ts->printf(ts->LOG, " full_name : %s\n", full_name.c_str()); + + imwrite(full_name, image); + + Mat loaded = imread(full_name); + if (loaded.empty()) + { + ts->printf(ts->LOG, "Reading failed at fmt=bmp\n"); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + const double thresDbell = 20; + double psnr = PSNR(loaded, image); + if (psnr < thresDbell) + { + ts->printf(ts->LOG, "Reading image from file: too big difference (=%g) with fmt=bmp\n", psnr); + ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); + continue; + } + + vector from_file; + + FILE *f = fopen(full_name.c_str(), "rb"); + fseek(f, 0, SEEK_END); + long len = ftell(f); + from_file.resize((size_t)len); + fseek(f, 0, SEEK_SET); + from_file.resize(fread(&from_file[0], 1, from_file.size(), f)); + fclose(f); + + vector buf; + imencode(".bmp", image, buf); + + if (buf != from_file) + { + ts->printf(ts->LOG, "Encoding failed with fmt=bmp\n"); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + Mat buf_loaded = imdecode(Mat(buf), 1); + + if (buf_loaded.empty()) + { + ts->printf(ts->LOG, "Decoding failed with fmt=bmp\n"); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + + psnr = PSNR(buf_loaded, image); + + if (psnr < thresDbell) + { + ts->printf(ts->LOG, "Decoding image from memory: too small PSNR (=%gdb) with fmt=bmp\n", psnr); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + continue; + } + } + ts->printf(ts->LOG, "end test function : SpecificImageTest \n"); + ts->set_failed_test_info(ts->OK); } +void CV_HighGuiTest::SpecificVideoFileTest(const string& dir, const char codecchars[4]) +{ + const string ext[] = {"avi", "mov", "mp4"/*, "mpg", "wmv"*/}; + + const size_t n = sizeof(ext)/sizeof(ext[0]); + + for (size_t j = 0; j < n; ++j) if ((ext[j]!="mp4")||(string(&codecchars[0], 4)!="IYUV")) + { + const string video_file = dir + "video_" + string(&codecchars[0], 4) + "." + ext[j]; + + VideoWriter writer; + + const size_t IMAGE_COUNT = 30; + + for(size_t i = 0; i < IMAGE_COUNT; ++i) + { + stringstream s_digit; + if (i < 10) {s_digit << "0"; s_digit << i;} + else s_digit << i; + + const string file_path = dir+"../python/images/QCIF_"+s_digit.str()+".bmp"; + + cv::Mat img = imread(file_path, CV_LOAD_IMAGE_COLOR); + + if (img.empty()) + { + ts->printf(ts->LOG, "Creating a video in %s\n", video_file.c_str()); + ts->printf(ts->LOG, "Cannot read frame in %s\n", (ts->get_data_path()+",,/python/images/QCIF_"+s_digit.str()+"."+ext[j]).c_str()); + ts->printf(ts->LOG, "Continue creating the video file...\n"); + ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); + continue; + } + + cv::resize(img, img, Size(968, 757), 0.0, 0.0, cv::INTER_CUBIC); + + for (int i = 0; i < img.rows; ++i) + for (int j = 0; j < img.cols; ++j) + if (img.at(i, j) == Vec3b::all(0)) + img.at(i, j) = Vec3b(0, 255, 0); + else img.at(i, j) = Vec3b(0, 0, 255); + + imwrite(dir+"QCIF_"+s_digit.str()+".bmp", img); + + if (!writer.isOpened()) + { + writer = cv::VideoWriter(video_file, CV_FOURCC(codecchars[0], codecchars[1], codecchars[2], codecchars[3]), 25, cv::Size(img.cols, img.rows), true); + + if (!writer.isOpened()) + { + ts->printf(ts->LOG, "Creating a video in %s\n", video_file.c_str()); + ts->printf(ts->LOG, "Cannot create VideoWriter with codec %s.\n", string(&codecchars[0], 4).c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + return; + } + } + + writer << img; + } + + writer.~VideoWriter(); -void CV_HighGuiTest::run( int /*start_from */) + cv::VideoCapture cap(video_file); + + size_t FRAME_COUNT = (size_t)cap.get(CV_CAP_PROP_FRAME_COUNT); + + if (FRAME_COUNT != IMAGE_COUNT) + { + ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", string(&codecchars[0], 4).c_str(), ext[j].c_str()); + ts->printf(ts->LOG, "Video codec: %s\n.", string(&codecchars[0], 4).c_str()); + ts->printf(ts->LOG, "Required frame count: %d; Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT); + ts->printf(ts->LOG, "Error: Incorrect frame count in the video.\n"); + ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); + continue; + } + + cap.set(CV_CAP_PROP_POS_FRAMES, -1); + + for (size_t i = -1; i < FRAME_COUNT-1; i++) + { + cv::Mat frame; cap >> frame; + if (frame.empty()) + { + ts->printf(ts->LOG, "\nError: cannot read the next frame with index %d\n", i+1); + ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); + break; + } + + stringstream s_digit; + if (i < 10) {s_digit << "0"; s_digit << i;} + else s_digit << i; + + cv::Mat img = imread(dir+"QCIF_"+s_digit.str()+".bmp", CV_LOAD_IMAGE_COLOR); + + if (img.empty()) + { + ts->printf(ts->LOG, "\nError: cannot read an image with index %d\n", i+1); + ts->set_failed_test_info(ts->FAIL_MISMATCH); + break; + } + + const double thresDbell = 20; + + double psnr = PSNR(img, frame); + + if (psnr > thresDbell) + { + ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", string(&codecchars[0], 4).c_str(), ext[j].c_str()); + ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); + ts->printf(ts->LOG, "Maximum allowed difference: %g", thresDbell); + ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); + continue; + } + + } + + cap.~VideoCapture(); + } +} + +void CV_HighGuiTest::SpecificVideoCameraTest(const string& dir, const char codecchars[4]) { - ImagesTest(ts->get_data_path()); + const string ext[] = {"avi", "mov", "mp4"/*, "mpg", "wmv"*/}; + + const size_t n = sizeof(ext)/sizeof(ext[0]); + + const int IMAGE_COUNT = 125; + + cv::VideoCapture cap(0); + + if (!cap.isOpened()) + { + ts->printf(ts->LOG, "\nError: cannot start working with device.\n"); + ts->set_failed_test_info(ts->FAIL_EXCEPTION); + return; + } + + for (size_t i = 0; i < n; ++i) if ((ext[i]!="mp4")||(string(&codecchars[0], 4)!="IYUV")) + { + Mat frame; int framecount = 0; + cv::VideoWriter writer; + + std::vector tmp_img(IMAGE_COUNT); + writer.open(dir+"video_"+string(&codecchars[0], 4)+"."+ext[i], CV_FOURCC(codecchars[0], codecchars[1], codecchars[2], codecchars[3]), 25, Size(968, 757), true); + + if (!writer.isOpened()) + { + ts->printf(ts->LOG, "\nVideo file directory: %s\n", dir.c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", std::string(&codecchars[0], 4).c_str()); + ts->printf(ts->LOG, "Error: cannot create VideoWriter object for video_%s.%s\n", string(&codecchars[0]).c_str(), ext[i].c_str()); + ts->set_failed_test_info(ts->FAIL_EXCEPTION); + continue; + } + + for (;;) + { + cap >> frame; + + if (frame.empty()) + { + ts->printf(ts->LOG, "\nVideo file directory: %s\n", dir.c_str()); + ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); + ts->printf(ts->LOG, "Frame index: %d\n", framecount); + ts->printf(ts->LOG, "Error: cannot read next frame from the device.\n"); + break; + } + + cv::resize(frame, frame, Size(968, 757), 0, 0, INTER_CUBIC); + writer << frame; tmp_img[framecount] = frame; + + framecount++; + if (framecount == IMAGE_COUNT) break; + } + + frame.~Mat(); + writer.~VideoWriter(); + + cv::VideoCapture vcap(dir+"video_"+string(&codecchars[0], 4)+"."+ext[i]); + + if (!vcap.isOpened()) + { + ts->printf(ts->LOG, "\nVideo file directory: %s\n", dir.c_str()); + ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); + ts->printf(ts->LOG, "Error: cannot open video file.\n"); + continue; + } + + int FRAME_COUNT = (int)vcap.get(CV_CAP_PROP_FRAME_COUNT); + + if (FRAME_COUNT != IMAGE_COUNT) + { + ts->printf(ts->LOG, "\nChecking frame count...\n"); + ts->printf(ts->LOG, "Video file directory: %s\n", dir.c_str()); + ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); + ts->printf(ts->LOG, "Required frame count: %d Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT); + ts->printf(ts->LOG, "Error: required and returned frame count are not matched.\n"); + ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); + continue; + } + + cv::Mat img; framecount = 0; + vcap.set(CV_CAP_PROP_POS_FRAMES, 0); + + for ( ; framecount <= std::min(FRAME_COUNT, IMAGE_COUNT); framecount++ ) + { + vcap >> img; + + if (img.empty()) + { + ts->printf(ts->LOG, "\nVideo file directory: %s\n", dir.c_str()); + ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); + ts->printf(ts->LOG, "Frame index: %d\n", framecount); + ts->printf(ts->LOG, "Error: cannot read next frame from the video.\n"); + break; + } + + const double thresDbell = 20; + double psnr = PSNR(img, tmp_img[framecount]); + + if (psnr > thresDbell) + { + ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); + ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); + ts->printf(ts->LOG, "Maximum allowed difference: %g", thresDbell); + ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); + continue; + } + } + + img.~Mat(); + vcap.~VideoCapture(); + } + + cap.~VideoCapture(); +} + +void CV_ImageTest::run(int) +{ + ImageTest(ts->get_data_path()); +} + +void CV_SpecificImageTest::run(int) +{ + SpecificImageTest(ts->get_data_path()); +} + +void CV_VideoTest::run(int) +{ #if defined WIN32 || (defined __linux__ && !defined ANDROID) -#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP +#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP const char codecs[][4] = { {'I', 'Y', 'U', 'V'}, {'X', 'V', 'I', 'D'}, {'M', 'P', 'G', '2'}, {'M', 'J', 'P', 'G'} }; - printf("%s", ts->get_data_path().c_str()); + printf("%s", ts->get_data_path().c_str()); + + int count = sizeof(codecs)/(4*sizeof(char)); + + for (int i = 0; i < count; ++i) + { + VideoTest(ts->get_data_path(), CV_FOURCC(codecs[i][0], codecs[i][1], codecs[i][2], codecs[i][3])); + } + +#endif +#endif +} + +void CV_SpecificVideoFileTest::run(int) +{ + const char codecs[][4] = { {'M', 'P', 'G', '2'}, + {'X', 'V', 'I', 'D'}, + {'M', 'J', 'P', 'G'}, + {'I', 'Y', 'U', 'V'} }; int count = sizeof(codecs)/(4*sizeof(char)); for (int i = 0; i < count; ++i) { - VideoTest(ts->get_data_path(), CV_FOURCC(codecs[i][0], codecs[i][1], codecs[i][2], codecs[i][3])); + SpecificVideoFileTest(ts->get_data_path(), codecs[i]); } +} +void CV_SpecificVideoCameraTest::run(int) +{ +#if defined WIN32 || (defined __linux__ && !defined ANDROID) +#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP + const char codecs[][4] = { {'M', 'P', 'G', '2'}, + {'X', 'V', 'I', 'D'}, + {'M', 'J', 'P', 'G'}, + {'I', 'Y', 'U', 'V'} }; + + int count = sizeof(codecs)/(4*sizeof(char)); + + for (int i = 0; i < count; ++i) + { + SpecificVideoCameraTest(ts->get_data_path(), codecs[i]); + } #endif #endif } -TEST(Highgui_HighGui, regression) { CV_HighGuiTest test; test.safe_run(); } +TEST(Highgui_Image, regression) { CV_ImageTest test; test.safe_run(); } +TEST(Highgui_Video, regression) { CV_VideoTest test; test.safe_run(); } +TEST(Highgui_SpecificImage, regression) { CV_SpecificImageTest test; test.safe_run(); } +TEST(Highgui_SpecificVideoFile, regression) { CV_SpecificVideoFileTest test; test.safe_run(); } +TEST(Highgui_SpecificVideoCamera, regression) { CV_SpecificVideoCameraTest test; test.safe_run(); } -- 2.7.4