4

I'm writing an Objective-C algorithm that compares two images and outputs the differences.

Occasionally two identical images will be passed in. Is there a way to tell immediately from the resulting CGImageRef that it contains no data? (i.e. only transparent pixels).

The algorithm is running at > 20 fps so performance is a top priority.

justin
  • 104,054
  • 14
  • 179
  • 226
Chris Nolet
  • 8,714
  • 7
  • 67
  • 92
  • 1
    If you want it to run quickly, be sure you check out the Accelerate framework. There are a lot of DSP and vector processing functions in there and they're super fast. – nielsbot Jul 06 '13 at 01:42

3 Answers3

2

From a performance perspective, you should incorporate this check into your comparison-algorithm. The most expensive operation when working on images is most of the time loading a small bit of the image into cache. Once you got it there, there are plenty of ways of working on the data really fast (SIMD), but the problem is that you need to evict and reload the cache with new data all the time, and this is computationally expensive. Now, if you already have been through every pixel of both images once in your algorithm, it would make sense to at the same time compute the SAD while you still got the data in cache. So in pseudo-code:

int total_sad = 0
for y = 0; y < heigth; y++
  for x = 0; x < width; x+=16
    xmm0 = load_data (image0 + y * width + x)
    xmm1 = load_data (image1 + y * width + x)

    /* this stores the differences (your algorithm) */
    store_data (result_image + y * width + x, diff (xmm0, xmm1))
    /* this does the SAD at the same time */
    total_sad += sad (xmm0, xmm1)
if (total_sad == 0)
  print "the images are identical!"

Hope that helps.

Havard Graff
  • 2,805
  • 1
  • 15
  • 16
2

You should go with CoreImage here. Have a look at the "CIArea*" filters.

See Core Image Filter reference here: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CoreImageFilterReference/Reference/reference.html

This will be A LOT faster than any of the previous approaches. Let us know if this works for you.

tiescher
  • 271
  • 2
  • 8
1

Not sure about this but if you can have a sample image of completly blank image already exists then,

UIImage *image = [UIImage imageWithCGImage:imgRef]; //imgRef is your CGImageRef
if(blankImageData == nil)
{
    UIImage *blankImage = [UIImage imageNamed:@"BlankImage.png"]; 
    blankImageData = UIImagePNGRepresentation(blankImage); //blankImageData some global for cache
}

// Now comparison
imageData = UIImagePNGRepresentation(image);// Image from CGImageRef
if([imageData isEqualToData:blankImageData])
{
   // Your image is blank
}
else
{
   // There are some colourful pixel :)
}
TeaCupApp
  • 11,316
  • 18
  • 70
  • 150
  • Sounds like a good idea. Since we're comparing to a blank image, I wonder if it's faster to loop through and compare to zeros. (Writing for OSX too, so UIImage is unavailable, but I get the idea!) – Chris Nolet Jul 04 '13 at 21:38
  • 1
    Not sure how much time you have but I would love to see which will be faster by benchmarking :). Looping thru should work too. By any chance do have a specific region on image where the pixels will be drawn 100% , if not empty? You can develop such heuristic to boost up the loop too. – TeaCupApp Jul 04 '13 at 22:51
  • Such as if the produced image isn't holo. Then check the pixel in exat center. If the picture is drawn there are higher probabilities that pixel in a center will have colour in it. But this is dangerous...You must need to check the edge cases. – TeaCupApp Jul 04 '13 at 22:53
  • Good thinking. For my use case, the transparent/opaque bits will be completely random and distributed all around the image. Your idea might help the next person though! Thanks for your thoughtful feedback. – Chris Nolet Jul 05 '13 at 00:58
  • Thanks for accepting the answer. But please if this solution didn't solve your issue then you may un-accept(Damn it, forgot the antonym) it. I will throw 100 rep bounty on it as, now I am curious to know the answer too :P – TeaCupApp Jul 06 '13 at 01:33
  • 1
    Cool I have thrown 100 rep bounty to get more feedbacks. Thanks Chris – TeaCupApp Jul 06 '13 at 01:35
  • Thank you so much for putting the bounty up. tiescher has answered the question perfectly, and you and I have just learnt about CIArea filters! Thanks also for teaching me about bounties and how effective they are ;) Wow. – Chris Nolet Jul 09 '13 at 09:02
  • No worries, Just awarded bounty to @tiescher. Yup I learnt something new ;). – TeaCupApp Jul 09 '13 at 09:08