mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
imgcodecs(test): rework common I/O test, added grayscale mode
This commit is contained in:
parent
222a48577f
commit
6d85fa3fd2
51
modules/imgcodecs/test/test_common.cpp
Normal file
51
modules/imgcodecs/test/test_common.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
#include "test_precomp.hpp"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
|
||||||
|
namespace opencv_test {
|
||||||
|
|
||||||
|
static
|
||||||
|
Mat generateTestImageBGR_()
|
||||||
|
{
|
||||||
|
Size sz(640, 480);
|
||||||
|
Mat result(sz, CV_8UC3, Scalar::all(0));
|
||||||
|
|
||||||
|
const string fname = cvtest::findDataFile("../cv/shared/baboon.png");
|
||||||
|
Mat image = imread(fname, IMREAD_COLOR);
|
||||||
|
CV_Assert(!image.empty());
|
||||||
|
CV_CheckEQ(image.size(), Size(512, 512), "");
|
||||||
|
Rect roi((640-512) / 2, 0, 512, 480);
|
||||||
|
image(Rect(0, 0, 512, 480)).copyTo(result(roi));
|
||||||
|
result(Rect(0, 0, 5, 5)).setTo(Scalar(0, 0, 255)); // R
|
||||||
|
result(Rect(5, 0, 5, 5)).setTo(Scalar(0, 255, 0)); // G
|
||||||
|
result(Rect(10, 0, 5, 5)).setTo(Scalar(255, 0, 0)); // B
|
||||||
|
result(Rect(0, 5, 5, 5)).setTo(Scalar(128, 128, 128)); // gray
|
||||||
|
//imshow("test_image", result); waitKey();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Mat generateTestImageBGR()
|
||||||
|
{
|
||||||
|
static Mat image = generateTestImageBGR_(); // initialize once
|
||||||
|
CV_Assert(!image.empty());
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
Mat generateTestImageGrayscale_()
|
||||||
|
{
|
||||||
|
Mat imageBGR = generateTestImageBGR();
|
||||||
|
CV_Assert(!imageBGR.empty());
|
||||||
|
|
||||||
|
Mat result;
|
||||||
|
cvtColor(imageBGR, result, COLOR_BGR2GRAY);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Mat generateTestImageGrayscale()
|
||||||
|
{
|
||||||
|
static Mat image = generateTestImageGrayscale_(); // initialize once
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
15
modules/imgcodecs/test/test_common.hpp
Normal file
15
modules/imgcodecs/test/test_common.hpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html
|
||||||
|
|
||||||
|
#ifndef OPENCV_TEST_IMGCODECS_COMMON_HPP
|
||||||
|
#define OPENCV_TEST_IMGCODECS_COMMON_HPP
|
||||||
|
|
||||||
|
namespace opencv_test {
|
||||||
|
|
||||||
|
Mat generateTestImageBGR();
|
||||||
|
Mat generateTestImageGrayscale();
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // OPENCV_TEST_IMGCODECS_COMMON_HPP
|
@ -2,6 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
// of this distribution and at http://opencv.org/license.html
|
// of this distribution and at http://opencv.org/license.html
|
||||||
#include "test_precomp.hpp"
|
#include "test_precomp.hpp"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
|
||||||
namespace opencv_test { namespace {
|
namespace opencv_test { namespace {
|
||||||
|
|
||||||
@ -145,45 +146,6 @@ TEST(Imgcodecs_Image, read_write_bmp)
|
|||||||
typedef string Ext;
|
typedef string Ext;
|
||||||
typedef testing::TestWithParam<Ext> Imgcodecs_Image;
|
typedef testing::TestWithParam<Ext> 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<uchar> 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<uchar> 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);
|
|
||||||
|
|
||||||
EXPECT_EQ(0, remove(full_name.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
const string exts[] = {
|
const string exts[] = {
|
||||||
#ifdef HAVE_PNG
|
#ifdef HAVE_PNG
|
||||||
"png",
|
"png",
|
||||||
@ -209,6 +171,90 @@ const string exts[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
void test_image_io(const Mat& image, const std::string& fname, const std::string& ext, int imreadFlag, double psnrThreshold)
|
||||||
|
{
|
||||||
|
vector<uchar> buf;
|
||||||
|
ASSERT_NO_THROW(imencode("." + ext, image, buf));
|
||||||
|
|
||||||
|
ASSERT_NO_THROW(imwrite(fname, image));
|
||||||
|
|
||||||
|
FILE *f = fopen(fname.c_str(), "rb");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long len = ftell(f);
|
||||||
|
cout << "File size: " << len << " bytes" << endl;
|
||||||
|
EXPECT_GT(len, 1024) << "File is small. Test or implementation is broken";
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
vector<uchar> file_buf((size_t)len);
|
||||||
|
EXPECT_EQ(len, (long)fread(&file_buf[0], 1, (size_t)len, f));
|
||||||
|
fclose(f); f = NULL;
|
||||||
|
|
||||||
|
EXPECT_EQ(buf, file_buf) << "imwrite() / imencode() calls must provide the same output (bit-exact)";
|
||||||
|
|
||||||
|
Mat buf_loaded = imdecode(Mat(buf), imreadFlag);
|
||||||
|
EXPECT_FALSE(buf_loaded.empty());
|
||||||
|
|
||||||
|
Mat loaded = imread(fname, imreadFlag);
|
||||||
|
EXPECT_FALSE(loaded.empty());
|
||||||
|
|
||||||
|
EXPECT_EQ(0, cv::norm(loaded, buf_loaded, NORM_INF)) << "imread() and imdecode() calls must provide the same result (bit-exact)";
|
||||||
|
|
||||||
|
double psnr = cvtest::PSNR(loaded, image);
|
||||||
|
EXPECT_GT(psnr, psnrThreshold);
|
||||||
|
|
||||||
|
// not necessary due bitexact check above
|
||||||
|
//double buf_psnr = cvtest::PSNR(buf_loaded, image);
|
||||||
|
//EXPECT_GT(buf_psnr, psnrThreshold);
|
||||||
|
|
||||||
|
#if 0 // debug
|
||||||
|
if (psnr <= psnrThreshold /*|| buf_psnr <= thresDbell*/)
|
||||||
|
{
|
||||||
|
cout << "File: " << fname << endl;
|
||||||
|
imshow("origin", image);
|
||||||
|
imshow("imread", loaded);
|
||||||
|
imshow("imdecode", buf_loaded);
|
||||||
|
waitKey();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Imgcodecs_Image, read_write_BGR)
|
||||||
|
{
|
||||||
|
const string ext = this->GetParam();
|
||||||
|
const string fname = cv::tempfile(ext.c_str());
|
||||||
|
|
||||||
|
double psnrThreshold = 100;
|
||||||
|
if (ext == "jpg")
|
||||||
|
psnrThreshold = 32;
|
||||||
|
|
||||||
|
Mat image = generateTestImageBGR();
|
||||||
|
EXPECT_NO_THROW(test_image_io(image, fname, ext, IMREAD_COLOR, psnrThreshold));
|
||||||
|
|
||||||
|
EXPECT_EQ(0, remove(fname.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(Imgcodecs_Image, read_write_GRAYSCALE)
|
||||||
|
{
|
||||||
|
const string ext = this->GetParam();
|
||||||
|
|
||||||
|
if (false
|
||||||
|
|| ext == "ppm" // grayscale is not implemented
|
||||||
|
|| ext == "ras" // broken (black result)
|
||||||
|
)
|
||||||
|
throw SkipTestException("GRAYSCALE mode is not supported");
|
||||||
|
|
||||||
|
const string fname = cv::tempfile(ext.c_str());
|
||||||
|
|
||||||
|
double psnrThreshold = 100;
|
||||||
|
if (ext == "jpg")
|
||||||
|
psnrThreshold = 40;
|
||||||
|
|
||||||
|
Mat image = generateTestImageGrayscale();
|
||||||
|
EXPECT_NO_THROW(test_image_io(image, fname, ext, IMREAD_GRAYSCALE, psnrThreshold));
|
||||||
|
|
||||||
|
EXPECT_EQ(0, remove(fname.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(imgcodecs, Imgcodecs_Image, testing::ValuesIn(exts));
|
INSTANTIATE_TEST_CASE_P(imgcodecs, Imgcodecs_Image, testing::ValuesIn(exts));
|
||||||
|
|
||||||
TEST(Imgcodecs_Image, regression_9376)
|
TEST(Imgcodecs_Image, regression_9376)
|
||||||
|
Loading…
Reference in New Issue
Block a user