Ask Your Question

Revision history [back]

The idea is to create a mask, where it's 0 everywhere, except if the original color is the same as the reference color. After, you copy the image, or, you can directly use the dst image to put the right color in it. The code below is something like this. I suppose source image is in CV_8UC3, aka BGR color space.

/// With the mask
Vec3b colorRef(255,0,0); // for ''pure'' blue
int i,j;
Mat mask = Mat::zeros( img.rows, img.cols, CV_8UC1 );
for( i = 0; i < nRows; ++i)
{
    for ( j = 0; j < nCols; ++j)
    {
        if( img.at<Vec3b>(i,j) == colorRef )
        {
            mask.at<uchar>(i,j) = 255;
        }
    }
}
Mat dst;
img.copyTo( dst, mask );

/// Without the mask
Vec3b colorRef(255,0,0); // for ''pure'' blue
int i,j;
Mat dst;
img.copyTo( dst );
for( i = 0; i < nRows; ++i)
{
    for ( j = 0; j < nCols; ++j)
    {
        if( img.at<Vec3b>(i,j) != colorRef )
        {
            dst.at<Vec3b>(i,j) = 0;
        }
    }
}

If you want to be flexible for the color, not using a perfect equality, you have to consider the color distance, which is not the best in RGB cube, therefore, you need to change of color space, like YUV or anything else.

The idea is to create a mask, where it's 0 everywhere, except if the original color is the same as the reference color. After, you copy the image, or, you can directly use the dst image to put the right color in it. The code below is something like this. I suppose source image is in CV_8UC3, aka BGR color space.

/// With the mask
Vec3b colorRef(255,0,0); // for ''pure'' blue
int i,j;
Mat mask = Mat::zeros( img.rows, img.cols, CV_8UC1 );
for( i = 0; i < nRows; ++i)
{
    for ( j = 0; j < nCols; ++j)
    {
        if( img.at<Vec3b>(i,j) == colorRef )
        {
            mask.at<uchar>(i,j) = 255;
        }
    }
}
Mat dst;
img.copyTo( dst, mask );

/// Without the mask
Vec3b colorRef(255,0,0); // for ''pure'' blue
int i,j;
Mat dst;
img.copyTo( dst );
for( i = 0; i < nRows; ++i)
{
    for ( j = 0; j < nCols; ++j)
    {
        if( img.at<Vec3b>(i,j) != colorRef )
        {
            dst.at<Vec3b>(i,j) = 0;
        }
    }
}

If you want to be flexible for the color, not using a perfect equality, you have to consider the color distance, which is not the best in RGB cube, therefore, you need to change of color space, like YUV or anything else.

[EDIT] I code it in C++, but it's almost the same in Python...