0

In my application, I need to compare 2 images and highlight the difference with color. For example, I am comparing UIImage1 with UIImage2, where both the images are same, except there is a small square in UIImage2. I need to highlight the extra square object with red color and display in the image view otherwise I want to know the x and y-direction of the difference.

I have tried this below code. in this code, I can only change the alpha value of the difference. can't change the color of the diff.

UIImage* bottomImage = [UIImage imageNamed:@"j1.jpg"];
UIImage* topImage    = [UIImage imageNamed:@"j2.jpg"];
UIImageView* imageView = [[UIImageView alloc] initWithImage:bottomImage];
UIImageView* subView   = [[UIImageView alloc] initWithImage:topImage];
subView.alpha = 0.5;  // Customize the opacity of the top image.
[imageView addSubview:subView];
UIGraphicsBeginImageContext(imageView.frame.size);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* blendedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_imageview.image = blendedImage;

image 1:

enter image description here

image 2:

enter image description here

diff image:

enter image description here

but what I want is this:

enter image description here

I'm new to OpenCV the codes are in python. can anyone help me to change this code into objective-c? I tried but I'm getting the error only.

https://stackoverflow.com/a/27500479/6859041

im = cv2.imread('c:\\diff.jpg')
im1 = cv2.imread('c:\\Edited.jpg')


imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(im1, contours, -1, (0,255,0), 1)
cv2.imwrite("c:\\see_this.jpg", im1)

how to change this code into objective C?

thanks.

Gaya3
  • 45
  • 10
  • 2
    Check this: https://stackoverflow.com/questions/10055739/ios-comparing-the-two-images – Faysal Ahmed Apr 09 '19 at 07:59
  • they are only comparing the image. I want to highlight the difference – Gaya3 Apr 09 '19 at 10:01
  • 1
    Faysal's comment is helpful though, comparison is the first step. Once you've compared the two and have an idea of where the images differ, you can start working on highlighting the differences. – Will Jones Apr 09 '19 at 10:24

3 Answers3

1

With ImageMagick, this is quite easy.

img1.jpg enter image description here

img2.jpg enter image description here

compare -fuzz 25% -metric rmse -lowlight-color transparent -highlight-color red img1.jpg img2.jpg diffimage.jpg
1562.23 (0.0238381)


enter image description here

You can do the same in Python Wand, which calls ImageMagick and gets the same image and value as above. (Credits to emcconville)

#!/bin/python3.7
from wand.image import Image
from wand.display import display
from wand.api import library

with Image(filename='img1.jpg') as bimg:
    with Image(filename='img2.jpg') as fimg:
        # We have to call the C method directly, and calculate the percentage.
        library.MagickSetImageFuzz(bimg.wand, 0.25 * bimg.quantum_range)
        bimg.artifacts['compare:highlight-color'] = 'red'
        bimg.artifacts['compare:lowlight-color'] = 'transparent'
        diff_img, diff_val =  bimg.compare(fimg, 'root_mean_square')
        print(diff_val)
        with diff_img:
            diff_img.save(filename='img1_img2_diff.jpg')
fmw42
  • 46,825
  • 10
  • 62
  • 80
0

You can check code of facebook solution for testing called Snapshot: https://github.com/uber/ios-snapshot-test-case/

Look at categories folder.

- (UIImage *)fb_diffWithImage:(UIImage *)image
{
    if (!image) {
        return nil;
    }
    CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height));
    UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
    CGContextSetAlpha(context, 0.5);
    CGContextBeginTransparencyLayer(context, NULL);
    [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
    CGContextSetBlendMode(context, kCGBlendModeDifference);
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height));
    CGContextEndTransparencyLayer(context);
    UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return returnImage;
}
aquarium_moose
  • 355
  • 1
  • 11
  • how can I get the coordinates of the where the difference happened? or instead of alpha changing, I want to change the color of the difference. – Gaya3 Apr 10 '19 at 08:02
  • I see your question edit: what will you do, if diff will be too small to see it over background? Or if color diff will be merged with background? Are you sure this solution will be usefull? – aquarium_moose Apr 10 '19 at 19:41
  • yes I want to highlight the difference on the image when I compare to the previous image – Gaya3 Apr 11 '19 at 07:02
0

You can directly look at the backing data of an image to get the RGBA value of any pixel and then use these to compare or construct a new image. Its expensive to do this on the CPU though. You may find its much faster to write a custom GPU shader that jsut compares the two inputs and writes the output based on whether or not they are equal.

func pixel(in image: UIImage, at point: CGPoint) -> (UInt8, UInt8, UInt8, UInt8)? {
    let width = Int(image.size.width)
    let height = Int(image.size.height)
    let x = Int(point.x)
    let y = Int(point.y)
    guard x < width && y < height else {
        return nil
    }
    guard let cfData:CFData = image.cgImage?.dataProvider?.data, let pointer = CFDataGetBytePtr(cfData) else {
        return nil
    }
    let bytesPerPixel = 4
    let offset = (x + y * width) * bytesPerPixel
    return (pointer[offset], pointer[offset + 1], pointer[offset + 2], pointer[offset + 3])
}

let image = UIImage(named: "t.png")!
if let (r,g,b,a) = pixel(in: image, at: CGPoint(x: 1, y:2)) {
    print ("Red: \(r), Green: \(g), Blue: \(b), Alpha: \(a)")
}
Josh Homann
  • 15,933
  • 3
  • 30
  • 33