opencv: Problem for Simple Alpha Blending
System information (version)
- OpenCV => 4.2.0
- Operating System / Platform => Windows 64 Bit
- Compiler => Visual Studio 2019
Detailed description
If running following the code for alpha blending, it output following results.
#include <opencv2/opencv.hpp>
int main( int argc, char* argv[] )
{
// Read Image
cv::Mat src = cv::imread( "lena.jpg" );
// Alpha Blend with Blue, Green, and Red
double alpha = 0.6;
double beta = 1.0 - alpha;
cv::Mat blend_b = alpha * src + beta * cv::Scalar( 255, 0, 0 ); // Blue (issue case!)
cv::Mat blend_g = alpha * src + beta * cv::Scalar( 0, 255, 0 ); // Green
cv::Mat blend_r = alpha * src + beta * cv::Scalar( 0, 0, 255 ); // Red
// Show Image
cv::imshow( "src" , src );
cv::imshow( "blue" , blend_b );
cv::imshow( "green", blend_g );
cv::imshow( "red" , blend_r );
cv::waitKey( 0 );
return 0;
}
The output of alpha blending with green and red is correct result.
These turned greenish color and reddish color.
But, the output of alpha blending with blue has become whitish color.
It is not expected output. It should turn to bluish color.
If changes blend color to the close to blue such as cv::Scalar(255, 1, 0)
(just add one to green), it turn correctly to bluish color.
cv::Mat blend_b = alpha * src + beta * cv::Scalar( 255, 1, 0 ); // Close to Blue
Related issues
This seems to be related to this issue #14738.
I think this is due to the difference between calculation results of cv::Mat and cv::MatExpr.
Therefore, I know that this issue can be avoided by changing to following code.
- cv::Mat blend_b = alpha * src + beta * cv::Scalar( 255, 0, 0 ); // Blue
+ cv::Mat blend_b = cv::Mat( alpha * src ) + beta * cv::Scalar( 255, 0, 0 ); // Blue
But, I think this is a bug of corner case. It should be fixed. What do you think? Thanks,
About this issue
- Original URL
- State: open
- Created 4 years ago
- Comments: 18 (11 by maintainers)
Fix may look like this:
Need to add corresponding simple test and prepare a PR.
BTW, Exploring of similar problem shows that there is similar approach few lines above.
Correction to what I said, and consider smaller example:
Input
img
is:Bug in MatExpr causes
beta * Scalar(255, 0, 0)
to be pass the test forisReal()
matrix_expressions.cpp As a result, it ends up addingbeta * Scalar(255, 0, 0)
to all channels ofimg
. Soblend_b
:blend_g
is correctly handled because it is handled in the correct optimization block in that conditional tree (matrix_expressions.cpp):Similarly
blend_r
is also correctly handled:As you can see, because
blend_b
gets information added to all channels more or less equally, the output image is a faded version of the input that doesn’t look bluish.Another workaround for RGB image (add 4th non-zero element to
Scalar
):