user2521051
user2521051

Reputation: 11

Emgu CV color detection and replace

I'm working on veins detection from image using emgu CV and I have few questions. Is there any simple way to detect color or range of colors? Is there a simple way to replace this color with another (e.g. average color of the image)? How can I achive that without degrading the performance?

Thanks in advance!

Upvotes: 1

Views: 13533

Answers (2)

zsx
zsx

Reputation: 111

I can't imagine this problem has published about 3 years...

    public static Image<Bgr, byte> BackgroundToGreen(Image<Bgr, byte> rgbimage)
    {
        Image<Bgr, byte> ret = rgbimage;
        var image = rgbimage.InRange(new Bgr(190, 190, 190), new Bgr(255, 255, 255));
        var mat = rgbimage.Mat;
        mat.SetTo(new MCvScalar(200, 237, 204), image);
        mat.CopyTo(ret);
        return ret;
    }

Why Matrix?

http://www.emgu.com/wiki/index.php/Working_with_Images#Accessing_the_pixels_from_Mat

Unlike the Image<,> class, where memory are pre-allocated and fixed, the memory of Mat can be automatically re-allocated by Open CV function calls. We cannot pre-allocate managed memory and assume the same memory are used through the life time of the Mat object. As a result, Mat class do not contains a Data property like the Image<,> class, where the pixels can be access through a managed array.

What is InRange?

http://www.emgu.com/wiki/files/2.0.0.0/html/07eff70b-f81f-6313-98a9-02d508f7c7e0.htm

Checks that image elements lie between two scalars

Return Value

res[i,j] = 255 if inrange, 0 otherwise

What is SetTo?

http://www.emgu.com/wiki/files/2.4.0/document/html/0309f41d-aa02-2c0d-767f-3d7d8ccc9212.htm

Copies scalar value to every selected element of the destination GpuMat: GpuMat(I)=value if mask(I)!=0

So it is.

Quoted from: http://blog.zsxsoft.com/post/24 (Chinese only) (CC BY-NC-ND)

Upvotes: 4

online Thomas
online Thomas

Reputation: 9381

Image<Bgr, Byte> img; 
 Image<Gray, Byte> grayImg = img.Convert<Gray, Byte>();

grayImg = img.InRange(new Bgr(minB, minG, minR), new Bgr(new Bgr(maxB, maxG, maxR);

it will only show your color(range) in binary and is the fastest way

But if you want to detect a certain range of colors AND replace them:

Image<Bgr, Byte> img;
                for (int i = 0; i < img.ManagedArray.GetLength(0); i++)
                {
                    for (int j = 0; j < img.ManagedArray.GetLength(1); j++)
                    {
                        Bgr currentColor = img[i, j];

                        if (currentColor.Blue >= minB && currentColor.Blue <= maxB && currentColor.Green >= minG && maxG <= trackBar13.Value && currentColor.Red >= minR && currentColor.Red <= maxR)
                        {
                            img[i, j] = new Bgr(B,G,R);
                        }
                    }
                }

Upvotes: 1

Related Questions