-
-
Notifications
You must be signed in to change notification settings - Fork 56.2k
cv::cvtColor does not properly take transparency into account #13135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Because there is no "transparent" color in |
@alalek Thanks for taking a look at the issue. However, in |
@PhilLab , what about converting to premultiplied alpha ( with_alpha = cv2.cvtColor(img, cv2.COLOR_RGBA2mRGBA)
gray = cv2.cvtColor(with_alpha, cv2.COLOR_RGBA2GRAY) gray_orig = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY) |
Or extract "alpha" channel and use it as mask (if it is binary 0/255). |
@mshabunin @alalek Thanks for the suggestions, I didn't know of
For 100 randomly generated images of sizes 1x1 to 4000x4000, this takes around 600ms instead of 2000ms when using the double pass OpenCV. Would there be a rationale for adding something like |
Just for the record, should we ever decide to implement it (and I understand the arguments why we wouldn't do it), here are two test images I used for testing our own implementation:
|
@PhilLab , I think something like But I believe that advanced transformations like BGRA2Gray should use different approaches: it can be different cvtColor interface with alpha-channels and nonlinearity in mind or maybe one can utilize G-API module to build complex operations from several basic transformations with tiling optimization. |
If a specific background color is needed, why not just alpha blend the image onto the solid color background ( |
I have written proof-of-concept code for this feature request. Link: https://gist.github.com/kinchungwong/df3963f09391474e1dabeebe1031ba75 The proof-of-concept code uses the following techniques:
The proof-of-concept code does not implement, but leaves open the possibility of:
The proof-of-concept code highlight the following pain points:
This code is intended for discussion with OpenCV's development team. It is not intended for use by end-users of OpenCV. The code does not implement error handling yet. Refer to disclaimers at the top of the proof-of-concept code. My benchmarking shows that it is much faster than other CPU-based approaches, even though I didn't implement parallel (multi-core) processing yet. I tested split and merge, BGRA2mBGRA followed by dropping alpha channel, one-pixel-at-a-time functor by @PhilLab, and GAPI. The benchmarking code is messy so I don't intend to share it. I did not compare performance with GPU-based approaches, since I don't have a machine setup that allows me to do this reliably. Edited 2018-12-07 I just learned about a pending pull request #13379 by @savuor that works on the same area ("color_rgb.cpp"). I'll need to study the code to see how to integrate both contributions. Remark The color conversion code mentioned by @mshabunin can be found in OpenCV 4.0 (C++) as cv::Mat matInput;
cv::Mat tempMBgra;
cv::Mat outputBgr;
cv::cvtColor(matInput, tempMBgra, cv::ColorConversionCodes::COLOR_RGBA2mRGBA);
cv::cvtColor(tempMBgra, outputBgr, cv::ColorConversionCodes::COLOR_BGRA2BGR); |
@kinchungwong In my PR I'm implementing mRGBA conversions in wide intrinsics right now (but for the only supported data type now which is 8U), hope this helps. |
System information (version)
Detailed description
cv::cvtColor(image, outImage, cv::COLOR_BGRA2GRAY`);
andcv::cvtColor(image, outImage, cv::COLOR_BGRA2BGR);
don't handle transparency well: RGB pixel values determine the output even if alpha value is zero.One could indeed argue that its because of a "wrong" image but this seems to be what many standard editing tools / conversion tools produce
Steps to reproduce
Use this test image at
path
: PngWithTransparency.pngThis is what is inside the images, a black "bounding box" and then fully white border around. Expected would be a full black background.
BTW:
cv::imshow("image", image)
would produce the same result asnoAlpha
The text was updated successfully, but these errors were encountered: