From 87b569d8127fe68e15a3f1ae91fb55e0e21b7afb Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Tue, 6 Jun 2017 20:22:30 +0300 Subject: [PATCH] Rewritten some tests in videoio and imgcodecs modules general: - all iterative tests have been replaced with parameterized tests - old-style try..catch tests have been modified to use EXPECT_/ASSERT_ gtest macros - added temporary files cleanup - modified MatComparator error message formatting imgcodecs: - test_grfmt.cpp split to test_jpg.cpp, test_png.cpp, test_tiff.cpp, etc. videoio: - added public HAVE_VIDEO_INPUT, HAVE_VIDEO_OUTPUT definitions to cvconfig.h - built-in MotionJPEG codec could not be tested on some platforms (read_write test was disabled if ffmpeg is off, encoding/decoding was handled by ffmpeg otherwise). - image-related tests moved to imgcodecs (Videoio_Image) - several property get/set tests have been combined into one - added MotionJPEG test video to opencv_extra --- cmake/templates/cvconfig.h.in | 20 + modules/cudabgsegm/perf/perf_bgsegm.cpp | 19 +- modules/cudabgsegm/test/test_bgsegm.cpp | 15 +- modules/cudacodec/perf/perf_video.cpp | 15 +- modules/cudalegacy/perf/perf_bgsegm.cpp | 17 +- modules/imgcodecs/test/test_grfmt.cpp | 1050 ++++---------------------- modules/imgcodecs/test/test_jpeg.cpp | 180 +++++ modules/imgcodecs/test/test_png.cpp | 95 +++ modules/imgcodecs/test/test_precomp.hpp | 7 +- modules/imgcodecs/test/test_read_write.cpp | 122 +++ modules/imgcodecs/test/test_tiff.cpp | 202 +++++ modules/imgcodecs/test/test_webp.cpp | 106 +++ modules/superres/test/test_precomp.hpp | 13 - modules/superres/test/test_superres.cpp | 4 +- modules/ts/src/ts_func.cpp | 6 +- modules/video/perf/opencl/perf_bgfg_mog2.cpp | 19 +- modules/video/test/ocl/test_bgfg_mog2.cpp | 17 +- modules/videoio/perf/perf_input.cpp | 33 +- modules/videoio/perf/perf_output.cpp | 43 +- modules/videoio/perf/perf_precomp.hpp | 29 - modules/videoio/src/cap.cpp | 5 - modules/videoio/src/precomp.hpp | 1 - modules/videoio/test/test_basic_props.cpp | 157 ---- modules/videoio/test/test_framecount.cpp | 114 --- modules/videoio/test/test_positioning.cpp | 223 ------ modules/videoio/test/test_precomp.hpp | 83 +- modules/videoio/test/test_video_io.cpp | 676 +++++------------ modules/videoio/test/test_video_pos.cpp | 179 ----- 28 files changed, 1134 insertions(+), 2316 deletions(-) create mode 100644 modules/imgcodecs/test/test_jpeg.cpp create mode 100644 modules/imgcodecs/test/test_png.cpp create mode 100644 modules/imgcodecs/test/test_read_write.cpp create mode 100644 modules/imgcodecs/test/test_tiff.cpp create mode 100644 modules/imgcodecs/test/test_webp.cpp delete mode 100644 modules/videoio/test/test_basic_props.cpp delete mode 100644 modules/videoio/test/test_framecount.cpp delete mode 100644 modules/videoio/test/test_positioning.cpp delete mode 100644 modules/videoio/test/test_video_pos.cpp diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index 754409a..12a1ff1 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -217,6 +217,26 @@ /* OpenVX */ #cmakedefine HAVE_OPENVX +#if defined(HAVE_XINE) || \ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_QTKIT) || \ + defined(HAVE_AVFOUNDATION) || \ + /*defined(HAVE_OPENNI) || too specialized */ \ + defined(HAVE_FFMPEG) || \ + defined(HAVE_MSMF) +#define HAVE_VIDEO_INPUT +#endif + +#if /*defined(HAVE_XINE) || */\ + defined(HAVE_GSTREAMER) || \ + defined(HAVE_QUICKTIME) || \ + defined(HAVE_QTKIT) || \ + defined(HAVE_AVFOUNDATION) || \ + defined(HAVE_FFMPEG) || \ + defined(HAVE_MSMF) +#define HAVE_VIDEO_OUTPUT +#endif #endif // OPENCV_CVCONFIG_H_INCLUDED diff --git a/modules/cudabgsegm/perf/perf_bgsegm.cpp b/modules/cudabgsegm/perf/perf_bgsegm.cpp index 48bda4a..21d03bc 100644 --- a/modules/cudabgsegm/perf/perf_bgsegm.cpp +++ b/modules/cudabgsegm/perf/perf_bgsegm.cpp @@ -46,23 +46,10 @@ using namespace std; using namespace testing; using namespace perf; -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(WIN32) /* assume that we have ffmpeg */ - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - ////////////////////////////////////////////////////// // MOG -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT DEF_PARAM_TEST(Video_Cn_LearningRate, string, MatCn, double); @@ -167,7 +154,7 @@ PERF_TEST_P(Video_Cn_LearningRate, MOG, ////////////////////////////////////////////////////// // MOG2 -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT DEF_PARAM_TEST(Video_Cn, string, int); @@ -324,7 +311,7 @@ PERF_TEST_P(Video_Cn, DISABLED_MOG2, ////////////////////////////////////////////////////// // MOG2GetBackgroundImage -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage, Combine(Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi"), diff --git a/modules/cudabgsegm/test/test_bgsegm.cpp b/modules/cudabgsegm/test/test_bgsegm.cpp index 9c463c3..a30cb1e 100644 --- a/modules/cudabgsegm/test/test_bgsegm.cpp +++ b/modules/cudabgsegm/test/test_bgsegm.cpp @@ -46,23 +46,10 @@ using namespace cvtest; -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(WIN32) /* assume that we have ffmpeg */ - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - ////////////////////////////////////////////////////// // MOG2 -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT namespace { diff --git a/modules/cudacodec/perf/perf_video.cpp b/modules/cudacodec/perf/perf_video.cpp index 7c3439e..3ccb79b 100644 --- a/modules/cudacodec/perf/perf_video.cpp +++ b/modules/cudacodec/perf/perf_video.cpp @@ -47,25 +47,12 @@ using namespace std; using namespace testing; using namespace perf; -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(WIN32) /* assume that we have ffmpeg */ - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - DEF_PARAM_TEST_1(FileName, string); ////////////////////////////////////////////////////// // VideoReader -#if defined(HAVE_NVCUVID) && BUILD_WITH_VIDEO_INPUT_SUPPORT +#if defined(HAVE_NVCUVID) && defined(HAVE_VIDEO_INPUT) PERF_TEST_P(FileName, VideoReader, Values("gpu/video/768x576.avi", "gpu/video/1920x1080.avi")) { diff --git a/modules/cudalegacy/perf/perf_bgsegm.cpp b/modules/cudalegacy/perf/perf_bgsegm.cpp index 4367910..58f859f 100644 --- a/modules/cudalegacy/perf/perf_bgsegm.cpp +++ b/modules/cudalegacy/perf/perf_bgsegm.cpp @@ -50,23 +50,10 @@ using namespace std; using namespace testing; using namespace perf; -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(WIN32) /* assume that we have ffmpeg */ - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - ////////////////////////////////////////////////////// // FGDStatModel -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT DEF_PARAM_TEST_1(Video, string); @@ -136,7 +123,7 @@ PERF_TEST_P(Video, FGDStatModel, ////////////////////////////////////////////////////// // GMG -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT DEF_PARAM_TEST(Video_Cn_MaxFeatures, string, MatCn, int); diff --git a/modules/imgcodecs/test/test_grfmt.cpp b/modules/imgcodecs/test/test_grfmt.cpp index faca3d7..64a0c1e 100644 --- a/modules/imgcodecs/test/test_grfmt.cpp +++ b/modules/imgcodecs/test/test_grfmt.cpp @@ -42,979 +42,185 @@ #include "test_precomp.hpp" -#include -#include -#include - using namespace cv; using namespace std; +using namespace std::tr1; -static -bool mats_equal(const Mat& lhs, const Mat& rhs) -{ - if (lhs.channels() != rhs.channels() || - lhs.depth() != rhs.depth() || - lhs.size().height != rhs.size().height || - lhs.size().width != rhs.size().width) - { - return false; - } +typedef tuple File_Mode; +typedef testing::TestWithParam Imgcodecs_FileMode; - Mat diff = (lhs != rhs); - const Scalar s = sum(diff); - for (int i = 0; i < s.channels; ++i) - { - if (s[i] != 0) - { - return false; - } - } +TEST_P(Imgcodecs_FileMode, regression) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string filename = root + get<0>(GetParam()); + const int mode = get<1>(GetParam()); - return true; -} + const Mat single = imread(filename, mode); + ASSERT_FALSE(single.empty()); -static -bool imread_compare(const string& filepath, int flags = IMREAD_COLOR) -{ vector pages; - if (!imreadmulti(filepath, pages, flags) || - pages.empty()) - { - return false; - } - - const Mat single = imread(filepath, flags); - return mats_equal(single, pages[0]); + ASSERT_TRUE(imreadmulti(filename, pages, mode)); + ASSERT_FALSE(pages.empty()); + const Mat page = pages[0]; + ASSERT_FALSE(page.empty()); + + EXPECT_EQ(page.channels(), single.channels()); + EXPECT_EQ(page.depth(), single.depth()); + EXPECT_EQ(page.size().height, single.size().height); + EXPECT_EQ(page.size().width, single.size().width); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), page, single); } -TEST(Imgcodecs_imread, regression) +const string all_images[] = { - const char* const filenames[] = - { #ifdef HAVE_JASPER - "Rome.jp2", + "readwrite/Rome.jp2", + "readwrite/Bretagne2.jp2", + "readwrite/Bretagne2.jp2", + "readwrite/Grey.jp2", + "readwrite/Grey.jp2", #endif #ifdef HAVE_GDCM - "int16-mono1.dcm", - "uint8-mono2.dcm", - "uint16-mono2.dcm", - "uint8-rgb.dcm", + "readwrite/int16-mono1.dcm", + "readwrite/uint8-mono2.dcm", + "readwrite/uint16-mono2.dcm", + "readwrite/uint8-rgb.dcm", #endif - "color_palette_alpha.png", - "multipage.tif", - "rle.hdr", - "ordinary.bmp", - "rle8.bmp", - "test_1_c1.jpg" - }; - - const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; - - for (size_t i = 0; i < sizeof(filenames) / sizeof(filenames[0]); ++i) - { - const string path = folder + string(filenames[i]); - ASSERT_TRUE(imread_compare(path, IMREAD_UNCHANGED)); - ASSERT_TRUE(imread_compare(path, IMREAD_GRAYSCALE)); - ASSERT_TRUE(imread_compare(path, IMREAD_COLOR)); - ASSERT_TRUE(imread_compare(path, IMREAD_ANYDEPTH)); - ASSERT_TRUE(imread_compare(path, IMREAD_ANYCOLOR)); - const string ext = path.substr( path.length() - 3 ); - if ( ext != "hdr" && ext != "dcm" ) - { - // GDAL does not support hdr nor dcm - ASSERT_TRUE(imread_compare(path, IMREAD_LOAD_GDAL)); - } - } -} - -template -string to_string(T i) -{ - stringstream ss; - string s; - ss << i; - s = ss.str(); - - return s; -} - - -/** - * Test for check whether reading exif orientation tag was processed successfully or not - * The test info is the set of 8 images named testExifRotate_{1 to 8}.jpg - * The test image is the square 10x10 points divided by four sub-squares: - * (R corresponds to Red, G to Green, B to Blue, W to white) - * --------- --------- - * | R | G | | G | R | - * |-------| - (tag 1) |-------| - (tag 2) - * | B | W | | W | B | - * --------- --------- - * - * --------- --------- - * | W | B | | B | W | - * |-------| - (tag 3) |-------| - (tag 4) - * | G | R | | R | G | - * --------- --------- - * - * --------- --------- - * | R | B | | G | W | - * |-------| - (tag 5) |-------| - (tag 6) - * | G | W | | R | B | - * --------- --------- - * - * --------- --------- - * | W | G | | B | R | - * |-------| - (tag 7) |-------| - (tag 8) - * | B | R | | W | G | - * --------- --------- - * - * - * Every image contains exif field with orientation tag (0x112) - * After reading each image the corresponding matrix must be read as - * --------- - * | R | G | - * |-------| - * | B | W | - * --------- - * - */ -class CV_GrfmtJpegExifOrientationTest : public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - for( int i = 1; i <= 8; ++i) - { - string fileName = "readwrite/testExifOrientation_" + to_string(i) + ".jpg"; - m_img = imread(string(ts->get_data_path()) + fileName); - if( !m_img.data ) - { - ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA); - } - ts->printf(cvtest::TS::LOG, "start reading image\t%s\n", fileName.c_str()); - if( !checkOrientation() ) - { - ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); - } - } - - } - catch(...) - { - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); - } - } -private: - bool checkOrientation(); - Mat m_img; + "readwrite/color_palette_alpha.png", + "readwrite/multipage.tif", + "readwrite/ordinary.bmp", + "readwrite/rle8.bmp", + "readwrite/test_1_c1.jpg", + "readwrite/rle.hdr" }; - -bool CV_GrfmtJpegExifOrientationTest::checkOrientation() +const int basic_modes[] = { - Vec3b vec; - int red = 0; - int green = 0; - int blue = 0; - - const int colorThresholdHigh = 250; - const int colorThresholdLow = 5; - - //Checking the first quadrant (with supposed red) - vec = m_img.at(2, 2); //some point inside the square - red = vec.val[2]; - green = vec.val[1]; - blue = vec.val[0]; - - ts->printf(cvtest::TS::LOG, "RED QUADRANT:\n"); - ts->printf(cvtest::TS::LOG, "Red calculated:\t\t%d\n", red); - ts->printf(cvtest::TS::LOG, "Green calculated:\t%d\n", green); - ts->printf(cvtest::TS::LOG, "Blue calculated:\t%d\n", blue); - if( red < colorThresholdHigh ) return false; - if( blue > colorThresholdLow ) return false; - if( green > colorThresholdLow ) return false; - - //Checking the second quadrant (with supposed green) - vec = m_img.at(2, 7); //some point inside the square - red = vec.val[2]; - green = vec.val[1]; - blue = vec.val[0]; - ts->printf(cvtest::TS::LOG, "GREEN QUADRANT:\n"); - ts->printf(cvtest::TS::LOG, "Red calculated:\t\t%d\n", red); - ts->printf(cvtest::TS::LOG, "Green calculated:\t%d\n", green); - ts->printf(cvtest::TS::LOG, "Blue calculated:\t%d\n", blue); - if( green < colorThresholdHigh ) return false; - if( red > colorThresholdLow ) return false; - if( blue > colorThresholdLow ) return false; - - //Checking the third quadrant (with supposed blue) - vec = m_img.at(7, 2); //some point inside the square - red = vec.val[2]; - green = vec.val[1]; - blue = vec.val[0]; - ts->printf(cvtest::TS::LOG, "BLUE QUADRANT:\n"); - ts->printf(cvtest::TS::LOG, "Red calculated:\t\t%d\n", red); - ts->printf(cvtest::TS::LOG, "Green calculated:\t%d\n", green); - ts->printf(cvtest::TS::LOG, "Blue calculated:\t%d\n", blue); - if( blue < colorThresholdHigh ) return false; - if( red > colorThresholdLow ) return false; - if( green > colorThresholdLow ) return false; - - return true; -} - -TEST(Imgcodecs_jpeg_exif, setOrientation) -{ - CV_GrfmtJpegExifOrientationTest test; - test.safe_run(); -} - -#ifdef HAVE_JASPER -TEST(Imgcodecs_jasper, regression) -{ - const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; - - ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_COLOR)); - ASSERT_TRUE(imread_compare(folder + "Bretagne2.jp2", IMREAD_GRAYSCALE)); - ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_COLOR)); - ASSERT_TRUE(imread_compare(folder + "Grey.jp2", IMREAD_GRAYSCALE)); -} -#endif - -class CV_GrfmtWriteBigImageTest : public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - ts->printf(cvtest::TS::LOG, "start reading big image\n"); - Mat img = imread(string(ts->get_data_path()) + "readwrite/read.png"); - ts->printf(cvtest::TS::LOG, "finish reading big image\n"); - if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - ts->printf(cvtest::TS::LOG, "start writing big image\n"); - imwrite(cv::tempfile(".png"), img); - ts->printf(cvtest::TS::LOG, "finish writing big image\n"); - } - catch(...) - { - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); - } - ts->set_failed_test_info(cvtest::TS::OK); - } + IMREAD_UNCHANGED, + IMREAD_GRAYSCALE, + IMREAD_COLOR, + IMREAD_ANYDEPTH, + IMREAD_ANYCOLOR }; -string ext_from_int(int ext) -{ -#ifdef HAVE_PNG - if (ext == 0) return ".png"; -#endif - if (ext == 1) return ".bmp"; - if (ext == 2) return ".pgm"; -#ifdef HAVE_TIFF - if (ext == 3) return ".tiff"; -#endif - if (ext == 4) return ".pam"; - return ""; -} - -class CV_GrfmtWriteSequenceImageTest : public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - const int img_r = 640; - const int img_c = 480; - - for (int k = 1; k <= 5; ++k) - { - for (int ext = 0; ext < 5; ++ext) // 0 - png, 1 - bmp, 2 - pgm, 3 - tiff - { - if(ext_from_int(ext).empty()) - continue; - for (int num_channels = 1; num_channels <= 4; num_channels++) - { - if (num_channels == 2) continue; - if (num_channels == 4 && ext!=3 /*TIFF*/) continue; - - ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str()); - Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); - circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), std::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); +INSTANTIATE_TEST_CASE_P(All, Imgcodecs_FileMode, + testing::Combine( + testing::ValuesIn(all_images), + testing::ValuesIn(basic_modes))); - string img_path = cv::tempfile(ext_from_int(ext).c_str()); - ts->printf(ts->LOG, "writing image : %s\n", img_path.c_str()); - imwrite(img_path, img); - - ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str()); - Mat img_test = imread(img_path, IMREAD_UNCHANGED); - - if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); - - CV_Assert(img.size() == img_test.size()); - CV_Assert(img.type() == img_test.type()); - CV_Assert(num_channels == img_test.channels()); - - double n = cvtest::norm(img, img_test, NORM_L2); - if ( n > 1.0) - { - ts->printf(ts->LOG, "norm = %f \n", n); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - } - } - } - -#ifdef HAVE_JPEG - for (int num_channels = 1; num_channels <= 3; num_channels+=2) - { - // jpeg - ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ".jpg"); - Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0)); - circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), std::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); - - string filename = cv::tempfile(".jpg"); - imwrite(filename, img); - ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str()); - Mat img_test = imread(filename, IMREAD_UNCHANGED); - - if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); - - CV_Assert(img.size() == img_test.size()); - CV_Assert(img.type() == img_test.type()); - - // JPEG format does not provide 100% accuracy - // using fuzzy image comparison - double n = cvtest::norm(img, img_test, NORM_L1); - double expected = 0.05 * img.size().area(); - if ( n > expected) - { - ts->printf(ts->LOG, "norm = %f > expected = %f \n", n, expected); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - } - } -#endif - -#ifdef HAVE_TIFF - for (int num_channels = 1; num_channels <= 4; num_channels++) - { - if (num_channels == 2) continue; - // tiff - ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_16U, num_channels, ".tiff"); - Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_16U, num_channels), Scalar::all(0)); - circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), std::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255)); - - string filename = cv::tempfile(".tiff"); - imwrite(filename, img); - ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str()); - Mat img_test = imread(filename, IMREAD_UNCHANGED); - - if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH); - - CV_Assert(img.size() == img_test.size()); - - ts->printf(ts->LOG, "img : %d ; %d \n", img.channels(), img.depth()); - ts->printf(ts->LOG, "img_test : %d ; %d \n", img_test.channels(), img_test.depth()); - - CV_Assert(img.type() == img_test.type()); - - - double n = cvtest::norm(img, img_test, NORM_L2); - if ( n > 1.0) - { - ts->printf(ts->LOG, "norm = %f \n", n); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - } - } -#endif - } - } - catch(const cv::Exception & e) - { - ts->printf(ts->LOG, "Exception: %s\n" , e.what()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - } - } -}; - -class CV_GrfmtReadBMPRLE8Test : public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - Mat rle = imread(string(ts->get_data_path()) + "readwrite/rle8.bmp"); - Mat bmp = imread(string(ts->get_data_path()) + "readwrite/ordinary.bmp"); - if (cvtest::norm(rle-bmp, NORM_L2)>1.e-10) - ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); - } - catch(...) - { - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); - } - ts->set_failed_test_info(cvtest::TS::OK); - } -}; - - -#ifdef HAVE_PNG -TEST(Imgcodecs_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); } -#endif - -TEST(Imgcodecs_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); } - -TEST(Imgcodecs_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); } - -#ifdef HAVE_PNG -class CV_GrfmtPNGEncodeTest : public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - vector buff; - Mat im = Mat::zeros(1000,1000, CV_8U); - //randu(im, 0, 256); - vector param; - param.push_back(IMWRITE_PNG_COMPRESSION); - param.push_back(3); //default(3) 0-9. - cv::imencode(".png" ,im ,buff, param); - - // hangs - Mat im2 = imdecode(buff,IMREAD_ANYDEPTH); - } - catch(...) - { - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); - } - ts->set_failed_test_info(cvtest::TS::OK); +// GDAL does not support "hdr", "dcm" and have problems with "jp2" +struct notForGDAL { + bool operator()(const string &name) const { + const string &ext = name.substr(name.size() - 3, 3); + return ext == "hdr" || ext == "dcm" || ext == "jp2"; } }; -TEST(Imgcodecs_Image, encode_png) { CV_GrfmtPNGEncodeTest test; test.safe_run(); } - -TEST(Imgcodecs_ImreadVSCvtColor, regression) +inline vector gdal_images() { - cvtest::TS& ts = *cvtest::TS::ptr(); - - const int MAX_MEAN_DIFF = 1; - const int MAX_ABS_DIFF = 10; - - string imgName = string(ts.get_data_path()) + "/../cv/shared/lena.png"; - Mat original_image = imread(imgName); - Mat gray_by_codec = imread(imgName, 0); - Mat gray_by_cvt; - - cvtColor(original_image, gray_by_cvt, CV_BGR2GRAY); - - Mat diff; - absdiff(gray_by_codec, gray_by_cvt, diff); - - double actual_avg_diff = (double)mean(diff)[0]; - double actual_maxval, actual_minval; - minMaxLoc(diff, &actual_minval, &actual_maxval); - //printf("actual avg = %g, actual maxdiff = %g, npixels = %d\n", actual_avg_diff, actual_maxval, (int)diff.total()); - - EXPECT_LT(actual_avg_diff, MAX_MEAN_DIFF); - EXPECT_LT(actual_maxval, MAX_ABS_DIFF); + vector res; + back_insert_iterator< vector > it(res); + remove_copy_if(all_images, all_images + sizeof(all_images)/sizeof(all_images[0]), it, notForGDAL()); + return res; } -//Test OpenCV issue 3075 is solved -class CV_GrfmtReadPNGColorPaletteWithAlphaTest : public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - // First Test : Read PNG with alpha, imread flag -1 - Mat img = imread(string(ts->get_data_path()) + "readwrite/color_palette_alpha.png",-1); - if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - - ASSERT_TRUE(img.channels() == 4); - - unsigned char* img_data = img.ptr(); - - // Verification first pixel is red in BGRA - ASSERT_TRUE(img_data[0] == 0x00); - ASSERT_TRUE(img_data[1] == 0x00); - ASSERT_TRUE(img_data[2] == 0xFF); - ASSERT_TRUE(img_data[3] == 0xFF); - - // Verification second pixel is red in BGRA - ASSERT_TRUE(img_data[4] == 0x00); - ASSERT_TRUE(img_data[5] == 0x00); - ASSERT_TRUE(img_data[6] == 0xFF); - ASSERT_TRUE(img_data[7] == 0xFF); - - // Second Test : Read PNG without alpha, imread flag -1 - img = imread(string(ts->get_data_path()) + "readwrite/color_palette_no_alpha.png",-1); - if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - - ASSERT_TRUE(img.channels() == 3); - - img_data = img.ptr(); - - // Verification first pixel is red in BGR - ASSERT_TRUE(img_data[0] == 0x00); - ASSERT_TRUE(img_data[1] == 0x00); - ASSERT_TRUE(img_data[2] == 0xFF); - - // Verification second pixel is red in BGR - ASSERT_TRUE(img_data[3] == 0x00); - ASSERT_TRUE(img_data[4] == 0x00); - ASSERT_TRUE(img_data[5] == 0xFF); - - // Third Test : Read PNG with alpha, imread flag 1 - img = imread(string(ts->get_data_path()) + "readwrite/color_palette_alpha.png",1); - if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - - ASSERT_TRUE(img.channels() == 3); - - img_data = img.ptr(); +INSTANTIATE_TEST_CASE_P(GDAL, Imgcodecs_FileMode, + testing::Combine( + testing::ValuesIn(gdal_images()), + testing::Values(IMREAD_LOAD_GDAL))); - // Verification first pixel is red in BGR - ASSERT_TRUE(img_data[0] == 0x00); - ASSERT_TRUE(img_data[1] == 0x00); - ASSERT_TRUE(img_data[2] == 0xFF); +//================================================================================================== - // Verification second pixel is red in BGR - ASSERT_TRUE(img_data[3] == 0x00); - ASSERT_TRUE(img_data[4] == 0x00); - ASSERT_TRUE(img_data[5] == 0xFF); +typedef tuple Ext_Size; +typedef testing::TestWithParam Imgcodecs_ExtSize; - // Fourth Test : Read PNG without alpha, imread flag 1 - img = imread(string(ts->get_data_path()) + "readwrite/color_palette_no_alpha.png",1); - if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - - ASSERT_TRUE(img.channels() == 3); - - img_data = img.ptr(); - - // Verification first pixel is red in BGR - ASSERT_TRUE(img_data[0] == 0x00); - ASSERT_TRUE(img_data[1] == 0x00); - ASSERT_TRUE(img_data[2] == 0xFF); - - // Verification second pixel is red in BGR - ASSERT_TRUE(img_data[3] == 0x00); - ASSERT_TRUE(img_data[4] == 0x00); - ASSERT_TRUE(img_data[5] == 0xFF); - } - catch(...) - { - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); - } - ts->set_failed_test_info(cvtest::TS::OK); - } -}; - -TEST(Imgcodecs_Image, read_png_color_palette_with_alpha) { CV_GrfmtReadPNGColorPaletteWithAlphaTest test; test.safe_run(); } -#endif - -#ifdef HAVE_JPEG -TEST(Imgcodecs_Jpeg, encode_empty) -{ - cv::Mat img; - std::vector jpegImg; - - ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception); -} - -TEST(Imgcodecs_Jpeg, encode_decode_progressive_jpeg) -{ - cvtest::TS& ts = *cvtest::TS::ptr(); - string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - std::vector params; - params.push_back(IMWRITE_JPEG_PROGRESSIVE); - params.push_back(1); - - string output_progressive = cv::tempfile(".jpg"); - EXPECT_NO_THROW(cv::imwrite(output_progressive, img, params)); - cv::Mat img_jpg_progressive = cv::imread(output_progressive); - - string output_normal = cv::tempfile(".jpg"); - EXPECT_NO_THROW(cv::imwrite(output_normal, img)); - cv::Mat img_jpg_normal = cv::imread(output_normal); - - EXPECT_EQ(0, cvtest::norm(img_jpg_progressive, img_jpg_normal, NORM_INF)); - - remove(output_progressive.c_str()); -} - -TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg) -{ - cvtest::TS& ts = *cvtest::TS::ptr(); - string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - std::vector params; - params.push_back(IMWRITE_JPEG_OPTIMIZE); - params.push_back(1); - - string output_optimized = cv::tempfile(".jpg"); - EXPECT_NO_THROW(cv::imwrite(output_optimized, img, params)); - cv::Mat img_jpg_optimized = cv::imread(output_optimized); - - string output_normal = cv::tempfile(".jpg"); - EXPECT_NO_THROW(cv::imwrite(output_normal, img)); - cv::Mat img_jpg_normal = cv::imread(output_normal); - - EXPECT_EQ(0, cvtest::norm(img_jpg_optimized, img_jpg_normal, NORM_INF)); - - remove(output_optimized.c_str()); -} - -TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg) -{ - cvtest::TS& ts = *cvtest::TS::ptr(); - string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - std::vector params; - params.push_back(IMWRITE_JPEG_RST_INTERVAL); - params.push_back(1); - - string output_rst = cv::tempfile(".jpg"); - EXPECT_NO_THROW(cv::imwrite(output_rst, img, params)); - cv::Mat img_jpg_rst = cv::imread(output_rst); - - string output_normal = cv::tempfile(".jpg"); - EXPECT_NO_THROW(cv::imwrite(output_normal, img)); - cv::Mat img_jpg_normal = cv::imread(output_normal); - - EXPECT_EQ(0, cvtest::norm(img_jpg_rst, img_jpg_normal, NORM_INF)); - - remove(output_rst.c_str()); -} - -#endif - - -#ifdef HAVE_TIFF - -// these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h -#define uint64 uint64_hack_ -#define int64 int64_hack_ -#include "tiff.h" - -#ifdef ANDROID -// Test disabled as it uses a lot of memory. -// It is killed with SIGKILL by out of memory killer. -TEST(Imgcodecs_Tiff, DISABLED_decode_tile16384x16384) -#else -TEST(Imgcodecs_Tiff, decode_tile16384x16384) -#endif +TEST_P(Imgcodecs_ExtSize, write_imageseq) { - // see issue #2161 - cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0)); - string file3 = cv::tempfile(".tiff"); - string file4 = cv::tempfile(".tiff"); + const string ext = get<0>(GetParam()); + const Size size = get<1>(GetParam()); + const Point2i center = Point2i(size.width / 2, size.height / 2); + const int radius = std::min(size.height, size.width / 4); - std::vector params; - params.push_back(TIFFTAG_ROWSPERSTRIP); - params.push_back(big.rows); - cv::imwrite(file4, big, params); - cv::imwrite(file3, big.colRange(0, big.cols - 1), params); - big.release(); - - try - { - cv::imread(file3, IMREAD_UNCHANGED); - EXPECT_NO_THROW(cv::imread(file4, IMREAD_UNCHANGED)); - } - catch(const std::bad_alloc&) - { - // have no enough memory - } - - remove(file3.c_str()); - remove(file4.c_str()); -} - -TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian) -{ - // see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness" - - // Setup data for two minimal 16-bit grayscale TIFF files in both endian formats - uchar tiff_sample_data[2][86] = { { - // Little endian - 0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01, - 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, - 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, { - // Big endian - 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00, - 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, - 0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x04 } - }; - - // Test imread() for both a little endian TIFF and big endian TIFF - for (int i = 0; i < 2; i++) + for (int cn = 1; cn <= 4; cn++) { - string filename = cv::tempfile(".tiff"); + SCOPED_TRACE(format("channels %d", cn)); + if (cn == 2) + continue; + if (cn == 4 && ext != ".tiff") + continue; + string filename = cv::tempfile(format("%d%s", cn, ext.c_str()).c_str()); - // Write sample TIFF file - FILE* fp = fopen(filename.c_str(), "wb"); - ASSERT_TRUE(fp != NULL); - ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp)); - fclose(fp); + Mat img_gt(size, CV_MAKETYPE(CV_8U, cn), Scalar::all(0)); + circle(img_gt, center, radius, Scalar::all(255)); + ASSERT_TRUE(imwrite(filename, img_gt)); Mat img = imread(filename, IMREAD_UNCHANGED); + ASSERT_FALSE(img.empty()); + EXPECT_EQ(img.size(), img.size()); + EXPECT_EQ(img.type(), img.type()); + EXPECT_EQ(cn, img.channels()); - EXPECT_EQ(1, img.rows); - EXPECT_EQ(2, img.cols); - EXPECT_EQ(CV_16U, img.type()); - EXPECT_EQ(sizeof(ushort), img.elemSize()); - EXPECT_EQ(1, img.channels()); - EXPECT_EQ(0xDEAD, img.at(0,0)); - EXPECT_EQ(0xBEEF, img.at(0,1)); - - remove(filename.c_str()); - } -} - -class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest -{ -public: - void run(int) - { - try - { - /* see issue #3472 - dealing with tiled images where the tile size is - * not a multiple of image size. - * The tiled images were created with 'convert' from ImageMagick, - * using the command 'convert -define tiff:tile-geometry=128x128 -depth [8|16] - * Note that the conversion to 16 bits expands the range from 0-255 to 0-255*255, - * so the test converts back but rounding errors cause small differences. - */ - cv::Mat img = imread(string(ts->get_data_path()) + "readwrite/non_tiled.tif",-1); - if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - ASSERT_TRUE(img.channels() == 3); - cv::Mat tiled8 = imread(string(ts->get_data_path()) + "readwrite/tiled_8.tif", -1); - if (tiled8.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, tiled8); - - cv::Mat tiled16 = imread(string(ts->get_data_path()) + "readwrite/tiled_16.tif", -1); - if (tiled16.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - ASSERT_TRUE(tiled16.elemSize() == 6); - tiled16.convertTo(tiled8, CV_8UC3, 1./256.); - ASSERT_PRED_FORMAT2(cvtest::MatComparator(2, 0), img, tiled8); - // What about 32, 64 bit? - } - catch(...) + if (ext == ".jpg") { - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); + // JPEG format does not provide 100% accuracy + // using fuzzy image comparison + double n = cvtest::norm(img, img_gt, NORM_L1); + double expected = 0.07 * img.size().area(); + EXPECT_LT(n, expected); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(10, 0), img, img_gt); } - ts->set_failed_test_info(cvtest::TS::OK); - } -}; - -TEST(Imgcodecs_Tiff, decode_tile_remainder) -{ - CV_GrfmtReadTifTiledWithNotFullTiles test; test.safe_run(); -} - -TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip) -{ - const uchar sample_data[142] = { - 0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x54, - 0x56, 0x5a, 0x59, 0x55, 0x5a, 0x00, 0x0a, 0x00, 0x00, 0x01, - 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, - 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, - 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x03, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 - }; - - const string filename = cv::tempfile(".tiff"); - std::ofstream outfile(filename.c_str(), std::ofstream::binary); - outfile.write(reinterpret_cast(sample_data), sizeof sample_data); - outfile.close(); - - EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED)); - - remove(filename.c_str()); -} - -class CV_GrfmtReadTifMultiPage : public cvtest::BaseTest -{ -private: - void compare(int flags) - { - const string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; - const int page_count = 6; - - vector pages; - bool res = imreadmulti(folder + "multipage.tif", pages, flags); - ASSERT_TRUE(res == true); - ASSERT_EQ(static_cast(page_count), pages.size()); - - for (int i = 0; i < page_count; i++) + else { - char buffer[256]; - sprintf(buffer, "%smultipage_p%d.tif", folder.c_str(), i + 1); - const string filepath(buffer); - const Mat page = imread(filepath, flags); - ASSERT_TRUE(mats_equal(page, pages[i])); + double n = cvtest::norm(img, img_gt, NORM_L2); + EXPECT_LT(n, 1.); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt); } + remove(filename.c_str()); } - -public: - void run(int) - { - compare(IMREAD_UNCHANGED); - compare(IMREAD_GRAYSCALE); - compare(IMREAD_COLOR); - compare(IMREAD_ANYDEPTH); - compare(IMREAD_ANYCOLOR); - // compare(IMREAD_LOAD_GDAL); // GDAL does not support multi-page TIFFs - } -}; - -TEST(Imgcodecs_Tiff, decode_multipage) -{ - CV_GrfmtReadTifMultiPage test; test.safe_run(); } -TEST(Imgcodecs_Tiff, imdecode_no_exception_temporary_file_removed) +const string all_exts[] = { - cvtest::TS& ts = *cvtest::TS::ptr(); - string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - std::vector buf; - EXPECT_NO_THROW(cv::imencode(".tiff", img, buf)); - - EXPECT_NO_THROW(cv::imdecode(buf, IMREAD_UNCHANGED)); -} - +#ifdef HAVE_PNG + ".png", #endif +#ifdef HAVE_TIFF + ".tiff", +#endif +#ifdef HAVE_JPEG + ".jpg", +#endif + ".bmp", + ".pgm", + ".pam" +}; -#ifdef HAVE_WEBP - -TEST(Imgcodecs_WebP, encode_decode_lossless_webp) +vector all_sizes() { - cvtest::TS& ts = *cvtest::TS::ptr(); - string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - string output = cv::tempfile(".webp"); - EXPECT_NO_THROW(cv::imwrite(output, img)); // lossless - - cv::Mat img_webp = cv::imread(output); - - std::vector buf; - - FILE * wfile = NULL; - - wfile = fopen(output.c_str(), "rb"); - if (wfile != NULL) - { - fseek(wfile, 0, SEEK_END); - size_t wfile_size = ftell(wfile); - fseek(wfile, 0, SEEK_SET); - - buf.resize(wfile_size); - - size_t data_size = fread(&buf[0], 1, wfile_size, wfile); - - if(wfile) - { - fclose(wfile); - } - - if (data_size != wfile_size) - { - EXPECT_TRUE(false); - } - } - - remove(output.c_str()); - - cv::Mat decode = cv::imdecode(buf, IMREAD_COLOR); - ASSERT_FALSE(decode.empty()); - EXPECT_TRUE(cvtest::norm(decode, img_webp, NORM_INF) == 0); - - ASSERT_FALSE(img_webp.empty()); - - EXPECT_TRUE(cvtest::norm(img, img_webp, NORM_INF) == 0); + vector res; + for (int k = 1; k <= 5; ++k) + res.push_back(Size(640 * k, 480 * k)); + return res; } -TEST(Imgcodecs_WebP, encode_decode_lossy_webp) -{ - cvtest::TS& ts = *cvtest::TS::ptr(); - std::string input = std::string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - for(int q = 100; q>=0; q-=20) - { - std::vector params; - params.push_back(IMWRITE_WEBP_QUALITY); - params.push_back(q); - string output = cv::tempfile(".webp"); +INSTANTIATE_TEST_CASE_P(All, Imgcodecs_ExtSize, + testing::Combine( + testing::ValuesIn(all_exts), + testing::ValuesIn(all_sizes()))); - EXPECT_NO_THROW(cv::imwrite(output, img, params)); - cv::Mat img_webp = cv::imread(output); - remove(output.c_str()); - EXPECT_FALSE(img_webp.empty()); - EXPECT_EQ(3, img_webp.channels()); - EXPECT_EQ(512, img_webp.cols); - EXPECT_EQ(512, img_webp.rows); - } -} +//================================================================================================== -TEST(Imgcodecs_WebP, encode_decode_with_alpha_webp) +TEST(Imgcodecs_Bmp, read_rle8) { - cvtest::TS& ts = *cvtest::TS::ptr(); - std::string input = std::string(ts.get_data_path()) + "../cv/shared/lena.png"; - cv::Mat img = cv::imread(input); - ASSERT_FALSE(img.empty()); - - std::vector imgs; - cv::split(img, imgs); - imgs.push_back(cv::Mat(imgs[0])); - imgs[imgs.size() - 1] = cv::Scalar::all(128); - cv::merge(imgs, img); - - string output = cv::tempfile(".webp"); - - EXPECT_NO_THROW(cv::imwrite(output, img)); - cv::Mat img_webp = cv::imread(output); - remove(output.c_str()); - EXPECT_FALSE(img_webp.empty()); - EXPECT_EQ(4, img_webp.channels()); - EXPECT_EQ(512, img_webp.cols); - EXPECT_EQ(512, img_webp.rows); + const string root = cvtest::TS::ptr()->get_data_path(); + Mat rle = imread(root + "readwrite/rle8.bmp"); + ASSERT_FALSE(rle.empty()); + Mat ord = imread(root + "readwrite/ordinary.bmp"); + ASSERT_FALSE(ord.empty()); + EXPECT_LE(cvtest::norm(rle, ord, NORM_L2), 1.e-10); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), rle, ord); } -#endif - TEST(Imgcodecs_Hdr, regression) { string folder = string(cvtest::TS::ptr()->get_data_path()) + "/readwrite/"; @@ -1038,9 +244,10 @@ TEST(Imgcodecs_Hdr, regression) minMaxLoc(abs(img_rle - written_img), &min, &max); ASSERT_FALSE(max > DBL_EPSILON); } + remove(tmp_file_name.c_str()); } -TEST(Imgcodecs_Pam, readwrite) +TEST(Imgcodecs_Pam, read_write) { string folder = string(cvtest::TS::ptr()->get_data_path()) + "readwrite/"; string filepath = folder + "lena.pam"; @@ -1062,4 +269,7 @@ TEST(Imgcodecs_Pam, readwrite) EXPECT_EQ(0, cvtest::norm(reread, reread_no_param, NORM_INF)); EXPECT_EQ(0, cvtest::norm(img, reread, NORM_INF)); + + remove(writefile.c_str()); + remove(writefile_no_param.c_str()); } diff --git a/modules/imgcodecs/test/test_jpeg.cpp b/modules/imgcodecs/test/test_jpeg.cpp new file mode 100644 index 0000000..5546f2d --- /dev/null +++ b/modules/imgcodecs/test/test_jpeg.cpp @@ -0,0 +1,180 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; +using namespace std::tr1; + +#ifdef HAVE_JPEG + +/** + * Test for check whether reading exif orientation tag was processed successfully or not + * The test info is the set of 8 images named testExifRotate_{1 to 8}.jpg + * The test image is the square 10x10 points divided by four sub-squares: + * (R corresponds to Red, G to Green, B to Blue, W to white) + * --------- --------- + * | R | G | | G | R | + * |-------| - (tag 1) |-------| - (tag 2) + * | B | W | | W | B | + * --------- --------- + * + * --------- --------- + * | W | B | | B | W | + * |-------| - (tag 3) |-------| - (tag 4) + * | G | R | | R | G | + * --------- --------- + * + * --------- --------- + * | R | B | | G | W | + * |-------| - (tag 5) |-------| - (tag 6) + * | G | W | | R | B | + * --------- --------- + * + * --------- --------- + * | W | G | | B | R | + * |-------| - (tag 7) |-------| - (tag 8) + * | B | R | | W | G | + * --------- --------- + * + * + * Every image contains exif field with orientation tag (0x112) + * After reading each image the corresponding matrix must be read as + * --------- + * | R | G | + * |-------| + * | B | W | + * --------- + * + */ + +typedef testing::TestWithParam Imgcodecs_Jpeg_Exif; + +TEST_P(Imgcodecs_Jpeg_Exif, exif_orientation) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string filename = root + GetParam(); + const int colorThresholdHigh = 250; + const int colorThresholdLow = 5; + + Mat m_img = imread(filename); + ASSERT_FALSE(m_img.empty()); + Vec3b vec; + + //Checking the first quadrant (with supposed red) + vec = m_img.at(2, 2); //some point inside the square + EXPECT_LE(vec.val[0], colorThresholdLow); + EXPECT_LE(vec.val[1], colorThresholdLow); + EXPECT_GE(vec.val[2], colorThresholdHigh); + + //Checking the second quadrant (with supposed green) + vec = m_img.at(2, 7); //some point inside the square + EXPECT_LE(vec.val[0], colorThresholdLow); + EXPECT_GE(vec.val[1], colorThresholdHigh); + EXPECT_LE(vec.val[2], colorThresholdLow); + + //Checking the third quadrant (with supposed blue) + vec = m_img.at(7, 2); //some point inside the square + EXPECT_GE(vec.val[0], colorThresholdHigh); + EXPECT_LE(vec.val[1], colorThresholdLow); + EXPECT_LE(vec.val[2], colorThresholdLow); +} + +const string exif_files[] = +{ + "readwrite/testExifOrientation_1.jpg", + "readwrite/testExifOrientation_2.jpg", + "readwrite/testExifOrientation_3.jpg", + "readwrite/testExifOrientation_4.jpg", + "readwrite/testExifOrientation_5.jpg", + "readwrite/testExifOrientation_6.jpg", + "readwrite/testExifOrientation_7.jpg", + "readwrite/testExifOrientation_8.jpg" +}; + +INSTANTIATE_TEST_CASE_P(ExifFiles, Imgcodecs_Jpeg_Exif, + testing::ValuesIn(exif_files)); + +//================================================================================================== + +TEST(Imgcodecs_Jpeg, encode_empty) +{ + cv::Mat img; + std::vector jpegImg; + ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception); +} + +TEST(Imgcodecs_Jpeg, encode_decode_progressive_jpeg) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(input); + ASSERT_FALSE(img.empty()); + + std::vector params; + params.push_back(IMWRITE_JPEG_PROGRESSIVE); + params.push_back(1); + + string output_progressive = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_progressive, img, params)); + cv::Mat img_jpg_progressive = cv::imread(output_progressive); + + string output_normal = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_normal, img)); + cv::Mat img_jpg_normal = cv::imread(output_normal); + + EXPECT_EQ(0, cvtest::norm(img_jpg_progressive, img_jpg_normal, NORM_INF)); + + remove(output_progressive.c_str()); + remove(output_normal.c_str()); +} + +TEST(Imgcodecs_Jpeg, encode_decode_optimize_jpeg) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(input); + ASSERT_FALSE(img.empty()); + + std::vector params; + params.push_back(IMWRITE_JPEG_OPTIMIZE); + params.push_back(1); + + string output_optimized = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_optimized, img, params)); + cv::Mat img_jpg_optimized = cv::imread(output_optimized); + + string output_normal = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_normal, img)); + cv::Mat img_jpg_normal = cv::imread(output_normal); + + EXPECT_EQ(0, cvtest::norm(img_jpg_optimized, img_jpg_normal, NORM_INF)); + + remove(output_optimized.c_str()); + remove(output_normal.c_str()); +} + +TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg) +{ + cvtest::TS& ts = *cvtest::TS::ptr(); + string input = string(ts.get_data_path()) + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(input); + ASSERT_FALSE(img.empty()); + + std::vector params; + params.push_back(IMWRITE_JPEG_RST_INTERVAL); + params.push_back(1); + + string output_rst = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_rst, img, params)); + cv::Mat img_jpg_rst = cv::imread(output_rst); + + string output_normal = cv::tempfile(".jpg"); + EXPECT_NO_THROW(cv::imwrite(output_normal, img)); + cv::Mat img_jpg_normal = cv::imread(output_normal); + + EXPECT_EQ(0, cvtest::norm(img_jpg_rst, img_jpg_normal, NORM_INF)); + + remove(output_rst.c_str()); + remove(output_normal.c_str()); +} + +#endif // HAVE_JPEG diff --git a/modules/imgcodecs/test/test_png.cpp b/modules/imgcodecs/test/test_png.cpp new file mode 100644 index 0000000..c46f901 --- /dev/null +++ b/modules/imgcodecs/test/test_png.cpp @@ -0,0 +1,95 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; +using namespace std::tr1; + +#ifdef HAVE_PNG + +TEST(Imgcodecs_Png, write_big) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string filename = root + "readwrite/read.png"; + const string dst_file = cv::tempfile(".png"); + Mat img; + ASSERT_NO_THROW(img = imread(filename)); + ASSERT_FALSE(img.empty()); + EXPECT_EQ(13043, img.cols); + EXPECT_EQ(13917, img.rows); + ASSERT_NO_THROW(imwrite(dst_file, img)); + remove(dst_file.c_str()); +} + +TEST(Imgcodecs_Png, encode) +{ + vector buff; + Mat img_gt = Mat::zeros(1000, 1000, CV_8U); + vector param; + param.push_back(IMWRITE_PNG_COMPRESSION); + param.push_back(3); //default(3) 0-9. + EXPECT_NO_THROW(imencode(".png", img_gt, buff, param)); + Mat img; + EXPECT_NO_THROW(img = imdecode(buff, IMREAD_ANYDEPTH)); // hang + EXPECT_FALSE(img.empty()); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt); +} + +TEST(Imgcodecs_Png, regression_ImreadVSCvtColor) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string imgName = root + "../cv/shared/lena.png"; + Mat original_image = imread(imgName); + Mat gray_by_codec = imread(imgName, IMREAD_GRAYSCALE); + Mat gray_by_cvt; + cvtColor(original_image, gray_by_cvt, CV_BGR2GRAY); + + Mat diff; + absdiff(gray_by_codec, gray_by_cvt, diff); + EXPECT_LT(cvtest::mean(diff)[0], 1.); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(10, 0), gray_by_codec, gray_by_cvt); +} + +// Test OpenCV issue 3075 is solved +TEST(Imgcodecs_Png, read_color_palette_with_alpha) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + Mat img; + + // First Test : Read PNG with alpha, imread flag -1 + img = imread(root + "readwrite/color_palette_alpha.png", IMREAD_UNCHANGED); + ASSERT_FALSE(img.empty()); + ASSERT_TRUE(img.channels() == 4); + + // pixel is red in BGRA + EXPECT_EQ(img.at(0, 0), Vec4b(0, 0, 255, 255)); + EXPECT_EQ(img.at(0, 1), Vec4b(0, 0, 255, 255)); + + // Second Test : Read PNG without alpha, imread flag -1 + img = imread(root + "readwrite/color_palette_no_alpha.png", IMREAD_UNCHANGED); + ASSERT_FALSE(img.empty()); + ASSERT_TRUE(img.channels() == 3); + + // pixel is red in BGR + EXPECT_EQ(img.at(0, 0), Vec3b(0, 0, 255)); + EXPECT_EQ(img.at(0, 1), Vec3b(0, 0, 255)); + + // Third Test : Read PNG with alpha, imread flag 1 + img = imread(root + "readwrite/color_palette_alpha.png", IMREAD_COLOR); + ASSERT_FALSE(img.empty()); + ASSERT_TRUE(img.channels() == 3); + + // pixel is red in BGR + EXPECT_EQ(img.at(0, 0), Vec3b(0, 0, 255)); + EXPECT_EQ(img.at(0, 1), Vec3b(0, 0, 255)); + + // Fourth Test : Read PNG without alpha, imread flag 1 + img = imread(root + "readwrite/color_palette_no_alpha.png", IMREAD_COLOR); + ASSERT_FALSE(img.empty()); + ASSERT_TRUE(img.channels() == 3); + + // pixel is red in BGR + EXPECT_EQ(img.at(0, 0), Vec3b(0, 0, 255)); + EXPECT_EQ(img.at(0, 1), Vec3b(0, 0, 255)); +} + +#endif // HAVE_PNG diff --git a/modules/imgcodecs/test/test_precomp.hpp b/modules/imgcodecs/test/test_precomp.hpp index 2aed614..fd9c18c 100644 --- a/modules/imgcodecs/test/test_precomp.hpp +++ b/modules/imgcodecs/test/test_precomp.hpp @@ -9,7 +9,6 @@ #ifndef __OPENCV_TEST_PRECOMP_HPP__ #define __OPENCV_TEST_PRECOMP_HPP__ -#include #include "opencv2/ts.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/imgcodecs.hpp" @@ -17,4 +16,10 @@ #include "opencv2/core/private.hpp" +#include +#include +#include +#include +#include + #endif diff --git a/modules/imgcodecs/test/test_read_write.cpp b/modules/imgcodecs/test/test_read_write.cpp new file mode 100644 index 0000000..38f1022 --- /dev/null +++ b/modules/imgcodecs/test/test_read_write.cpp @@ -0,0 +1,122 @@ +#include "test_precomp.hpp" + +#include +#include +#include + +using namespace cv; +using namespace std; +using namespace cvtest; + +TEST(Imgcodecs_Image, read_write_bmp) +{ + const size_t IMAGE_COUNT = 10; + const double thresDbell = 32; + + for (size_t i = 0; i < IMAGE_COUNT; ++i) + { + stringstream s; s << i; + const string digit = s.str(); + const string src_name = TS::ptr()->get_data_path() + "../python/images/QCIF_0" + digit + ".bmp"; + const string dst_name = cv::tempfile((digit + ".bmp").c_str()); + Mat image = imread(src_name); + ASSERT_FALSE(image.empty()); + + resize(image, image, Size(968, 757), 0.0, 0.0, INTER_CUBIC); + imwrite(dst_name, image); + Mat loaded = imread(dst_name); + ASSERT_FALSE(loaded.empty()); + + double psnr = cvtest::PSNR(loaded, image); + EXPECT_GT(psnr, thresDbell); + + vector from_file; + + FILE *f = fopen(dst_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); + ASSERT_EQ(buf, from_file); + + Mat buf_loaded = imdecode(Mat(buf), 1); + ASSERT_FALSE(buf_loaded.empty()); + + psnr = cvtest::PSNR(buf_loaded, image); + EXPECT_GT(psnr, thresDbell); + + remove(dst_name.c_str()); + } +} + +//================================================================================================== + +typedef string Ext; +typedef testing::TestWithParam Imgcodecs_Image; + +TEST_P(Imgcodecs_Image, read_write) +{ + const string ext = this->GetParam(); + const string full_name = cv::tempfile(ext.c_str()); + const string _name = TS::ptr()->get_data_path() + "../cv/shared/baboon.png"; + const double thresDbell = 32; + + Mat image = imread(_name); + image.convertTo(image, CV_8UC3); + ASSERT_FALSE(image.empty()); + + imwrite(full_name, image); + Mat loaded = imread(full_name); + ASSERT_FALSE(loaded.empty()); + + double psnr = cvtest::PSNR(loaded, image); + EXPECT_GT(psnr, thresDbell); + + 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("." + ext, image, buf); + ASSERT_EQ(buf, from_file); + + Mat buf_loaded = imdecode(Mat(buf), 1); + ASSERT_FALSE(buf_loaded.empty()); + + psnr = cvtest::PSNR(buf_loaded, image); + EXPECT_GT(psnr, thresDbell); + + remove(full_name.c_str()); +} + +const string exts[] = { +#ifdef HAVE_PNG + "png", +#endif +#ifdef HAVE_TIFF + "tiff", +#endif +#ifdef HAVE_JPEG + "jpg", +#endif +#ifdef HAVE_JASPER + "jp2", +#endif +#if 0 /*defined HAVE_OPENEXR && !defined __APPLE__*/ + "exr", +#endif + "bmp", + "ppm", + "ras" +}; + +INSTANTIATE_TEST_CASE_P(imgcodecs, Imgcodecs_Image, testing::ValuesIn(exts)); diff --git a/modules/imgcodecs/test/test_tiff.cpp b/modules/imgcodecs/test/test_tiff.cpp new file mode 100644 index 0000000..4cbb798 --- /dev/null +++ b/modules/imgcodecs/test/test_tiff.cpp @@ -0,0 +1,202 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; +using namespace std::tr1; + +#ifdef HAVE_TIFF + +// these defines are used to resolve conflict between tiff.h and opencv2/core/types_c.h +#define uint64 uint64_hack_ +#define int64 int64_hack_ +#include "tiff.h" + +#ifdef ANDROID +// Test disabled as it uses a lot of memory. +// It is killed with SIGKILL by out of memory killer. +TEST(Imgcodecs_Tiff, DISABLED_decode_tile16384x16384) +#else +TEST(Imgcodecs_Tiff, decode_tile16384x16384) +#endif +{ + // see issue #2161 + cv::Mat big(16384, 16384, CV_8UC1, cv::Scalar::all(0)); + string file3 = cv::tempfile(".tiff"); + string file4 = cv::tempfile(".tiff"); + + std::vector params; + params.push_back(TIFFTAG_ROWSPERSTRIP); + params.push_back(big.rows); + EXPECT_NO_THROW(cv::imwrite(file4, big, params)); + EXPECT_NO_THROW(cv::imwrite(file3, big.colRange(0, big.cols - 1), params)); + big.release(); + + try + { + cv::imread(file3, IMREAD_UNCHANGED); + EXPECT_NO_THROW(cv::imread(file4, IMREAD_UNCHANGED)); + } + catch(const std::bad_alloc&) + { + // not enough memory + } + + remove(file3.c_str()); + remove(file4.c_str()); +} + +TEST(Imgcodecs_Tiff, write_read_16bit_big_little_endian) +{ + // see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness" + + // Setup data for two minimal 16-bit grayscale TIFF files in both endian formats + uchar tiff_sample_data[2][86] = { { + // Little endian + 0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01, + 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, { + // Big endian + 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, + 0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x04 } + }; + + // Test imread() for both a little endian TIFF and big endian TIFF + for (int i = 0; i < 2; i++) + { + string filename = cv::tempfile(".tiff"); + + // Write sample TIFF file + FILE* fp = fopen(filename.c_str(), "wb"); + ASSERT_TRUE(fp != NULL); + ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp)); + fclose(fp); + + Mat img = imread(filename, IMREAD_UNCHANGED); + + EXPECT_EQ(1, img.rows); + EXPECT_EQ(2, img.cols); + EXPECT_EQ(CV_16U, img.type()); + EXPECT_EQ(sizeof(ushort), img.elemSize()); + EXPECT_EQ(1, img.channels()); + EXPECT_EQ(0xDEAD, img.at(0,0)); + EXPECT_EQ(0xBEEF, img.at(0,1)); + + remove(filename.c_str()); + } +} + +TEST(Imgcodecs_Tiff, decode_tile_remainder) +{ + /* see issue #3472 - dealing with tiled images where the tile size is + * not a multiple of image size. + * The tiled images were created with 'convert' from ImageMagick, + * using the command 'convert -define tiff:tile-geometry=128x128 -depth [8|16] + * Note that the conversion to 16 bits expands the range from 0-255 to 0-255*255, + * so the test converts back but rounding errors cause small differences. + */ + const string root = cvtest::TS::ptr()->get_data_path(); + cv::Mat img = imread(root + "readwrite/non_tiled.tif",-1); + ASSERT_FALSE(img.empty()); + ASSERT_TRUE(img.channels() == 3); + cv::Mat tiled8 = imread(root + "readwrite/tiled_8.tif", -1); + ASSERT_FALSE(tiled8.empty()); + ASSERT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, tiled8); + cv::Mat tiled16 = imread(root + "readwrite/tiled_16.tif", -1); + ASSERT_FALSE(tiled16.empty()); + ASSERT_TRUE(tiled16.elemSize() == 6); + tiled16.convertTo(tiled8, CV_8UC3, 1./256.); + ASSERT_PRED_FORMAT2(cvtest::MatComparator(2, 0), img, tiled8); + // What about 32, 64 bit? +} + +TEST(Imgcodecs_Tiff, decode_infinite_rowsperstrip) +{ + const uchar sample_data[142] = { + 0x49, 0x49, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x54, + 0x56, 0x5a, 0x59, 0x55, 0x5a, 0x00, 0x0a, 0x00, 0x00, 0x01, + 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x03, 0x01, 0x03, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x15, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x16, 0x01, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x03, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }; + + const string filename = cv::tempfile(".tiff"); + std::ofstream outfile(filename.c_str(), std::ofstream::binary); + outfile.write(reinterpret_cast(sample_data), sizeof sample_data); + outfile.close(); + + EXPECT_NO_THROW(cv::imread(filename, IMREAD_UNCHANGED)); + + remove(filename.c_str()); +} + +//================================================================================================== + +typedef testing::TestWithParam Imgcodecs_Tiff_Modes; + +TEST_P(Imgcodecs_Tiff_Modes, decode_multipage) +{ + const int mode = GetParam(); + const string root = cvtest::TS::ptr()->get_data_path(); + const string filename = root + "readwrite/multipage.tif"; + const string page_files[] = { + "readwrite/multipage_p1.tif", + "readwrite/multipage_p2.tif", + "readwrite/multipage_p3.tif", + "readwrite/multipage_p4.tif", + "readwrite/multipage_p5.tif", + "readwrite/multipage_p6.tif" + }; + const size_t page_count = sizeof(page_files)/sizeof(page_files[0]); + vector pages; + bool res = imreadmulti(filename, pages, mode); + ASSERT_TRUE(res == true); + ASSERT_EQ(page_count, pages.size()); + for (size_t i = 0; i < page_count; i++) + { + const Mat page = imread(root + page_files[i], mode); + EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), page, pages[i]); + } +} + +const int all_modes[] = +{ + IMREAD_UNCHANGED, + IMREAD_GRAYSCALE, + IMREAD_COLOR, + IMREAD_ANYDEPTH, + IMREAD_ANYCOLOR +}; + +INSTANTIATE_TEST_CASE_P(AllModes, Imgcodecs_Tiff_Modes, testing::ValuesIn(all_modes)); + +//================================================================================================== + +TEST(Imgcodecs_Tiff, imdecode_no_exception_temporary_file_removed) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string filename = root + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(filename); + ASSERT_FALSE(img.empty()); + std::vector buf; + EXPECT_NO_THROW(cv::imencode(".tiff", img, buf)); + EXPECT_NO_THROW(cv::imdecode(buf, IMREAD_UNCHANGED)); +} + +#endif diff --git a/modules/imgcodecs/test/test_webp.cpp b/modules/imgcodecs/test/test_webp.cpp new file mode 100644 index 0000000..6d40ce2 --- /dev/null +++ b/modules/imgcodecs/test/test_webp.cpp @@ -0,0 +1,106 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; +using namespace std::tr1; + +#ifdef HAVE_WEBP + +TEST(Imgcodecs_WebP, encode_decode_lossless_webp) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + string filename = root + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(filename); + ASSERT_FALSE(img.empty()); + + string output = cv::tempfile(".webp"); + EXPECT_NO_THROW(cv::imwrite(output, img)); // lossless + + cv::Mat img_webp = cv::imread(output); + + std::vector buf; + + FILE * wfile = NULL; + + wfile = fopen(output.c_str(), "rb"); + if (wfile != NULL) + { + fseek(wfile, 0, SEEK_END); + size_t wfile_size = ftell(wfile); + fseek(wfile, 0, SEEK_SET); + + buf.resize(wfile_size); + + size_t data_size = fread(&buf[0], 1, wfile_size, wfile); + + if(wfile) + { + fclose(wfile); + } + + if (data_size != wfile_size) + { + EXPECT_TRUE(false); + } + } + + remove(output.c_str()); + + cv::Mat decode = cv::imdecode(buf, IMREAD_COLOR); + ASSERT_FALSE(decode.empty()); + EXPECT_TRUE(cvtest::norm(decode, img_webp, NORM_INF) == 0); + + ASSERT_FALSE(img_webp.empty()); + + EXPECT_TRUE(cvtest::norm(img, img_webp, NORM_INF) == 0); +} + +TEST(Imgcodecs_WebP, encode_decode_lossy_webp) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + std::string input = root + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(input); + ASSERT_FALSE(img.empty()); + + for(int q = 100; q>=0; q-=20) + { + std::vector params; + params.push_back(IMWRITE_WEBP_QUALITY); + params.push_back(q); + string output = cv::tempfile(".webp"); + + EXPECT_NO_THROW(cv::imwrite(output, img, params)); + cv::Mat img_webp = cv::imread(output); + remove(output.c_str()); + EXPECT_FALSE(img_webp.empty()); + EXPECT_EQ(3, img_webp.channels()); + EXPECT_EQ(512, img_webp.cols); + EXPECT_EQ(512, img_webp.rows); + } +} + +TEST(Imgcodecs_WebP, encode_decode_with_alpha_webp) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + std::string input = root + "../cv/shared/lena.png"; + cv::Mat img = cv::imread(input); + ASSERT_FALSE(img.empty()); + + std::vector imgs; + cv::split(img, imgs); + imgs.push_back(cv::Mat(imgs[0])); + imgs[imgs.size() - 1] = cv::Scalar::all(128); + cv::merge(imgs, img); + + string output = cv::tempfile(".webp"); + + EXPECT_NO_THROW(cv::imwrite(output, img)); + cv::Mat img_webp = cv::imread(output); + remove(output.c_str()); + EXPECT_FALSE(img_webp.empty()); + EXPECT_EQ(4, img_webp.channels()); + EXPECT_EQ(512, img_webp.cols); + EXPECT_EQ(512, img_webp.rows); +} + +#endif // HAVE_WEBP diff --git a/modules/superres/test/test_precomp.hpp b/modules/superres/test/test_precomp.hpp index b1c8257..9e89b42 100644 --- a/modules/superres/test/test_precomp.hpp +++ b/modules/superres/test/test_precomp.hpp @@ -59,17 +59,4 @@ #include "cvconfig.h" #include "../src/input_array_utility.hpp" -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) || \ - defined(HAVE_VFW) -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - #endif diff --git a/modules/superres/test/test_superres.cpp b/modules/superres/test/test_superres.cpp index 56e9f54..0c6128c 100644 --- a/modules/superres/test/test_superres.cpp +++ b/modules/superres/test/test_superres.cpp @@ -43,7 +43,7 @@ #include "test_precomp.hpp" #include "opencv2/ts/ocl_test.hpp" -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT class AllignedFrameSource : public cv::superres::FrameSource { @@ -295,4 +295,4 @@ OCL_TEST_F(SuperResolution, BTVL1) #endif -#endif // BUILD_WITH_VIDEO_INPUT_SUPPORT +#endif // HAVE_VIDEO_INPUT diff --git a/modules/ts/src/ts_func.cpp b/modules/ts/src/ts_func.cpp index a8f1460..702bdf3 100644 --- a/modules/ts/src/ts_func.cpp +++ b/modules/ts/src/ts_func.cpp @@ -2947,9 +2947,9 @@ MatComparator::operator()(const char* expr1, const char* expr2, return ::testing::AssertionFailure() << "too big relative difference (" << realmaxdiff << " > " << maxdiff << ") between " - << MatInfo(m1) << " '" << expr1 << "' and '" << expr2 << "' at " << Mat(loc0) << ".\n\n" - << "'" << expr1 << "': " << MatPart(m1part, border > 0 ? &loc : 0) << ".\n\n" - << "'" << expr2 << "': " << MatPart(m2part, border > 0 ? &loc : 0) << ".\n"; + << MatInfo(m1) << " '" << expr1 << "' and '" << expr2 << "' at " << Mat(loc0).t() << ".\n" + << "- " << expr1 << ":\n" << MatPart(m1part, border > 0 ? &loc : 0) << ".\n" + << "- " << expr2 << ":\n" << MatPart(m2part, border > 0 ? &loc : 0) << ".\n"; } void printVersionInfo(bool useStdOut) diff --git a/modules/video/perf/opencl/perf_bgfg_mog2.cpp b/modules/video/perf/opencl/perf_bgfg_mog2.cpp index 12223d6..e80972d 100644 --- a/modules/video/perf/opencl/perf_bgfg_mog2.cpp +++ b/modules/video/perf/opencl/perf_bgfg_mog2.cpp @@ -2,20 +2,7 @@ #include "opencv2/ts/ocl_perf.hpp" #ifdef HAVE_OPENCL - -#if defined(HAVE_XINE) || \ -defined(HAVE_GSTREAMER) || \ -defined(HAVE_QUICKTIME) || \ -defined(HAVE_AVFOUNDATION) || \ -defined(HAVE_FFMPEG) || \ -defined(WIN32) - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT namespace cvtest { namespace ocl { @@ -116,5 +103,5 @@ OCL_PERF_TEST_P(MOG2_GetBackgroundImage, Mog2, Combine(Values("gpu/video/768x576 }}// namespace cvtest::ocl - #endif -#endif \ No newline at end of file +#endif +#endif diff --git a/modules/video/test/ocl/test_bgfg_mog2.cpp b/modules/video/test/ocl/test_bgfg_mog2.cpp index 030cd09..3c9c004 100644 --- a/modules/video/test/ocl/test_bgfg_mog2.cpp +++ b/modules/video/test/ocl/test_bgfg_mog2.cpp @@ -2,20 +2,7 @@ #include "opencv2/ts/ocl_test.hpp" #ifdef HAVE_OPENCL - -#if defined(HAVE_XINE) || \ -defined(HAVE_GSTREAMER) || \ -defined(HAVE_QUICKTIME) || \ -defined(HAVE_AVFOUNDATION) || \ -defined(HAVE_FFMPEG) || \ -defined(WIN32) - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT namespace cvtest { namespace ocl { @@ -154,5 +141,5 @@ OCL_INSTANTIATE_TEST_CASE_P(OCL_Video, Mog2_getBackgroundImage, Combine( }}// namespace cvtest::ocl - #endif +#endif #endif diff --git a/modules/videoio/perf/perf_input.cpp b/modules/videoio/perf/perf_input.cpp index 10ce30a..8b7d984 100644 --- a/modules/videoio/perf/perf_input.cpp +++ b/modules/videoio/perf/perf_input.cpp @@ -1,6 +1,6 @@ #include "perf_precomp.hpp" -#if BUILD_WITH_VIDEO_INPUT_SUPPORT +#ifdef HAVE_VIDEO_INPUT using namespace std; using namespace cv; @@ -11,21 +11,19 @@ using std::tr1::get; typedef perf::TestBaseWithParam VideoCapture_Reading; -#if defined(HAVE_MSMF) -// MPEG2 is not supported by Media Foundation yet -// http://social.msdn.microsoft.com/Forums/en-US/mediafoundationdevelopment/thread/39a36231-8c01-40af-9af5-3c105d684429 -PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::Values( "highgui/video/big_buck_bunny.avi", - "highgui/video/big_buck_bunny.mov", - "highgui/video/big_buck_bunny.mp4", - "highgui/video/big_buck_bunny.wmv" ) ) - -#else -PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::Values( "highgui/video/big_buck_bunny.avi", - "highgui/video/big_buck_bunny.mov", - "highgui/video/big_buck_bunny.mp4", - "highgui/video/big_buck_bunny.mpg", - "highgui/video/big_buck_bunny.wmv" ) ) +const string bunny_files[] = { + "highgui/video/big_buck_bunny.avi", + "highgui/video/big_buck_bunny.mov", + "highgui/video/big_buck_bunny.mp4", +#ifndef HAVE_MSMF + // MPEG2 is not supported by Media Foundation yet + // http://social.msdn.microsoft.com/Forums/en-US/mediafoundationdevelopment/thread/39a36231-8c01-40af-9af5-3c105d684429 + "highgui/video/big_buck_bunny.mpg", #endif + "highgui/video/big_buck_bunny.wmv" +}; + +PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::ValuesIn(bunny_files) ) { string filename = getDataPath(GetParam()); @@ -33,8 +31,7 @@ PERF_TEST_P(VideoCapture_Reading, ReadFile, testing::Values( "highgui/video/big_ TEST_CYCLE() cap.open(filename); - bool dummy = cap.isOpened(); - SANITY_CHECK(dummy); + SANITY_CHECK_NOTHING(); } -#endif // BUILD_WITH_VIDEO_INPUT_SUPPORT +#endif // HAVE_VIDEO_INPUT diff --git a/modules/videoio/perf/perf_output.cpp b/modules/videoio/perf/perf_output.cpp index 8e7ec54..b99b752 100644 --- a/modules/videoio/perf/perf_output.cpp +++ b/modules/videoio/perf/perf_output.cpp @@ -1,6 +1,6 @@ #include "perf_precomp.hpp" -#if BUILD_WITH_VIDEO_OUTPUT_SUPPORT +#ifdef HAVE_VIDEO_OUTPUT using namespace std; using namespace cv; @@ -11,30 +11,35 @@ using std::tr1::get; typedef std::tr1::tuple VideoWriter_Writing_t; typedef perf::TestBaseWithParam VideoWriter_Writing; +const string image_files[] = { + "python/images/QCIF_00.bmp", + "python/images/QCIF_01.bmp", + "python/images/QCIF_02.bmp", + "python/images/QCIF_03.bmp", + "python/images/QCIF_04.bmp", + "python/images/QCIF_05.bmp" +}; + PERF_TEST_P(VideoWriter_Writing, WriteFrame, - testing::Combine( testing::Values( "python/images/QCIF_00.bmp", - "python/images/QCIF_01.bmp", - "python/images/QCIF_02.bmp", - "python/images/QCIF_03.bmp", - "python/images/QCIF_04.bmp", - "python/images/QCIF_05.bmp" ), - testing::Bool())) + testing::Combine( + testing::ValuesIn(image_files), + testing::Bool())) { - string filename = getDataPath(get<0>(GetParam())); - bool isColor = get<1>(GetParam()); + const string filename = getDataPath(get<0>(GetParam())); + const bool isColor = get<1>(GetParam()); Mat image = imread(filename, 1); #if defined(HAVE_MSMF) && !defined(HAVE_VFW) && !defined(HAVE_FFMPEG) // VFW has greater priority - VideoWriter writer(cv::tempfile(".wmv"), VideoWriter::fourcc('W', 'M', 'V', '3'), - 25, cv::Size(image.cols, image.rows), isColor); + const string outfile = cv::tempfile(".wmv"); + const int fourcc = VideoWriter::fourcc('W', 'M', 'V', '3'); #else - VideoWriter writer(cv::tempfile(".avi"), VideoWriter::fourcc('X', 'V', 'I', 'D'), - 25, cv::Size(image.cols, image.rows), isColor); + const string outfile = cv::tempfile(".avi"); + const int fourcc = VideoWriter::fourcc('X', 'V', 'I', 'D'); #endif - TEST_CYCLE() { image = imread(filename, 1); writer << image; } - - bool dummy = writer.isOpened(); - SANITY_CHECK(dummy); + VideoWriter writer(outfile, fourcc, 25, cv::Size(image.cols, image.rows), isColor); + TEST_CYCLE_N(100) { writer << image; } + SANITY_CHECK_NOTHING(); + remove(outfile.c_str()); } -#endif // BUILD_WITH_VIDEO_OUTPUT_SUPPORT +#endif // HAVE_VIDEO_OUTPUT diff --git a/modules/videoio/perf/perf_precomp.hpp b/modules/videoio/perf/perf_precomp.hpp index bd27700..52ba934 100644 --- a/modules/videoio/perf/perf_precomp.hpp +++ b/modules/videoio/perf/perf_precomp.hpp @@ -17,33 +17,4 @@ #error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined #endif -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) || \ - defined(HAVE_VFW) - /*defined(HAVE_OPENNI) too specialized */ \ - -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - -#if /*defined(HAVE_XINE) || */\ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) || \ - defined(HAVE_VFW) -# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0 -#endif - - #endif diff --git a/modules/videoio/src/cap.cpp b/modules/videoio/src/cap.cpp index 6de3994..752e3b9 100644 --- a/modules/videoio/src/cap.cpp +++ b/modules/videoio/src/cap.cpp @@ -182,11 +182,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index) TRY_OPEN(capture, cvCreateCameraCapture_MSMF(index)) if (pref) break; #endif -#ifdef HAVE_TYZX - case CV_CAP_STEREO: - TRY_OPEN(capture, cvCreateCameraCapture_TYZX(index)) - if (pref) break; -#endif case CV_CAP_VFW: #ifdef HAVE_VFW TRY_OPEN(capture, cvCreateCameraCapture_VFW(index)) diff --git a/modules/videoio/src/precomp.hpp b/modules/videoio/src/precomp.hpp index a63649b..7330e4e 100644 --- a/modules/videoio/src/precomp.hpp +++ b/modules/videoio/src/precomp.hpp @@ -108,7 +108,6 @@ CvCapture * cvCreateCameraCapture_DC1394_2( int index ); CvCapture* cvCreateCameraCapture_MIL( int index ); CvCapture* cvCreateCameraCapture_Giganetix( int index ); CvCapture * cvCreateCameraCapture_CMU( int index ); -CV_IMPL CvCapture * cvCreateCameraCapture_TYZX( int index ); CvCapture* cvCreateFileCapture_Win32( const char* filename ); CvCapture* cvCreateCameraCapture_VFW( int index ); CvCapture* cvCreateFileCapture_VFW( const char* filename ); diff --git a/modules/videoio/test/test_basic_props.cpp b/modules/videoio/test/test_basic_props.cpp deleted file mode 100644 index ef2fabe..0000000 --- a/modules/videoio/test/test_basic_props.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#include "test_precomp.hpp" -#include "opencv2/videoio.hpp" -#include "opencv2/ts.hpp" -#include - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT - -using namespace cv; -using namespace std; -using namespace cvtest; - -#ifdef HAVE_GSTREAMER -const string ext[] = {"avi"}; -#else -const string ext[] = {"avi", "mov", "mp4"}; -#endif - -TEST(Videoio_Video, prop_resolution) -{ - const size_t n = sizeof(ext)/sizeof(ext[0]); - const string src_dir = TS::ptr()->get_data_path(); - - TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); - - for (size_t i = 0; i < n; ++i) - { - string file_path = src_dir+"video/big_buck_bunny."+ext[i]; - VideoCapture cap(file_path); - if (!cap.isOpened()) - { - TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); - TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); - TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - return; - } - - ASSERT_EQ(672, cap.get(CAP_PROP_FRAME_WIDTH)); - ASSERT_EQ(384, cap.get(CAP_PROP_FRAME_HEIGHT)); - } -} - -TEST(Videoio_Video, actual_resolution) -{ - const size_t n = sizeof(ext)/sizeof(ext[0]); - const string src_dir = TS::ptr()->get_data_path(); - - TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); - - for (size_t i = 0; i < n; ++i) - { - string file_path = src_dir+"video/big_buck_bunny."+ext[i]; - VideoCapture cap(file_path); - if (!cap.isOpened()) - { - TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); - TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); - TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - return; - } - - Mat frame; - cap >> frame; - - ASSERT_EQ(672, frame.cols); - ASSERT_EQ(384, frame.rows); - } -} - -TEST(Videoio_Video, DISABLED_prop_fps) -{ - const size_t n = sizeof(ext)/sizeof(ext[0]); - const string src_dir = TS::ptr()->get_data_path(); - - TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); - - for (size_t i = 0; i < n; ++i) - { - string file_path = src_dir+"video/big_buck_bunny."+ext[i]; - VideoCapture cap(file_path); - if (!cap.isOpened()) - { - TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); - TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); - TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - return; - } - - ASSERT_EQ(24, cap.get(CAP_PROP_FPS)); - } -} - -TEST(Videoio_Video, prop_framecount) -{ - const size_t n = sizeof(ext)/sizeof(ext[0]); - const string src_dir = TS::ptr()->get_data_path(); - - TS::ptr()->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); - - for (size_t i = 0; i < n; ++i) - { - string file_path = src_dir+"video/big_buck_bunny."+ext[i]; - VideoCapture cap(file_path); - if (!cap.isOpened()) - { - TS::ptr()->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); - TS::ptr()->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); - TS::ptr()->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - return; - } - - ASSERT_EQ(125, cap.get(CAP_PROP_FRAME_COUNT)); - } -} - -#endif diff --git a/modules/videoio/test/test_framecount.cpp b/modules/videoio/test/test_framecount.cpp deleted file mode 100644 index 94ddbf8..0000000 --- a/modules/videoio/test/test_framecount.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#include "test_precomp.hpp" -#include "opencv2/videoio/videoio_c.h" -#include - -using namespace cv; -using namespace std; - -class CV_FramecountTest: public cvtest::BaseTest -{ -public: - void run(int); -}; - -void CV_FramecountTest::run(int) -{ - const int time_sec = 5, fps = 25; - - const string ext[] = {"avi", "mov", "mp4"}; - - const size_t n = sizeof(ext)/sizeof(ext[0]); - - const string src_dir = ts->get_data_path(); - - ts->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); - - Ptr cap; - - for (size_t i = 0; i < n; ++i) - { - string file_path = src_dir+"video/big_buck_bunny."+ext[i]; - - cap.reset(cvCreateFileCapture(file_path.c_str())); - if (!cap) - { - ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); - ts->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); - ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - return; - } - - //cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 0); - IplImage* frame; int FrameCount = 0; - - for(;;) - { - frame = cvQueryFrame(cap); - if( !frame ) - break; - FrameCount++; - } - - int framecount = (int)cvGetCaptureProperty(cap, CAP_PROP_FRAME_COUNT); - - ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n"\ - "\nName: big_buck_bunny.%s\nActual frame count: %d\n"\ - "Frame count computed in the cycle of queries of frames: %d\n"\ - "Frame count returned by cvGetCaptureProperty function: %d\n", - i+1, ext[i].c_str(), time_sec*fps, FrameCount, framecount); - - if( (FrameCount != cvRound(time_sec*fps) || - FrameCount != framecount) && ext[i] != "mpg" ) - { - ts->printf(cvtest::TS::LOG, "FAILED\n"); - ts->printf(cvtest::TS::LOG, "\nError: actual frame count and returned frame count are not matched.\n"); - ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); - return; - } - } -} -#if BUILD_WITH_VIDEO_INPUT_SUPPORT && defined HAVE_FFMPEG -TEST(Videoio_Video, framecount) {CV_FramecountTest test; test.safe_run();} -#endif diff --git a/modules/videoio/test/test_positioning.cpp b/modules/videoio/test/test_positioning.cpp deleted file mode 100644 index 5cead8d..0000000 --- a/modules/videoio/test/test_positioning.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#include "test_precomp.hpp" -#include "opencv2/videoio/videoio_c.h" -#include - -using namespace cv; -using namespace std; - -class CV_VideoPositioningTest: public cvtest::BaseTest -{ -public: - enum {PROGRESSIVE, RANDOM}; - - CV_VideoPositioningTest(); - ~CV_VideoPositioningTest(); - virtual void run(int) = 0; - -protected: - vector idx; - void run_test(int method); - -private: - void generate_idx_seq(CvCapture *cap, int method); -}; - -class CV_VideoProgressivePositioningTest: public CV_VideoPositioningTest -{ -public: - CV_VideoProgressivePositioningTest() : CV_VideoPositioningTest() { } - ~CV_VideoProgressivePositioningTest(); - void run(int); -}; - -class CV_VideoRandomPositioningTest: public CV_VideoPositioningTest -{ -public: - CV_VideoRandomPositioningTest(): CV_VideoPositioningTest() { } - ~CV_VideoRandomPositioningTest(); - void run(int); -}; - -CV_VideoPositioningTest::CV_VideoPositioningTest() {} -CV_VideoPositioningTest::~CV_VideoPositioningTest() {} -CV_VideoProgressivePositioningTest::~CV_VideoProgressivePositioningTest() {} -CV_VideoRandomPositioningTest::~CV_VideoRandomPositioningTest() {} - -void CV_VideoPositioningTest::generate_idx_seq(CvCapture* cap, int method) -{ - idx.clear(); - int N = (int)cvGetCaptureProperty(cap, CAP_PROP_FRAME_COUNT); - switch(method) - { - case PROGRESSIVE: - { - int pos = 1, step = 20; - do - { - idx.push_back(pos); - pos += step; - } - while (pos <= N); - break; - } - case RANDOM: - { - RNG rng(N); - idx.clear(); - for( int i = 0; i >= 0 && i < N-1; i++ ) - idx.push_back(rng.uniform(0, N)); - idx.push_back(N-1); - std::swap(idx.at(rng.uniform(0, N-1)), idx.at(N-1)); - break; - } - default:break; - } -} - -void CV_VideoPositioningTest::run_test(int method) -{ - const string& src_dir = ts->get_data_path(); - - ts->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str()); - - const string ext[] = {"avi", "mov", "mp4", "mpg"}; - - int n = (int)(sizeof(ext)/sizeof(ext[0])); - - int failed_videos = 0; - - for (int i = 0; i < n; ++i) - { - // skip random positioning test in plain mpegs - if( method == RANDOM && ext[i] == "mpg" ) - continue; - string file_path = src_dir + "video/big_buck_bunny." + ext[i]; - - ts->printf(cvtest::TS::LOG, "\nReading video file in %s...\n", file_path.c_str()); - - CvCapture* cap = cvCreateFileCapture(file_path.c_str()); - - if (!cap) - { - ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str()); - ts->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n"); - ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA); - failed_videos++; continue; - } - - cvSetCaptureProperty(cap, CAP_PROP_POS_FRAMES, 0); - - generate_idx_seq(cap, method); - - int N = (int)idx.size(), failed_frames = 0, failed_positions = 0, failed_iterations = 0; - - for (int j = 0; j < N; ++j) - { - bool flag = false; - - cvSetCaptureProperty(cap, CAP_PROP_POS_FRAMES, idx.at(j)); - - /* IplImage* frame = cvRetrieveFrame(cap); - - if (!frame) - { - if (!failed_frames) - { - ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\n", i+1, ext[i].c_str()); - } - failed_frames++; - ts->printf(cvtest::TS::LOG, "\nIteration: %d\n\nError: cannot read a frame with index %d.\n", j, idx.at(j)); - ts->set_failed_test_info(cvtest::TS::FAIL_EXCEPTION); - flag = !flag; - } */ - - int val = (int)cvGetCaptureProperty(cap, CAP_PROP_POS_FRAMES); - - if (idx.at(j) != val) - { - if (!(failed_frames||failed_positions)) - { - ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\n", i+1, ext[i].c_str()); - } - failed_positions++; - if (!failed_frames) - { - ts->printf(cvtest::TS::LOG, "\nIteration: %d\n", j); - } - ts->printf(cvtest::TS::LOG, "Required pos: %d\nReturned pos: %d\n", idx.at(j), val); - ts->printf(cvtest::TS::LOG, "Error: required and returned positions are not matched.\n"); - ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT); - flag = true; - } - - if (flag) - { - failed_iterations++; - failed_videos++; - break; - } - } - - cvReleaseCapture(&cap); - } - - ts->printf(cvtest::TS::LOG, "\nSuccessfull experiments: %d (%d%%)\n", n-failed_videos, 100*(n-failed_videos)/n); - ts->printf(cvtest::TS::LOG, "Failed experiments: %d (%d%%)\n", failed_videos, 100*failed_videos/n); -} - -void CV_VideoProgressivePositioningTest::run(int) -{ - run_test(PROGRESSIVE); -} - -void CV_VideoRandomPositioningTest::run(int) -{ - run_test(RANDOM); -} - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT && defined HAVE_FFMPEG -TEST (Videoio_Video, seek_progressive) { CV_VideoProgressivePositioningTest test; test.safe_run(); } -TEST (Videoio_Video, seek_random) { CV_VideoRandomPositioningTest test; test.safe_run(); } -#endif diff --git a/modules/videoio/test/test_precomp.hpp b/modules/videoio/test/test_precomp.hpp index a6a5b44..a7706fd 100644 --- a/modules/videoio/test/test_precomp.hpp +++ b/modules/videoio/test/test_precomp.hpp @@ -18,74 +18,29 @@ #include "opencv2/core/private.hpp" -#if defined(HAVE_DSHOW) || \ - defined(HAVE_TYZX) || \ - defined(HAVE_VFW) || \ - defined(HAVE_LIBV4L) || \ - (defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2)) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_DC1394_2) || \ - defined(HAVE_DC1394) || \ - defined(HAVE_CMU1394) || \ - defined(HAVE_MIL) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_UNICAP) || \ - defined(HAVE_PVAPI) || \ - defined(HAVE_OPENNI) || \ - defined(HAVE_XIMEA) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_GIGE_API) || \ - defined(HAVE_INTELPERC) || \ - defined(HAVE_GPHOTO2) || \ - (0) -# define BUILD_WITH_CAMERA_SUPPORT 1 -#else -# define BUILD_WITH_CAMERA_SUPPORT 0 -#endif - -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - /*defined(HAVE_OPENNI) || too specialized */ \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0 -#endif - -#if /*defined(HAVE_XINE) || */\ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) -# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1 -#else -# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0 -#endif - -namespace cvtest +inline std::string fourccToString(int fourcc) { + return cv::format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255); +} -string fourccToString(int fourcc); - -struct VideoFormat +inline int fourccFromString(const std::string &fourcc) { - VideoFormat() { fourcc = -1; } - VideoFormat(const string& _ext, int _fourcc) : ext(_ext), fourcc(_fourcc) {} - bool empty() const { return ext.empty(); } - - string ext; - int fourcc; -}; - -extern const VideoFormat g_specific_fmt_list[]; + if (fourcc.size() != 4) return 0; + return cv::VideoWriter::fourcc(fourcc[0], fourcc[1], fourcc[2], fourcc[3]); +} +inline void generateFrame(int i, int FRAME_COUNT, cv::Mat & frame) +{ + using namespace cv; + using namespace std; + frame = Scalar(30, 140, 10); + ostringstream buf; buf << "Frame " << setw(2) << setfill('0') << i + 1; + int baseLine = 0; + Size box = getTextSize(buf.str(), FONT_HERSHEY_COMPLEX, 2, 5, &baseLine); + putText(frame, buf.str(), Point((frame.cols - box.width) / 2, (frame.rows - box.height) / 2 + baseLine), + FONT_HERSHEY_COMPLEX, 2, Scalar(255, 255, 255), 5, LINE_AA); + Point p(i * frame.cols / (FRAME_COUNT - 1), i * frame.rows / (FRAME_COUNT - 1)); + circle(frame, p, 20, Scalar(200, 25, 55), 5, LINE_AA); } #endif diff --git a/modules/videoio/test/test_video_io.cpp b/modules/videoio/test/test_video_io.cpp index ba50b4b..b8bb422 100644 --- a/modules/videoio/test/test_video_io.cpp +++ b/modules/videoio/test/test_video_io.cpp @@ -42,546 +42,266 @@ #include "test_precomp.hpp" #include "opencv2/videoio/videoio_c.h" +#include "opencv2/highgui.hpp" +#include using namespace cv; using namespace std; +using namespace std::tr1; -namespace cvtest -{ - -string fourccToString(int fourcc) -{ - return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255); -} - -#ifdef HAVE_MSMF -const VideoFormat g_specific_fmt_list[] = -{ - /*VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', '2', '5')), - VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', '5', '0')), - VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 'c', ' ')), - VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 'h', '1')), - VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 'h', 'd')), - VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 's', 'd')), - VideoFormat("wmv", CV_FOURCC_MACRO('d', 'v', 's', 'l')), - VideoFormat("wmv", CV_FOURCC_MACRO('H', '2', '6', '3')), - VideoFormat("wmv", CV_FOURCC_MACRO('M', '4', 'S', '2')), - VideoFormat("avi", CV_FOURCC_MACRO('M', 'J', 'P', 'G')), - VideoFormat("mp4", CV_FOURCC_MACRO('M', 'P', '4', 'S')), - VideoFormat("mp4", CV_FOURCC_MACRO('M', 'P', '4', 'V')), - VideoFormat("wmv", CV_FOURCC_MACRO('M', 'P', '4', '3')), - VideoFormat("wmv", CV_FOURCC_MACRO('M', 'P', 'G', '1')), - VideoFormat("wmv", CV_FOURCC_MACRO('M', 'S', 'S', '1')), - VideoFormat("wmv", CV_FOURCC_MACRO('M', 'S', 'S', '2')),*/ -#if !defined(_M_ARM) - VideoFormat("wmv", CV_FOURCC_MACRO('W', 'M', 'V', '1')), - VideoFormat("wmv", CV_FOURCC_MACRO('W', 'M', 'V', '2')), -#endif - VideoFormat("wmv", CV_FOURCC_MACRO('W', 'M', 'V', '3')), - VideoFormat("avi", CV_FOURCC_MACRO('H', '2', '6', '4')), - //VideoFormat("wmv", CV_FOURCC_MACRO('W', 'V', 'C', '1')), - VideoFormat() -}; -#else -const VideoFormat g_specific_fmt_list[] = -{ - VideoFormat("avi", VideoWriter::fourcc('X', 'V', 'I', 'D')), - VideoFormat("avi", VideoWriter::fourcc('M', 'P', 'E', 'G')), - VideoFormat("avi", VideoWriter::fourcc('M', 'J', 'P', 'G')), - //VideoFormat("avi", VideoWriter::fourcc('I', 'Y', 'U', 'V')), - VideoFormat("mkv", VideoWriter::fourcc('X', 'V', 'I', 'D')), - VideoFormat("mkv", VideoWriter::fourcc('M', 'P', 'E', 'G')), - VideoFormat("mkv", VideoWriter::fourcc('M', 'J', 'P', 'G')), -#ifndef HAVE_GSTREAMER - VideoFormat("mov", VideoWriter::fourcc('m', 'p', '4', 'v')), -#endif - VideoFormat() -}; -#endif - -} - -class CV_VideoIOTest : public cvtest::BaseTest +class Videoio_Test_Base { protected: - void ImageTest (const string& dir); - void VideoTest (const string& dir, const cvtest::VideoFormat& fmt); - void SpecificImageTest (const string& dir); - void SpecificVideoTest (const string& dir, const cvtest::VideoFormat& fmt); - - CV_VideoIOTest() {} - ~CV_VideoIOTest() {} - virtual void run(int) = 0; -}; - -class CV_ImageTest : public CV_VideoIOTest -{ -public: - CV_ImageTest() {} - ~CV_ImageTest() {} - void run(int); -}; - -class CV_SpecificImageTest : public CV_VideoIOTest -{ -public: - CV_SpecificImageTest() {} - ~CV_SpecificImageTest() {} - void run(int); -}; - -class CV_VideoTest : public CV_VideoIOTest -{ -public: - CV_VideoTest() {} - ~CV_VideoTest() {} - void run(int); -}; - -class CV_SpecificVideoTest : public CV_VideoIOTest -{ -public: - CV_SpecificVideoTest() {} - ~CV_SpecificVideoTest() {} - void run(int); -}; - - -void CV_VideoIOTest::ImageTest(const string& dir) -{ - string _name = dir + string("../cv/shared/baboon.png"); - ts->printf(ts->LOG, "reading image : %s\n", _name.c_str()); - - Mat image = imread(_name); - image.convertTo(image, CV_8UC3); - - if (image.empty()) + string ext; + string video_file; +protected: + Videoio_Test_Base() {} + virtual ~Videoio_Test_Base() {} + virtual void checkFrameContent(Mat &, int) {} + virtual void checkFrameCount(int &) {} + void checkFrameRead(int idx, VideoCapture & cap) { - ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); - return; + Mat img; cap >> img; + ASSERT_FALSE(img.empty()); + checkFrameContent(img, idx); } - - const string exts[] = { -#ifdef HAVE_PNG - "png", -#endif -#ifdef HAVE_TIFF - "tiff", -#endif -#ifdef HAVE_JPEG - "jpg", -#endif -#ifdef HAVE_JASPER - "jp2", -#endif -#if 0 /*defined HAVE_OPENEXR && !defined __APPLE__*/ - "exr", -#endif - "bmp", - "ppm", - "ras" - }; - const size_t ext_num = sizeof(exts)/sizeof(exts[0]); - - for(size_t i = 0; i < ext_num; ++i) + void checkFrameSeek(int idx, VideoCapture & cap) { - string ext = exts[i]; - string full_name = cv::tempfile(ext.c_str()); - 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=%s\n", ext.c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - continue; - } - - const double thresDbell = 20; - double psnr = cvtest::PSNR(loaded, image); - if (psnr < thresDbell) - { - ts->printf(ts->LOG, "Reading image from file: too big difference (=%g) with fmt=%s\n", psnr, ext.c_str()); - 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); + ASSERT_TRUE(cap.set(CAP_PROP_POS_FRAMES, idx)); + ASSERT_EQ(idx, (int)cap.get(CAP_PROP_POS_FRAMES)); + checkFrameRead(idx, cap); + } +public: + void doTest() + { + VideoCapture cap(video_file); + ASSERT_TRUE(cap.isOpened()); - vector buf; - imencode("." + exts[i], image, buf); + int n_frames = (int)cap.get(CAP_PROP_FRAME_COUNT); + ASSERT_GT(n_frames, 0); + checkFrameCount(n_frames); - if (buf != from_file) { - ts->printf(ts->LOG, "Encoding failed with fmt=%s\n", ext.c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - continue; + SCOPED_TRACE("consecutive read"); + for (int k = 0; k < n_frames; ++k) + { + checkFrameRead(k, cap); + } } - Mat buf_loaded = imdecode(Mat(buf), 1); - - if (buf_loaded.empty()) + if (ext != "mpg" && ext != "wmv") { - ts->printf(ts->LOG, "Decoding failed with fmt=%s\n", ext.c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - continue; + SCOPED_TRACE("random seek"); + ASSERT_TRUE(cap.set(CAP_PROP_POS_FRAMES, 0)); + for (int k = 0; k < 10; ++k) + { + checkFrameSeek(cvtest::TS::ptr()->get_rng().uniform(0, n_frames), cap); + } } - psnr = cvtest::PSNR(buf_loaded, image); - - if (psnr < thresDbell) + if (ext != "wmv") { - ts->printf(ts->LOG, "Decoding image from memory: too small PSNR (=%gdb) with fmt=%s\n", psnr, ext.c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - continue; + SCOPED_TRACE("progressive seek"); + ASSERT_TRUE(cap.set(CAP_PROP_POS_FRAMES, 0)); + for (int k = 1; k < n_frames; k += 20) + { + checkFrameSeek(k, cap); + } } - } +}; - ts->printf(ts->LOG, "end test function : ImagesTest \n"); - ts->set_failed_test_info(ts->OK); -} - +//================================================================================================== -void CV_VideoIOTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt) +class Videoio_Bunny : public Videoio_Test_Base, public testing::TestWithParam { - string src_file = dir + "../cv/shared/video_for_test.avi"; - string tmp_name = cv::tempfile((cvtest::fourccToString(fmt.fourcc) + "." + fmt.ext).c_str()); - - ts->printf(ts->LOG, "reading video : %s and converting it to %s\n", src_file.c_str(), tmp_name.c_str()); - - CvCapture* cap = cvCaptureFromFile(src_file.c_str()); - - if (!cap) +public: + Videoio_Bunny() { - ts->set_failed_test_info(ts->FAIL_MISMATCH); - return; + ext = GetParam(); + video_file = cvtest::TS::ptr()->get_data_path() + "video/big_buck_bunny." + ext; } - - CvVideoWriter* writer = 0; - vector frames; - - for(;;) + void doFrameCountTest() { - IplImage* img = cvQueryFrame( cap ); - - if (!img) - break; - - frames.push_back(cv::cvarrToMat(img, true)); - - if (writer == NULL) + VideoCapture cap(video_file); + ASSERT_TRUE(cap.isOpened()); + + const int width_gt = 672; + const int height_gt = 384; + const int fps_gt = 24; + const double time_gt = 5.21; + const int count_gt = cvRound(fps_gt * time_gt); // 5.21 sec * 24 fps + + EXPECT_EQ(width_gt, cap.get(CAP_PROP_FRAME_WIDTH)); + EXPECT_EQ(height_gt, cap.get(CAP_PROP_FRAME_HEIGHT)); + + int fps_prop = (int)cap.get(CAP_PROP_FPS); + EXPECT_EQ(fps_gt, fps_prop); + + int count_prop = (int)cap.get(CAP_PROP_FRAME_COUNT); + ASSERT_GT(count_prop, 0); + // mpg file reports 5.08 sec * 24 fps => property returns 122 frames + // but actual number of frames returned is 125 + if (ext != "mpg") { - writer = cvCreateVideoWriter(tmp_name.c_str(), fmt.fourcc, 24, cvGetSize(img)); - if (writer == NULL) - { - ts->printf(ts->LOG, "can't create writer (with fourcc : %s)\n", - cvtest::fourccToString(fmt.fourcc).c_str()); - cvReleaseCapture( &cap ); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - return; - } + EXPECT_EQ(count_gt, count_prop); } - cvWriteFrame(writer, img); + int count_actual = 0; + while (cap.isOpened()) + { + Mat frame; + cap >> frame; + if (frame.empty()) + break; + EXPECT_EQ(width_gt, frame.cols); + EXPECT_EQ(height_gt, frame.rows); + count_actual += 1; + } + EXPECT_EQ(count_gt, count_actual); } +}; - cvReleaseVideoWriter( &writer ); - cvReleaseCapture( &cap ); +typedef tuple Ext_Fourcc_PSNR; +typedef tuple Size_Ext_Fourcc_PSNR; - CvCapture *saved = cvCaptureFromFile(tmp_name.c_str()); - if (!saved) +class Videoio_Synthetic : public Videoio_Test_Base, public testing::TestWithParam +{ + Size frame_size; + int fourcc; + float PSNR_GT; + int frame_count; + double fps; +public: + Videoio_Synthetic() { - ts->set_failed_test_info(ts->FAIL_MISMATCH); - return; + frame_size = get<0>(GetParam()); + const Ext_Fourcc_PSNR ¶m = get<1>(GetParam()); + ext = get<0>(param); + fourcc = fourccFromString(get<1>(param)); + PSNR_GT = get<2>(param); + video_file = cv::tempfile((fourccToString(fourcc) + "." + ext).c_str()); + frame_count = 100; + fps = 25.; } - - const double thresDbell = 20; - - for(int i = 0;; i++) + void SetUp() { - IplImage* ipl1 = cvQueryFrame( saved ); - - if (!ipl1) - break; - - Mat img = frames[i]; - Mat img1 = cv::cvarrToMat(ipl1); - - double psnr = cvtest::PSNR(img1, img); - if (psnr < thresDbell) + Mat img(frame_size, CV_8UC3); + VideoWriter writer(video_file, fourcc, fps, frame_size, true); + ASSERT_TRUE(writer.isOpened()); + for(int i = 0; i < frame_count; ++i ) { - ts->printf(ts->LOG, "Too low frame %d psnr = %gdb\n", i, psnr); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - - //imwrite("original.png", img); - //imwrite("after_test.png", img1); - //Mat diff; - //absdiff(img, img1, diff); - //imwrite("diff.png", diff); - - break; + generateFrame(i, frame_count, img); + writer << img; } + writer.release(); } - - cvReleaseCapture( &saved ); - - ts->printf(ts->LOG, "end test function : ImagesVideo \n"); -} - -void CV_VideoIOTest::SpecificImageTest(const string& dir) -{ - const size_t IMAGE_COUNT = 10; - - for (size_t i = 0; i < IMAGE_COUNT; ++i) + void TearDown() { - 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; - } - - resize(image, image, Size(968, 757), 0.0, 0.0, INTER_CUBIC); - - stringstream s_digit; s_digit << i; - - string full_name = cv::tempfile((s_digit.str() + ".bmp").c_str()); - 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 = cvtest::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 = cvtest::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; - } + remove(video_file.c_str()); } - - ts->printf(ts->LOG, "end test function : SpecificImageTest \n"); - ts->set_failed_test_info(ts->OK); -} - - -void CV_VideoIOTest::SpecificVideoTest(const string& dir, const cvtest::VideoFormat& fmt) -{ - string ext = fmt.ext; - int fourcc = fmt.fourcc; - - string fourcc_str = cvtest::fourccToString(fourcc); - const string video_file = cv::tempfile((fourcc_str + "." + ext).c_str()); - - Size frame_size(968 & -2, 757 & -2); - VideoWriter writer(video_file, fourcc, 25, frame_size, true); - - if (!writer.isOpened()) + virtual void checkFrameContent(Mat & img, int idx) { - // call it repeatedly for easier debugging - VideoWriter writer2(video_file, fourcc, 25, frame_size, true); - ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); - ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - return; + Mat imgGT(frame_size, CV_8UC3); + generateFrame(idx, frame_count, imgGT); + double psnr = cvtest::PSNR(img, imgGT); + ASSERT_GT(psnr, PSNR_GT) << "frame " << idx; } - - const size_t IMAGE_COUNT = 30; - vector images; - - for( size_t i = 0; i < IMAGE_COUNT; ++i ) + virtual void checkFrameCount(int &actual) { - string file_path = format("%s../python/images/QCIF_%02d.bmp", dir.c_str(), i); - Mat img = imread(file_path, IMREAD_COLOR); - - if (img.empty()) - { - ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); - ts->printf(ts->LOG, "Error: cannot read frame from %s.\n", file_path.c_str()); - ts->printf(ts->LOG, "Continue creating the video file...\n"); - ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); - break; - } - - for (int k = 0; k < img.rows; ++k) - for (int l = 0; l < img.cols; ++l) - if (img.at(k, l) == Vec3b::all(0)) - img.at(k, l) = Vec3b(0, 255, 0); - else img.at(k, l) = Vec3b(0, 0, 255); + Range expected_frame_count = Range(frame_count, frame_count); + + // Hack! Newer FFmpeg versions in this combination produce a file + // whose reported duration is one frame longer than needed, and so + // the calculated frame count is also off by one. Ideally, we'd want + // to fix both writing (to produce the correct duration) and reading + // (to correctly report frame count for such files), but I don't know + // how to do either, so this is a workaround for now. + if (fourcc == VideoWriter::fourcc('M', 'P', 'E', 'G') && ext == "mkv") + expected_frame_count.end += 1; + + // Hack! Some GStreamer encoding pipelines drop last frame in the video +#ifdef HAVE_GSTREAMER + expected_frame_count.start -= 1; +#endif - resize(img, img, frame_size, 0.0, 0.0, INTER_CUBIC); + ASSERT_LE(expected_frame_count.start, actual); + ASSERT_GE(expected_frame_count.end, actual); - images.push_back(img); - writer << img; + actual = expected_frame_count.start; // adjust actual frame boundary to possible minimum } +}; - writer.release(); - VideoCapture cap(video_file); - - size_t FRAME_COUNT = (size_t)cap.get(CAP_PROP_FRAME_COUNT); - - size_t allowed_extra_frames = 0; +//================================================================================================== - // Hack! Newer FFmpeg versions in this combination produce a file - // whose reported duration is one frame longer than needed, and so - // the calculated frame count is also off by one. Ideally, we'd want - // to fix both writing (to produce the correct duration) and reading - // (to correctly report frame count for such files), but I don't know - // how to do either, so this is a workaround for now. - // See also the same hack in CV_PositioningTest::run. - if (fourcc == VideoWriter::fourcc('M', 'P', 'E', 'G') && ext == "mkv") - allowed_extra_frames = 1; - // Hack! Some GStreamer encoding pipelines drop last frame in the video - int allowed_frame_frop = 0; -#ifdef HAVE_GSTREAMER - allowed_frame_frop = 1; +string bunny_params[] = { +#ifdef HAVE_VIDEO_INPUT + string("avi"), + string("mov"), + string("mp4"), + string("mpg"), + string("wmv"), #endif + string("mjpg.avi") +}; - if (FRAME_COUNT < IMAGE_COUNT - allowed_frame_frop || FRAME_COUNT > IMAGE_COUNT + allowed_extra_frames) - { - ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); - if (allowed_extra_frames != 0) - ts->printf(ts->LOG, "Required frame count: %d-%d; Returned frame count: %d\n", - IMAGE_COUNT, IMAGE_COUNT + allowed_extra_frames, FRAME_COUNT); - else - 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->printf(ts->LOG, "Continue checking...\n"); - ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); - return; - } +TEST_P(Videoio_Bunny, read_position) { doTest(); } - for (int i = 0; (size_t)i < IMAGE_COUNT-allowed_frame_frop; i++) - { - Mat frame; cap >> frame; - if (frame.empty()) - { - ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); - ts->printf(ts->LOG, "File name: video_%s.%s\n", fourcc_str.c_str(), ext.c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); - ts->printf(ts->LOG, "Error: cannot read the next frame with index %d.\n", i+1); - ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); - break; - } +TEST_P(Videoio_Bunny, frame_count) { doFrameCountTest(); } - Mat img = images[i]; +INSTANTIATE_TEST_CASE_P(videoio, Videoio_Bunny, + testing::ValuesIn(bunny_params)); - const double thresDbell = 40; - double psnr = cvtest::PSNR(img, frame); - if (psnr > thresDbell) - { - ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); - ts->printf(ts->LOG, "Frame index: %d\n", i+1); - ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); - ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell); - ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); - break; - } - } -} +//================================================================================================== -void CV_ImageTest::run(int) +inline Ext_Fourcc_PSNR makeParam(const char * ext, const char * fourcc, float psnr) { - ImageTest(ts->get_data_path()); + return make_tuple(string(ext), string(fourcc), (float)psnr); } -void CV_SpecificImageTest::run(int) -{ - SpecificImageTest(ts->get_data_path()); -} +Ext_Fourcc_PSNR synthetic_params[] = { -void CV_VideoTest::run(int) -{ - for (int i = 0; ; ++i) - { - const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[i]; - if( fmt.empty() ) - break; - VideoTest(ts->get_data_path(), fmt); - } -} +#if defined(HAVE_VIDEO_INPUT) && defined(HAVE_VIDEO_OUTPUT) && !defined(__APPLE__) -void CV_SpecificVideoTest::run(int) -{ - for (int i = 0; ; ++i) - { - const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[i]; - if( fmt.empty() ) - break; - SpecificVideoTest(ts->get_data_path(), fmt); - } -} +#ifdef HAVE_MSMF -#ifdef HAVE_JPEG -TEST(Videoio_Image, regression) { CV_ImageTest test; test.safe_run(); } +#if !defined(_M_ARM) + makeParam("wmv", "WMV1", 39.f), + makeParam("wmv", "WMV2", 39.f), #endif - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT && !defined(__APPLE__) -TEST(Videoio_Video, regression) { CV_VideoTest test; test.safe_run(); } -TEST(Videoio_Video, write_read) { CV_SpecificVideoTest test; test.safe_run(); } + makeParam("wmv", "WMV3", 39.f), + makeParam("avi", "H264", 39.f), + makeParam("wmv", "WVC1", 39.f), + +#else // HAVE_MSMF + + makeParam("avi", "XVID", 35.f), + makeParam("avi", "MPEG", 35.f), + makeParam("avi", "IYUV", 35.f), + makeParam("mkv", "XVID", 35.f), + makeParam("mkv", "MPEG", 35.f), + makeParam("mkv", "MJPG", 35.f), +#ifndef HAVE_GSTREAMER + makeParam("mov", "mp4v", 35.f), #endif -TEST(Videoio_Image, write_read) { CV_SpecificImageTest test; test.safe_run(); } +#endif // HAVE_MSMF + +#endif // HAVE_VIDEO_INPUT && HAVE_VIDEO_OUTPUT ... + + makeParam("avi", "MJPG", 41.f) +}; + +Size all_sizes[] = { + Size(640, 480), + Size(976, 768) +}; + +TEST_P(Videoio_Synthetic, write_read_position) { doTest(); } + +INSTANTIATE_TEST_CASE_P(videoio, Videoio_Synthetic, + testing::Combine( + testing::ValuesIn(all_sizes), + testing::ValuesIn(synthetic_params))); diff --git a/modules/videoio/test/test_video_pos.cpp b/modules/videoio/test/test_video_pos.cpp deleted file mode 100644 index cd21bc2..0000000 --- a/modules/videoio/test/test_video_pos.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// - // - // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. - // - // By downloading, copying, installing or using the software you agree to this license. - // If you do not agree to this license, do not download, install, - // copy or use the software. - // - // - // License Agreement - // For Open Source Computer Vision Library - // - // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. - // Copyright (C) 2009, Willow Garage Inc., all rights reserved. - // Third party copyrights are property of their respective owners. - // - // Redistribution and use in source and binary forms, with or without modification, - // are permitted provided that the following conditions are met: - // - // * Redistribution's of source code must retain the above copyright notice, - // this list of conditions and the following disclaimer. - // - // * Redistribution's in binary form must reproduce the above copyright notice, - // this list of conditions and the following disclaimer in the documentation - // and/or other materials provided with the distribution. - // - // * The name of the copyright holders may not be used to endorse or promote products - // derived from this software without specific prior written permission. - // - // This software is provided by the copyright holders and contributors "as is" and - // any express or implied warranties, including, but not limited to, the implied - // warranties of merchantability and fitness for a particular purpose are disclaimed. - // In no event shall the Intel Corporation or contributors be liable for any direct, - // indirect, incidental, special, exemplary, or consequential damages - // (including, but not limited to, procurement of substitute goods or services; - // loss of use, data, or profits; or business interruption) however caused - // and on any theory of liability, whether in contract, strict liability, - // or tort (including negligence or otherwise) arising in any way out of - // the use of this software, even if advised of the possibility of such damage. - // - //M*/ - -#include "test_precomp.hpp" -#include "opencv2/videoio.hpp" - -using namespace cv; -using namespace std; - -class CV_PositioningTest : public cvtest::BaseTest -{ -public: - CV_PositioningTest() - { - framesize = Size(640, 480); - } - - Mat drawFrame(int i) - { - Mat mat = Mat::zeros(framesize, CV_8UC3); - - mat = Scalar(fabs(cos(i*0.08)*255), fabs(sin(i*0.05)*255), i); - putText(mat, format("%03d", i), Point(10, 350), 0, 10, Scalar(128, 255, 255), 15); - return mat; - } - - string getFilename(const cvtest::VideoFormat& fmt) - { - return cv::tempfile((cvtest::fourccToString(fmt.fourcc) + "." + fmt.ext).c_str()); - } - - bool CreateTestVideo(const cvtest::VideoFormat& fmt, int framecount, string filename) - { - VideoWriter writer(filename, fmt.fourcc, 25, framesize, true); - if( !writer.isOpened() ) - return false; - - for (int i = 0; i < framecount; ++i) - { - Mat img = drawFrame(i); - writer << img; - } - return true; - } - - void run(int) - { - int n_frames = 100; - - for( int testcase = 0; ; testcase++ ) - { - const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[testcase]; - if( fmt.empty() ) - break; - string filename = getFilename(fmt); - ts->printf(ts->LOG, "\nFile: %s\n", filename.c_str()); - - if( !CreateTestVideo(fmt, n_frames, filename) ) - { - ts->printf(ts->LOG, "\nError: cannot create video file"); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - return; - } - - VideoCapture cap(filename); - - if (!cap.isOpened()) - { - ts->printf(ts->LOG, "\nError: cannot read video file."); - ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); - return; - } - - int N0 = (int)cap.get(CAP_PROP_FRAME_COUNT); - cap.set(CAP_PROP_POS_FRAMES, 0); - int N = (int)cap.get(CAP_PROP_FRAME_COUNT); - - // See the same hack in CV_VideoIOTest::SpecificVideoTest for explanation. - int allowed_extra_frames = 0; - if (fmt.fourcc == VideoWriter::fourcc('M', 'P', 'E', 'G') && fmt.ext == "mkv") - allowed_extra_frames = 1; - - if (N < n_frames || N > n_frames + allowed_extra_frames || N != N0) - { - ts->printf(ts->LOG, "\nError: returned frame count (N0=%d, N=%d) is different from the reference number %d\n", N0, N, n_frames); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - return; - } - - for (int k = 0; k < n_frames; ++k) - { - int idx = theRNG().uniform(0, n_frames); - - if( !cap.set(CAP_PROP_POS_FRAMES, idx) ) - { - ts->printf(ts->LOG, "\nError: cannot seek to frame %d.\n", idx); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - return; - } - - int idx1 = (int)cap.get(CAP_PROP_POS_FRAMES); - - Mat img; cap >> img; - Mat img0 = drawFrame(idx); - - if( idx != idx1 ) - { - ts->printf(ts->LOG, "\nError: the current position (%d) after seek is different from specified (%d)\n", - idx1, idx); - ts->printf(ts->LOG, "Saving both frames ...\n"); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - return; - } - - if (img.empty()) - { - ts->printf(ts->LOG, "\nError: cannot read a frame at position %d.\n", idx); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - return; - } - - double err = cvtest::PSNR(img, img0); - - if( err < 20 ) - { - ts->printf(ts->LOG, "The frame read after positioning to %d is incorrect (PSNR=%g)\n", idx, err); - ts->printf(ts->LOG, "Saving both frames ...\n"); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - return; - } - } - } - } - - Size framesize; -}; - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT && defined HAVE_FFMPEG -TEST(Videoio_Video, seek_random_synthetic) { CV_PositioningTest test; test.safe_run(); } -#endif -- 2.7.4