Ask Your Question

like the picture below,how can i deal with the blue edges?

asked 2014-07-15 05:08:48 -0500

Song gravatar image

updated 2014-07-15 20:37:16 -0500

this is the source image,i matting the cat with photoshopcs5 and setting the background blue,cause i think this maybe easier to matted by opencv. image description this is the threshold image image description image description

Mat src,dst;
src = imread("t1.jpg");
if (src.empty())
    cout<<"read data error!"<<endl;
    return -1;


this is callback function

bk = imread("Daydream.jpg");
if (bk.empty())
    cout<<"read data error!"<<endl;
    return ;
edit retag flag offensive close merge delete


Have you cut it by hand (the cat and post it on blue)? Maybe it is bad because of that. You may try to do something like on the edges remove blue

thdrksdfthmn gravatar imagethdrksdfthmn ( 2014-07-15 05:13:54 -0500 )edit

I guess your best guess is to add a single erode of 1 pixel to your binary image. However applying to much erosion could cause you to loose information.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-15 08:14:35 -0500 )edit

And to give more detail, the reason of this occuring is due to the fact you are working on jpeg image. Due to the lossy compression, pixel values get shifted and blue artefacts occur around border.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-15 08:17:34 -0500 )edit

erode let the cat have no beard :D

Song gravatar imageSong ( 2014-07-15 20:46:34 -0500 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2014-07-15 21:16:12 -0500

Witek gravatar image

updated 2014-07-15 21:24:43 -0500

I found your problem quite interesting and decided to spend some time on it. Actually it took me well over 2 hours to work it out and write the answer!! My coding efficiency sucks :(

Generally the idea is simple: while copying the masked out part of the image (cat with whiskers) do not copy blue parts as they are, but get rid of their blue channel and replace it by the average of the remaining two. Your blue background has a hue value of 120 in OpenCV. However, this clear hue is affected by the whiskers and the outline of the cat. So we want to get rid of the bluish hue for all the pixels of hue in the range of 120+-10. Once we have done that, we can copy the masked part of the image.

Here is the code. First we find the blue and bluish pixels.

Mat hsv, blue_mask;
Mat nlb(src.rows,src.cols,CV_8UC3,Scalar(110,70,70));
Mat nub(src.rows,src.cols,CV_8UC3,Scalar(130,255,255));
//you can dilate the mask here to make sure the edges are blue-free

The effect can be seen below. If you decrease the upper bound of saturation or value just by 1 you will see some compression artifacts:

image description

However with values of 255 the mask is clear:

image description

As I hate to iterate pixel by pixel I was looking for some other solution to replace the blue channel under the mask above with the average value of the other two channels. This is probably not the simplest nor the fastest solution. If anybody knows a better way, please enlighten me.

Mat((spl[1]+spl[2])/2).copyTo(spl[0],mask); //overwrite bluish pixels of B with (G+R)/2
vector<Mat> channels;
merge(channels,new_src); //merge all channels to create new version of the input image

This new image looks like this:

image description

Actually this new version of the input image happens to be the desired output image! You don't even need to threshold your blue channel and mask it anymore!

Unfortunately, some of the cat's fur is missing, but I think you can play more with matting in Photoshop to get better results. Let us know if you succeed.

If you still see some blue tint, play with the lower and upper bounds for hue, saturation and value. They will be probably a little different for other images.

edit flag offensive delete link more


thank you for your time,that is awesome

Song gravatar imageSong ( 2014-07-15 21:41:52 -0500 )edit

You saved the cat from the blue pixel attack!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 00:44:05 -0500 )edit

what's that mean?

Song gravatar imageSong ( 2014-07-16 01:34:49 -0500 )edit

@Song - it means that the cat has no blue pixel edges anymore :) Just a laugh!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 02:00:21 -0500 )edit

my English is awful, :) my purpose is to achieve blue background video matting,do you have any idea?

Song gravatar imageSong ( 2014-07-16 02:39:08 -0500 )edit

Nope :D Never tried implementing that!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 02:43:07 -0500 )edit

i had seen the bayesian matting papers and robust matting ,but i could not find any code about that

Song gravatar imageSong ( 2014-07-16 02:53:33 -0500 )edit

Thats usually the case with academic papers. You will need to try and implement yourself using techniques described in the paper.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 03:15:15 -0500 )edit

my higher mathematics is not very good,that's so difficult to me. -_-

Song gravatar imageSong ( 2014-07-16 04:04:42 -0500 )edit

I have never worked with video matting, but this code should work for videos too.

Witek gravatar imageWitek ( 2014-07-16 04:07:27 -0500 )edit

answered 2014-07-15 10:12:38 -0500

What you need to do is to AND the binary image by the original image.

cv::bitwise_and(src, dst, bk);

bk is the output image.

edit flag offensive delete link more


he is doing this already... it won't solve the blue pixels...

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-15 13:28:48 -0500 )edit

No,cv::bitwise_and(src, dst, bk);//this is error ,size of input argument do not match

Song gravatar imageSong ( 2014-07-15 20:24:51 -0500 )edit

You're right! I'm sorry I missed that point.

hadoofi gravatar imagehadoofi ( 2014-07-16 10:00:16 -0500 )edit
Login/Signup to Answer

Question Tools


Asked: 2014-07-15 05:08:48 -0500

Seen: 652 times

Last updated: Jul 15 '14