Change all white pixels of image to transparent in OpenCV C++
Asked Answered
M

1

6

I have this image in OpenCV imgColorPanel = imread("newGUI.png", CV_LOAD_IMAGE_COLOR);:

enter image description here

When I load it in with grey scale imgColorPanel = imread("newGUI.png", CV_LOAD_IMAGE_GRAYSCALE); it looks like this:

enter image description here

However I want to remove the white background or make it transparent (only it's white pixels), to be looking like this:

How to do it in C++ OpenCV ?

enter image description here

Me answered 25/3, 2016 at 18:7 Comment(7)
cv::cvtColor(input,output; CV_BGR2BGRA); then, for each pixel: if pixel == white, set alpha value of that pixel to zero.Ritualist
ah no, your input image is transparent already? use the CV_LOAD_IMAGE_ANYDEPTH flag.Ritualist
or use any negative value as said in docs.opencv.org/2.4/modules/highgui/doc/…Ritualist
but be aware that opencv gui functions like cv::imshow wont handle the alpha channel correctly, so you have to handle that yourself. BUT you do have the alpha value = transparency information!Ritualist
No! My image is not already transparent. I did it transparent in GIMP to just show what result i want to achieve in OpenCV. So i want to change image white pixels to transparent in OpenCV.Me
then load as color image and use my first comment :) tell me if you have problems with that.Ritualist
Ok, two things. How to get single pixel from image (i mean I know to use loop to get all pixels), but how to get pixel from image? Second thing - how to set that alpha value to zero (make it transparent)?Me
R
19

You can convert the input image to BGRA channel (color image with alpha channel) and then modify each pixel that is white to set the alpha value to zero.

See this code:

    // load as color image BGR
    cv::Mat input = cv::imread("C:/StackOverflow/Input/transparentWhite.png");

    cv::Mat input_bgra;
    cv::cvtColor(input, input_bgra, CV_BGR2BGRA);

    // find all white pixel and set alpha value to zero:
    for (int y = 0; y < input_bgra.rows; ++y)
    for (int x = 0; x < input_bgra.cols; ++x)
    {
        cv::Vec4b & pixel = input_bgra.at<cv::Vec4b>(y, x);
        // if pixel is white
        if (pixel[0] == 255 && pixel[1] == 255 && pixel[2] == 255)
        {
            // set alpha to zero:
            pixel[3] = 0;
        }
    }

    // save as .png file (which supports alpha channels/transparency)
    cv::imwrite("C:/StackOverflow/Output/transparentWhite.png", input_bgra);

This will save your image with transparency. The result image opened with GIMP looks like:

enter image description here

As you can see, some "white regions" are not transparent, this means your those pixel weren't perfectly white in the input image. Instead you can try

    // if pixel is white
    int thres = 245; // where thres is some value smaller but near to 255.
    if (pixel[0] >= thres&& pixel[1] >= thres && pixel[2] >= thres)
Ritualist answered 25/3, 2016 at 19:15 Comment(5)
It doesn't seem to work. transparentGUI.png still has background. Also, loading this image in Gray Scale causes crash.Me
loading in geayscale you have to use CV_GRAY2BGRA code in cvrColor. If ai run the code, my png result image has transparency. Did you open it in GIMP? some viewer do always show a backgroundRitualist
cvtColor with CV_GRAY2BGRA also causes crash. I checked in GIMP - and whtie background is still there. Where could I do a mistake?Me
Sorry, i checked wrong image in GIMP (old "newGUI.png" image instead of modified one) - and it's ok - no white background. But OpenCV still cannot load it (crash) or loads it with background. Error is: "Unhandled exception at at 0x74FCB727 in ConsoleApplication1.exe: Microsoft C++ exception: cv::Exception at memory location 0x002AC198.", when I am doing like this Mat imgColorPanel0,imgColorPanel; imgColorPanel0 = imread("transparentGUI.png"); cvtColor(imgColorPanel0, imgColorPanel, CV_BGR2GRAY);**I tried with** CV_GRAY2BGRA and there is crash too.Me
Can you please explain in pythonAppertain

© 2022 - 2024 — McMap. All rights reserved.