mirror of
https://github.com/opencv/opencv.git
synced 2025-01-18 22:44:02 +08:00
Merge pull request #19540 from asmorkalov:as/openexr_comression_options
OpenEXR compression options * Adding possibility to select the compression type for the OpenEXR format. There are compression modes other than the default that are more suited for certain data. Mainly grainy/noisy data. * Code review fixes. Co-authored-by: Daniel Rydstrom <daniel.rydstrom@sick.se>
This commit is contained in:
parent
ca7518c13b
commit
c131c12fd7
@ -95,6 +95,7 @@ enum ImwriteFlags {
|
||||
IMWRITE_PNG_BILEVEL = 18, //!< Binary level PNG, 0 or 1, default is 0.
|
||||
IMWRITE_PXM_BINARY = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1.
|
||||
IMWRITE_EXR_TYPE = (3 << 4) + 0, /* 48 */ //!< override EXR storage type (FLOAT (FP32) is default)
|
||||
IMWRITE_EXR_COMPRESSION = (3 << 4) + 1, /* 49 */ //!< override EXR compression type (ZIP_COMPRESSION = 3 is default)
|
||||
IMWRITE_WEBP_QUALITY = 64, //!< For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used.
|
||||
IMWRITE_PAM_TUPLETYPE = 128,//!< For PAM, sets the TUPLETYPE field to the corresponding string value that is defined for the format
|
||||
IMWRITE_TIFF_RESUNIT = 256,//!< For TIFF, use to specify which DPI resolution unit to set; see libtiff documentation for valid values
|
||||
@ -110,6 +111,19 @@ enum ImwriteEXRTypeFlags {
|
||||
IMWRITE_EXR_TYPE_FLOAT = 2 //!< store as FP32 (default)
|
||||
};
|
||||
|
||||
enum ImwriteEXRCompressionFlags {
|
||||
IMWRITE_EXR_COMPRESSION_NO = 0, //!< no compression
|
||||
IMWRITE_EXR_COMPRESSION_RLE = 1, //!< run length encoding
|
||||
IMWRITE_EXR_COMPRESSION_ZIPS = 2, //!< zlib compression, one scan line at a time
|
||||
IMWRITE_EXR_COMPRESSION_ZIP = 3, //!< zlib compression, in blocks of 16 scan lines
|
||||
IMWRITE_EXR_COMPRESSION_PIZ = 4, //!< piz-based wavelet compression
|
||||
IMWRITE_EXR_COMPRESSION_PXR24 = 5, //!< lossy 24-bit float compression
|
||||
IMWRITE_EXR_COMPRESSION_B44 = 6, //!< lossy 4-by-4 pixel block compression, fixed compression rate
|
||||
IMWRITE_EXR_COMPRESSION_B44A = 7, //!< lossy 4-by-4 pixel block compression, flat fields are compressed more
|
||||
IMWRITE_EXR_COMPRESSION_DWAA = 8, //!< lossy DCT based compression, in blocks of 32 scanlines. More efficient for partial buffer access.
|
||||
IMWRITE_EXR_COMPRESSION_DWAB = 9, //!< lossy DCT based compression, in blocks of 256 scanlines. More efficient space wise and faster to decode full frames than DWAA_COMPRESSION.
|
||||
};
|
||||
|
||||
//! Imwrite PNG specific flags used to tune the compression algorithm.
|
||||
/** These flags will be modify the way of PNG image compression and will be passed to the underlying zlib processing stage.
|
||||
|
||||
|
@ -589,7 +589,45 @@ bool ExrEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
type = FLOAT;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error( "IMWRITE_EXR_TYPE is invalid or not supported" );
|
||||
CV_Error(Error::StsBadArg, "IMWRITE_EXR_TYPE is invalid or not supported");
|
||||
}
|
||||
}
|
||||
if ( params[i] == IMWRITE_EXR_COMPRESSION )
|
||||
{
|
||||
switch ( params[i + 1] )
|
||||
{
|
||||
case IMWRITE_EXR_COMPRESSION_NO:
|
||||
header.compression() = NO_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_RLE:
|
||||
header.compression() = RLE_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_ZIPS:
|
||||
header.compression() = ZIPS_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_ZIP:
|
||||
header.compression() = ZIP_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_PIZ:
|
||||
header.compression() = PIZ_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_PXR24:
|
||||
header.compression() = PXR24_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_B44:
|
||||
header.compression() = B44_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_B44A:
|
||||
header.compression() = B44A_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_DWAA:
|
||||
header.compression() = DWAA_COMPRESSION;
|
||||
break;
|
||||
case IMWRITE_EXR_COMPRESSION_DWAB:
|
||||
header.compression() = DWAB_COMPRESSION;
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "IMWRITE_EXR_COMPRESSION is invalid or not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,17 @@
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
size_t getFileSize(const string& filename)
|
||||
{
|
||||
std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
|
||||
if (ifs.is_open())
|
||||
{
|
||||
ifs.seekg(0, std::ios::end);
|
||||
return ifs.tellg();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST(Imgcodecs_EXR, readWrite_32FC1)
|
||||
{
|
||||
const string root = cvtest::TS::ptr()->get_data_path();
|
||||
@ -23,6 +34,8 @@ TEST(Imgcodecs_EXR, readWrite_32FC1)
|
||||
ASSERT_EQ(CV_32FC1,img.type());
|
||||
|
||||
ASSERT_TRUE(cv::imwrite(filenameOutput, img));
|
||||
// Check generated file size to ensure that it's compressed with proper options
|
||||
ASSERT_EQ(396u, getFileSize(filenameOutput));
|
||||
const Mat img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED);
|
||||
ASSERT_EQ(img2.type(), img.type());
|
||||
ASSERT_EQ(img2.size(), img.size());
|
||||
@ -113,5 +126,29 @@ TEST(Imgcodecs_EXR, readWrite_32FC3_half)
|
||||
EXPECT_EQ(0, remove(filenameOutput.c_str()));
|
||||
}
|
||||
|
||||
TEST(Imgcodecs_EXR, readWrite_32FC1_PIZ)
|
||||
{
|
||||
const string root = cvtest::TS::ptr()->get_data_path();
|
||||
const string filenameInput = root + "readwrite/test32FC1.exr";
|
||||
const string filenameOutput = cv::tempfile(".exr");
|
||||
|
||||
|
||||
const Mat img = cv::imread(filenameInput, IMREAD_UNCHANGED);
|
||||
ASSERT_FALSE(img.empty());
|
||||
ASSERT_EQ(CV_32FC1, img.type());
|
||||
|
||||
std::vector<int> params;
|
||||
params.push_back(IMWRITE_EXR_COMPRESSION);
|
||||
params.push_back(IMWRITE_EXR_COMPRESSION_PIZ);
|
||||
ASSERT_TRUE(cv::imwrite(filenameOutput, img, params));
|
||||
// Check generated file size to ensure that it's compressed with proper options
|
||||
ASSERT_EQ(849u, getFileSize(filenameOutput));
|
||||
const Mat img2 = cv::imread(filenameOutput, IMREAD_UNCHANGED);
|
||||
ASSERT_EQ(img2.type(), img.type());
|
||||
ASSERT_EQ(img2.size(), img.size());
|
||||
EXPECT_LE(cvtest::norm(img, img2, NORM_INF | NORM_RELATIVE), 1e-3);
|
||||
EXPECT_EQ(0, remove(filenameOutput.c_str()));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user