mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -3230,7 +3230,7 @@ Check @ref tutorial_homography "the corresponding tutorial" for more details.
|
||||
|
||||
This function extracts relative camera motion between two views of a planar object and returns up to
|
||||
four mathematical solution tuples of rotation, translation, and plane normal. The decomposition of
|
||||
the homography matrix H is described in detail in @cite Malis.
|
||||
the homography matrix H is described in detail in @cite Malis2007.
|
||||
|
||||
If the homography H, induced by the plane, gives the constraint
|
||||
\f[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\f] on the source image points
|
||||
@@ -3258,7 +3258,7 @@ CV_EXPORTS_W int decomposeHomographyMat(InputArray H,
|
||||
@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the #findHomography function
|
||||
|
||||
This function is intended to filter the output of the #decomposeHomographyMat based on additional
|
||||
information as described in @cite Malis . The summary of the method: the #decomposeHomographyMat function
|
||||
information as described in @cite Malis2007 . The summary of the method: the #decomposeHomographyMat function
|
||||
returns 2 unique solutions and their "opposites" for a total of 4 solutions. If we have access to the
|
||||
sets of points visible in the camera frame before and after the homography transformation is applied,
|
||||
we can determine which are the true potential solutions and which are the opposites by verifying which
|
||||
|
||||
@@ -71,7 +71,7 @@ data sharing. A destructor decrements the reference counter associated with the
|
||||
The buffer is deallocated if and only if the reference counter reaches zero, that is, when no other
|
||||
structures refer to the same buffer. Similarly, when a Mat instance is copied, no actual data is
|
||||
really copied. Instead, the reference counter is incremented to memorize that there is another owner
|
||||
of the same data. There is also the Mat::clone method that creates a full copy of the matrix data.
|
||||
of the same data. There is also the cv::Mat::clone method that creates a full copy of the matrix data.
|
||||
See the example below:
|
||||
```.cpp
|
||||
// create a big 8Mb matrix
|
||||
@@ -159,11 +159,11 @@ grayscale conversion. Note that frame and edges are allocated only once during t
|
||||
of the loop body since all the next video frames have the same resolution. If you somehow change the
|
||||
video resolution, the arrays are automatically reallocated.
|
||||
|
||||
The key component of this technology is the Mat::create method. It takes the desired array size and
|
||||
type. If the array already has the specified size and type, the method does nothing. Otherwise, it
|
||||
releases the previously allocated data, if any (this part involves decrementing the reference
|
||||
The key component of this technology is the cv::Mat::create method. It takes the desired array size
|
||||
and type. If the array already has the specified size and type, the method does nothing. Otherwise,
|
||||
it releases the previously allocated data, if any (this part involves decrementing the reference
|
||||
counter and comparing it with zero), and then allocates a new buffer of the required size. Most
|
||||
functions call the Mat::create method for each output array, and so the automatic output data
|
||||
functions call the cv::Mat::create method for each output array, and so the automatic output data
|
||||
allocation is implemented.
|
||||
|
||||
Some notable exceptions from this scheme are cv::mixChannels, cv::RNG::fill, and a few other
|
||||
@@ -247,9 +247,9 @@ Examples:
|
||||
// matrix (10-element complex vector)
|
||||
Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image
|
||||
// of 1920 columns and 1080 rows.
|
||||
Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of
|
||||
// the same size and same
|
||||
// channel type as img
|
||||
Mat grayscale(img.size(), CV_MAKETYPE(img.depth(), 1)); // make a 1-channel image of
|
||||
// the same size and same
|
||||
// channel type as img
|
||||
```
|
||||
Arrays with more complex elements cannot be constructed or processed using OpenCV. Furthermore, each
|
||||
function or method can handle only a subset of all possible array types. Usually, the more complex
|
||||
@@ -269,14 +269,14 @@ extended in future based on user requests.
|
||||
### InputArray and OutputArray
|
||||
|
||||
Many OpenCV functions process dense 2-dimensional or multi-dimensional numerical arrays. Usually,
|
||||
such functions take cppMat as parameters, but in some cases it's more convenient to use
|
||||
such functions take `cv::Mat` as parameters, but in some cases it's more convenient to use
|
||||
`std::vector<>` (for a point set, for example) or `cv::Matx<>` (for 3x3 homography matrix and such). To
|
||||
avoid many duplicates in the API, special "proxy" classes have been introduced. The base "proxy"
|
||||
class is cv::InputArray. It is used for passing read-only arrays on a function input. The derived from
|
||||
InputArray class cv::OutputArray is used to specify an output array for a function. Normally, you should
|
||||
not care of those intermediate types (and you should not declare variables of those types
|
||||
explicitly) - it will all just work automatically. You can assume that instead of
|
||||
InputArray/OutputArray you can always use `Mat`, `std::vector<>`, `cv::Matx<>`, `cv::Vec<>` or `cv::Scalar`. When a
|
||||
InputArray/OutputArray you can always use `cv::Mat`, `std::vector<>`, `cv::Matx<>`, `cv::Vec<>` or `cv::Scalar`. When a
|
||||
function has an optional input or output array, and you do not have or do not want one, pass
|
||||
cv::noArray().
|
||||
|
||||
@@ -288,7 +288,7 @@ the optimization algorithm did not converge), it returns a special error code (t
|
||||
boolean variable).
|
||||
|
||||
The exceptions can be instances of the cv::Exception class or its derivatives. In its turn,
|
||||
cv::Exception is a derivative of std::exception. So it can be gracefully handled in the code using
|
||||
cv::Exception is a derivative of `std::exception`. So it can be gracefully handled in the code using
|
||||
other standard C++ library components.
|
||||
|
||||
The exception is typically thrown either using the `#CV_Error(errcode, description)` macro, or its
|
||||
@@ -297,7 +297,7 @@ printf-like `#CV_Error_(errcode, (printf-spec, printf-args))` variant, or using
|
||||
satisfied. For performance-critical code, there is #CV_DbgAssert(condition) that is only retained in
|
||||
the Debug configuration. Due to the automatic memory management, all the intermediate buffers are
|
||||
automatically deallocated in case of a sudden error. You only need to add a try statement to catch
|
||||
exceptions, if needed: :
|
||||
exceptions, if needed:
|
||||
```.cpp
|
||||
try
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
#if defined(__clang__) && defined(__has_feature)
|
||||
#if __has_feature(memory_sanitizer)
|
||||
#define CV_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
|
||||
__msan_unpoison(adresse, size)
|
||||
__msan_unpoison(address, size)
|
||||
#endif
|
||||
#endif
|
||||
#ifndef CV_ANNOTATE_MEMORY_IS_INITIALIZED
|
||||
|
||||
@@ -90,6 +90,7 @@ enum ImwriteFlags {
|
||||
IMWRITE_JPEG_RST_INTERVAL = 4, //!< JPEG restart interval, 0 - 65535, default is 0 - no restart.
|
||||
IMWRITE_JPEG_LUMA_QUALITY = 5, //!< Separate luma quality level, 0 - 100, default is -1 - don't use.
|
||||
IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is -1 - don't use.
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR = 7, //!< For JPEG, set sampling factor. See cv::ImwriteJPEGSamplingFactorParams.
|
||||
IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. If specified, strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY). Default value is 1 (best speed setting).
|
||||
IMWRITE_PNG_STRATEGY = 17, //!< One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE.
|
||||
IMWRITE_PNG_BILEVEL = 18, //!< Binary level PNG, 0 or 1, default is 0.
|
||||
@@ -105,6 +106,15 @@ enum ImwriteFlags {
|
||||
IMWRITE_JPEG2000_COMPRESSION_X1000 = 272 //!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000.
|
||||
};
|
||||
|
||||
enum ImwriteJPEGSamplingFactorParams {
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_411 = 0x411111, //!< 4x1,1x1,1x1
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_420 = 0x221111, //!< 2x2,1x1,1x1(Default)
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_422 = 0x211111, //!< 2x1,1x1,1x1
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_440 = 0x121111, //!< 1x2,1x1,1x1
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_444 = 0x111111 //!< 1x1,1x1,1x1(No subsampling)
|
||||
};
|
||||
|
||||
|
||||
enum ImwriteEXRTypeFlags {
|
||||
/*IMWRITE_EXR_TYPE_UNIT = 0, //!< not supported */
|
||||
IMWRITE_EXR_TYPE_HALF = 1, //!< store as HALF (FP16)
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//interaction between '_setjmp' and C++ object destruction is non-portable
|
||||
#pragma warning(disable: 4611)
|
||||
@@ -640,6 +642,7 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
int rst_interval = 0;
|
||||
int luma_quality = -1;
|
||||
int chroma_quality = -1;
|
||||
uint32_t sampling_factor = 0; // same as 0x221111
|
||||
|
||||
for( size_t i = 0; i < params.size(); i += 2 )
|
||||
{
|
||||
@@ -687,6 +690,27 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
rst_interval = params[i+1];
|
||||
rst_interval = MIN(MAX(rst_interval, 0), 65535L);
|
||||
}
|
||||
|
||||
if( params[i] == IMWRITE_JPEG_SAMPLING_FACTOR )
|
||||
{
|
||||
sampling_factor = static_cast<uint32_t>(params[i+1]);
|
||||
|
||||
switch ( sampling_factor )
|
||||
{
|
||||
case IMWRITE_JPEG_SAMPLING_FACTOR_411:
|
||||
case IMWRITE_JPEG_SAMPLING_FACTOR_420:
|
||||
case IMWRITE_JPEG_SAMPLING_FACTOR_422:
|
||||
case IMWRITE_JPEG_SAMPLING_FACTOR_440:
|
||||
case IMWRITE_JPEG_SAMPLING_FACTOR_444:
|
||||
// OK.
|
||||
break;
|
||||
|
||||
default:
|
||||
CV_LOG_WARNING(NULL, cv::format("Unknown value for IMWRITE_JPEG_SAMPLING_FACTOR: 0x%06x", sampling_factor ) );
|
||||
sampling_factor = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jpeg_set_defaults( &cinfo );
|
||||
@@ -699,6 +723,14 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
|
||||
if( optimize )
|
||||
cinfo.optimize_coding = TRUE;
|
||||
|
||||
if( (channels > 1) && ( sampling_factor != 0 ) )
|
||||
{
|
||||
cinfo.comp_info[0].v_samp_factor = (sampling_factor >> 16 ) & 0xF;
|
||||
cinfo.comp_info[0].h_samp_factor = (sampling_factor >> 20 ) & 0xF;
|
||||
cinfo.comp_info[1].v_samp_factor = 1;
|
||||
cinfo.comp_info[1].h_samp_factor = 1;
|
||||
}
|
||||
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
if (luma_quality >= 0 && chroma_quality >= 0)
|
||||
{
|
||||
|
||||
@@ -178,6 +178,98 @@ TEST(Imgcodecs_Jpeg, encode_decode_rst_jpeg)
|
||||
EXPECT_EQ(0, remove(output_normal.c_str()));
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
static const uint32_t default_sampling_factor = static_cast<uint32_t>(0x221111);
|
||||
|
||||
static uint32_t test_jpeg_subsampling( const Mat src, const vector<int> param )
|
||||
{
|
||||
vector<uint8_t> jpeg;
|
||||
|
||||
if ( cv::imencode(".jpg", src, jpeg, param ) == false )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( src.channels() != 3 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find SOF Marker(FFC0)
|
||||
int sof_offset = 0; // not found.
|
||||
int jpeg_size = static_cast<int>( jpeg.size() );
|
||||
for ( int i = 0 ; i < jpeg_size - 1; i++ )
|
||||
{
|
||||
if ( (jpeg[i] == 0xff ) && ( jpeg[i+1] == 0xC0 ) )
|
||||
{
|
||||
sof_offset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( sof_offset == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Extract Subsampling Factor from SOF.
|
||||
return ( jpeg[sof_offset + 0x0A + 3 * 0 + 1] << 16 ) +
|
||||
( jpeg[sof_offset + 0x0A + 3 * 1 + 1] << 8 ) +
|
||||
( jpeg[sof_offset + 0x0A + 3 * 2 + 1] ) ;
|
||||
}
|
||||
|
||||
TEST(Imgcodecs_Jpeg, encode_subsamplingfactor_default)
|
||||
{
|
||||
vector<int> param;
|
||||
Mat src( 48, 64, CV_8UC3, cv::Scalar::all(0) );
|
||||
EXPECT_EQ( default_sampling_factor, test_jpeg_subsampling(src, param) );
|
||||
}
|
||||
|
||||
TEST(Imgcodecs_Jpeg, encode_subsamplingfactor_usersetting_valid)
|
||||
{
|
||||
Mat src( 48, 64, CV_8UC3, cv::Scalar::all(0) );
|
||||
const uint32_t sampling_factor_list[] = {
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_411,
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_420,
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_422,
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_440,
|
||||
IMWRITE_JPEG_SAMPLING_FACTOR_444,
|
||||
};
|
||||
const int sampling_factor_list_num = 5;
|
||||
|
||||
for ( int i = 0 ; i < sampling_factor_list_num; i ++ )
|
||||
{
|
||||
vector<int> param;
|
||||
param.push_back( IMWRITE_JPEG_SAMPLING_FACTOR );
|
||||
param.push_back( sampling_factor_list[i] );
|
||||
EXPECT_EQ( sampling_factor_list[i], test_jpeg_subsampling(src, param) );
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Imgcodecs_Jpeg, encode_subsamplingfactor_usersetting_invalid)
|
||||
{
|
||||
Mat src( 48, 64, CV_8UC3, cv::Scalar::all(0) );
|
||||
const uint32_t sampling_factor_list[] = { // Invalid list
|
||||
0x111112,
|
||||
0x000000,
|
||||
0x001111,
|
||||
0xFF1111,
|
||||
0x141111, // 1x4,1x1,1x1 - unknown
|
||||
0x241111, // 2x4,1x1,1x1 - unknown
|
||||
0x421111, // 4x2,1x1,1x1 - unknown
|
||||
0x441111, // 4x4,1x1,1x1 - 410(libjpeg cannot handle it)
|
||||
};
|
||||
const int sampling_factor_list_num = 8;
|
||||
|
||||
for ( int i = 0 ; i < sampling_factor_list_num; i ++ )
|
||||
{
|
||||
vector<int> param;
|
||||
param.push_back( IMWRITE_JPEG_SAMPLING_FACTOR );
|
||||
param.push_back( sampling_factor_list[i] );
|
||||
EXPECT_EQ( default_sampling_factor, test_jpeg_subsampling(src, param) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_JPEG
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -1633,7 +1633,7 @@ bool CvCapture_FFMPEG::retrieveFrame(int flag, unsigned char** data, int* step,
|
||||
img_convert_ctx,
|
||||
sw_picture->data,
|
||||
sw_picture->linesize,
|
||||
0, context->coded_height,
|
||||
0, sw_picture->height,
|
||||
rgb_picture.data,
|
||||
rgb_picture.linesize
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user