5

Have searched on Stackoverflow.com and google. But didn't found any proper method to do so apart from the link shown below.

compare two images and extract the difference using emgu cv library

Please suggest or give helpful feedback so that i can start up with the application.

Community
  • 1
  • 1
Prakash Vishwakarma
  • 814
  • 2
  • 9
  • 25

5 Answers5

3

Please have a look at the Emgu CV API documentation for the methods of the Image class.

It contains the method AbsDiff to compute the absolute differences between two images. It also provides Cmp to get a comparison mask for the differences between two images.

To get a single value describing the difference you could use the number of non-zero pixels per channel provided by the Image.CountNonzero method. Then find the channel with the maximum number of changed (non-zero) pixels. To get a relative value (percentage) just divide that by width * height (total number of pixels in the image).

andyp
  • 6,229
  • 3
  • 38
  • 55
  • AbsDiff gives me difference in the format of image, but i need difference either in percentage or any decimal value. Is it possible to do so??? – Prakash Vishwakarma Apr 04 '14 at 13:15
  • Hi, I've added a simple method to get a single value describing the difference of two images. But it's rough and from the top of my head as I've used the library quite a while ago.. Hope that helps – andyp Apr 04 '14 at 16:23
  • @andyp what do u mean by `Then find the channel with the maximum number of changed (non-zero) pixels.` How can i do this? I also want to calculate percentage of difference between two images or similarity of images in percentage. can you help with this http://stackoverflow.com/questions/36193475/difference-between-two-images-using-emgu-cv – Amogh Mar 24 '16 at 04:53
  • @Amogh did you find a solution to this? – zainul Jan 02 '19 at 13:01
1

Using EmguCV's AbsDiff method.

       using (Image<Gray, byte> sourceImage = new Image<Gray, byte>(_orgImage))
        {
        using (Image<Gray, byte> templateImage = new Image<Gray, byte>(_refImage))
        {
            Image<Gray, byte> resultImage = new Image<Gray, byte>(_bufferParams.MaskDetails.width, _bufferParams.MaskDetails.height);
            CvInvoke.AbsDiff(sourceImage, templateImage, resultImage);
            //resultImage.Save(@"some path" + "imagename.jpeg");
            int diff = CvInvoke.CountNonZero(resultImage);
            //if diff = 0 exact match, otherwise there are some difference.
         }     
        }
Nikhil Dinesh
  • 3,359
  • 2
  • 38
  • 41
0

I think what you are looking for:

image1 = image2 - image1;

Due to operator overloading, this is possible directly in Emgu CV. here is bit code snippet that may help you to achieve your goal using Emgu CV lib.

Image<Gray, Byte> img1 = new Image<Gray, Byte>("C:\\image1.png"); 
Image<Gray, Byte> img2 = new Image<Gray, Byte>("C:\\image2.png"); 
Image<Gray, Byte> img3 = img2 - img1; //Here the difference is applied.

thanks

Thomas
  • 33,544
  • 126
  • 357
  • 626
  • This throws an error for me like "The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array"... Can you help with this? – zainul Jan 02 '19 at 13:03
0

If you want to get a value after comparing two images you can use MatchTemplate API in EmguCV.

Image<Gray, float> resultImage = sourceImage.MatchTemplate(templateImage, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed);
                    double[] minValues, maxValues;
                    Point[] minLocations, maxLocations;
resultImage.MinMax(out minValues, out maxValues, out minLocations, out maxLocations);

maxValues[0] will give you a value between 0-1, close to 1, means more match

Nikhil Dinesh
  • 3,359
  • 2
  • 38
  • 41
0

I am using them method to compare two images similarity. Of course, some of the parameters could be adjusted.

    public bool Compare(Image<Gray, byte> image1, Image<Gray, byte> image2)
    {
        if (image1.Width != image2.Width || image1.Height != image2.Height)
        {
            return false;
        }

        using var diffImage = new Image<Gray, byte>(image1.Width, image1.Height);
        // Get the image of different pixels.
        CvInvoke.AbsDiff(image1, image2, diffImage);

        using var threadholdImage = new Image<Gray, byte>(image1.Width, image1.Height);
        // Check the pixies difference.
        // For instance, if difference between the same pixel on both image are less then 20,
        // we can say that this pixel is the same on both images.
        // After threadholding we would have matrix on which we would have 0 for pixels which are "nearly" the same and 1 for pixes which are different.
        CvInvoke.Threshold(diffImage, threadholdImage, 20, 1, Emgu.CV.CvEnum.ThresholdType.Binary);
        int diff = CvInvoke.CountNonZero(threadholdImage);

        // Take the percentage of the pixels which are different.
        var deffPrecentage = diff / (double) (image1.Width * image1.Height);

        // If the amount of different pixeles more then 15% then we can say that those immages are different.
        return deffPrecentage < 0.15;
    }
Oleg Krymskyi
  • 171
  • 1
  • 4