1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge branch '4.x' into '5.x'

This commit is contained in:
Maksim Shabunin
2024-06-11 19:38:59 +03:00
573 changed files with 72922 additions and 7355 deletions
+1 -1
View File
@@ -729,7 +729,7 @@ bool ExrEncoder::write( const Mat& img, const std::vector<int>& params )
Mat exrMat;
if( type == HALF )
{
convertFp16(img, exrMat);
img.convertTo(exrMat, CV_16F);
buffer = (char *)const_cast<uchar *>( exrMat.ptr() );
bufferstep = exrMat.step;
size = 2;
+12 -4
View File
@@ -93,10 +93,18 @@ bool HdrDecoder::readData(Mat& _img)
RGBE_ReadPixels_RLE(file, const_cast<float*>(img.ptr<float>()), img.cols, img.rows);
fclose(file); file = NULL;
if(_img.depth() == img.depth()) {
img.convertTo(_img, _img.type());
} else {
img.convertTo(_img, _img.type(), 255);
// NOTE: 'img' has type CV32FC3
switch (_img.depth())
{
case CV_8U: img.convertTo(img, _img.depth(), 255); break;
case CV_32F: break;
default: CV_Error(Error::StsError, "Wrong expected image depth, allowed: CV_8U and CV_32F");
}
switch (_img.channels())
{
case 1: cvtColor(img, _img, COLOR_BGR2GRAY); break;
case 3: img.copyTo(_img); break;
default: CV_Error(Error::StsError, "Wrong expected image channels, allowed: 1 and 3");
}
return true;
}
+61 -32
View File
@@ -619,11 +619,6 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
std::vector<uchar> out_buf(1 << 12);
#ifndef JCS_EXTENSIONS
AutoBuffer<uchar> _buffer;
uchar* buffer;
#endif
struct jpeg_compress_struct cinfo;
JpegErrorMgr jerr;
JpegDestination dest;
@@ -658,14 +653,40 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
int _channels = img.channels();
int channels = _channels > 1 ? 3 : 1;
bool doDirectWrite = false;
switch( _channels )
{
case 1:
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
doDirectWrite = true; // GRAY -> GRAY
break;
case 3:
#ifdef JCS_EXTENSIONS
cinfo.input_components = _channels;
cinfo.in_color_space = _channels == 3 ? JCS_EXT_BGR
: _channels == 4 ? JCS_EXT_BGRX : JCS_GRAYSCALE;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_EXT_BGR;
doDirectWrite = true; // BGR -> BGR
#else
cinfo.input_components = channels;
cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
doDirectWrite = false; // BGR -> RGB
#endif
break;
case 4:
#ifdef JCS_EXTENSIONS
cinfo.input_components = 4;
cinfo.in_color_space = JCS_EXT_BGRX;
doDirectWrite = true; // BGRX -> BGRX
#else
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
doDirectWrite = false; // BGRA -> RGB
#endif
break;
default:
CV_Error(cv::Error::StsError, cv::format("Unsupported number of _channels: %06d", _channels) );
break;
}
int quality = 95;
int progressive = 0;
@@ -762,9 +783,9 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
cinfo.comp_info[1].h_samp_factor = 1;
}
#if JPEG_LIB_VERSION >= 70
if (luma_quality >= 0 && chroma_quality >= 0)
{
#if JPEG_LIB_VERSION >= 70
cinfo.q_scale_factor[0] = jpeg_quality_scaling(luma_quality);
cinfo.q_scale_factor[1] = jpeg_quality_scaling(chroma_quality);
if ( luma_quality != chroma_quality )
@@ -776,35 +797,43 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
cinfo.comp_info[1].h_samp_factor = 1;
}
jpeg_default_qtables( &cinfo, TRUE );
}
#else
// See https://github.com/opencv/opencv/issues/25646
CV_LOG_ONCE_WARNING(NULL, cv::format("IMWRITE_JPEG_LUMA/CHROMA_QUALITY are not supported bacause JPEG_LIB_VERSION < 70."));
#endif // #if JPEG_LIB_VERSION >= 70
}
jpeg_start_compress( &cinfo, TRUE );
#ifndef JCS_EXTENSIONS
if( channels > 1 )
_buffer.allocate(width*channels);
buffer = _buffer.data();
#endif
for( int y = 0; y < height; y++ )
if( doDirectWrite )
{
uchar *data = img.data + img.step*y, *ptr = data;
#ifndef JCS_EXTENSIONS
if( _channels == 3 )
for( int y = 0; y < height; y++ )
{
icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, Size(width,1) );
ptr = buffer;
uchar *data = const_cast<uchar*>(img.ptr<uchar>(y));
jpeg_write_scanlines( &cinfo, &data, 1 );
}
else if( _channels == 4 )
{
icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, Size(width,1), 2 );
ptr = buffer;
}
#endif
}
else
{
CV_Check(_channels, (_channels == 3) || (_channels == 4), "Unsupported number of channels(indirect write)");
jpeg_write_scanlines( &cinfo, &ptr, 1 );
AutoBuffer<uchar> _buffer;
_buffer.allocate(width*channels);
uchar *buffer = _buffer.data();
for( int y = 0; y < height; y++ )
{
uchar *data = const_cast<uchar*>(img.ptr<uchar>(y));
if( _channels == 3 )
{
icvCvt_BGR2RGB_8u_C3R( data, 0, buffer, 0, Size(width,1) );
}
else // if( _channels == 4 )
{
icvCvt_BGRA2BGR_8u_C4C3R( data, 0, buffer, 0, Size(width,1), 2 );
}
jpeg_write_scanlines( &cinfo, &buffer, 1 );
}
}
jpeg_finish_compress( &cinfo );
+31 -66
View File
@@ -81,6 +81,22 @@ static Size validateInputImageSize(const Size& size)
}
static inline int calcType(int type, int flags)
{
if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
{
if( (flags & IMREAD_ANYDEPTH) == 0 )
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if( (flags & IMREAD_COLOR) != 0 ||
((flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) )
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
return type;
}
namespace {
class ByteStreamBuffer: public std::streambuf
@@ -328,7 +344,7 @@ static ImageEncoder findEncoder( const String& _ext )
}
static void ExifTransform(int orientation, Mat& img)
static void ExifTransform(int orientation, OutputArray img)
{
switch( orientation )
{
@@ -365,7 +381,7 @@ static void ExifTransform(int orientation, Mat& img)
}
}
static void ApplyExifOrientation(ExifEntry_t orientationTag, Mat& img)
static void ApplyExifOrientation(ExifEntry_t orientationTag, OutputArray img)
{
int orientation = IMAGE_ORIENTATION_TL;
@@ -385,7 +401,7 @@ static void ApplyExifOrientation(ExifEntry_t orientationTag, Mat& img)
*
*/
static bool
imread_( const String& filename, int flags, Mat& mat )
imread_( const String& filename, int flags, OutputArray mat )
{
/// Search for the relevant decoder to handle the imagery
ImageDecoder decoder;
@@ -444,18 +460,7 @@ imread_( const String& filename, int flags, Mat& mat )
Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
// grab the decoded type
int type = decoder->type();
if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
{
if( (flags & IMREAD_ANYDEPTH) == 0 )
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if( (flags & IMREAD_COLOR) != 0 ||
((flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) )
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
const int type = calcType(decoder->type(), flags);
if (mat.empty())
{
@@ -469,11 +474,16 @@ imread_( const String& filename, int flags, Mat& mat )
}
// read the image data
Mat real_mat = mat.getMat();
const void * original_ptr = real_mat.data;
bool success = false;
try
{
if (decoder->readData(mat))
if (decoder->readData(real_mat))
{
CV_CheckTrue(original_ptr == real_mat.data, "Internal imread issue");
success = true;
}
}
catch (const cv::Exception& e)
{
@@ -567,18 +577,7 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats, int star
while (current < count)
{
// grab the decoded type
int type = decoder->type();
if ((flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED)
{
if ((flags & IMREAD_ANYDEPTH) == 0)
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if ((flags & IMREAD_COLOR) != 0 ||
((flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1))
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
const int type = calcType(decoder->type(), flags);
// established the required input image size
Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
@@ -645,10 +644,8 @@ void imread( const String& filename, OutputArray dst, int flags )
{
CV_TRACE_FUNCTION();
Mat img = dst.getMat();
/// load the data
imread_(filename, flags, img);
imread_(filename, flags, dst);
}
/**
@@ -866,18 +863,7 @@ imdecode_( const Mat& buf, int flags, Mat& mat )
// established the required input image size
Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
int type = decoder->type();
if( (flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED )
{
if( (flags & IMREAD_ANYDEPTH) == 0 )
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if( (flags & IMREAD_COLOR) != 0 ||
((flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1) )
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
const int type = calcType(decoder->type(), flags);
mat.create( size.height, size.width, type );
@@ -1028,18 +1014,7 @@ imdecodemulti_(const Mat& buf, int flags, std::vector<Mat>& mats, int start, int
while (current < count)
{
// grab the decoded type
int type = decoder->type();
if ((flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && flags != IMREAD_UNCHANGED)
{
if ((flags & IMREAD_ANYDEPTH) == 0)
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if ((flags & IMREAD_COLOR) != 0 ||
((flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1))
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
const int type = calcType(decoder->type(), flags);
// established the required input image size
Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
@@ -1279,17 +1254,7 @@ bool ImageCollection::Impl::readHeader() {
// readHeader must be called before calling this method
Mat ImageCollection::Impl::readData() {
int type = m_decoder->type();
if ((m_flags & IMREAD_LOAD_GDAL) != IMREAD_LOAD_GDAL && m_flags != IMREAD_UNCHANGED) {
if ((m_flags & IMREAD_ANYDEPTH) == 0)
type = CV_MAKETYPE(CV_8U, CV_MAT_CN(type));
if ((m_flags & IMREAD_COLOR) != 0 ||
((m_flags & IMREAD_ANYCOLOR) != 0 && CV_MAT_CN(type) > 1))
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 3);
else
type = CV_MAKETYPE(CV_MAT_DEPTH(type), 1);
}
const int type = calcType(m_decoder->type(), m_flags);
// established the required input image size
Size size = validateInputImageSize(Size(m_width, m_height));