An important step in performing any kind of image processing is the dumping of unnecessary data and the extraction of useful data. Now usually I would recommend OpenCV for this kind of task, but there is another library I use more frequently to perform this kind of processing on images. The library is simple-iphone-image-processing, and not only is it simple to use but all you have to import are 2 files of code and you can suddenly perform gaussian blurs and edge detection at the drop of the hat. The library was created by Chris Greening who did the Sudoku Grab App (a great app which I recommend you should download). My only criticism of the library is that it needs to call C++ methods, which means you have to rename any bit of code that you want to use it with to a .mm rather than just a .m. To get around this I have created a UIImage category that allows you to use simple-image-processing from purely objective C files.
/* * Copyright (c) 2011 b2cloud * By Will Sackfield * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for specific language governing permissions and * limitations under the License. * * File: UIImage+simple-image-processing.h * * 1.0 (13/09/2011) */ #import @interface UIImage (UIImage_simple_image_processing) // Resize the image the size given by a CGSize element -(UIImage*) imageResize:(CGSize)size; // Extract the edges using a canny edge extraction based on the low and high values -(UIImage*) imageByCannyEdgeExtractionLow:(CGFloat)low high:(CGFloat)high; // Perform automatic local threshold -(UIImage*) imageByLocalThreshold; // Perform thresholding using the entire image as a threshold -(UIImage*) imageByThresholding; // Perform a gaussian blur on an image -(UIImage*) imageByGaussianBlur; // Extract a connected region from an image // NSArray is full of CGPoints -(NSArray*) connectedRegionFromPoint:(CGPoint)point; // Extract the largest region from an image // NSArray is full of CGPoints -(NSArray*) largestRegion; // Perform normalisation on an image -(UIImage*) imageByNormalising; // Rotate the image (in radians) -(UIImage*) imageRotate:(CGFloat)radians; // Perform histogram equalisation on an image -(UIImage*) imageByHistogramEqualisation; // Perform topological skeleton on an image -(UIImage*) imageByTopologicalSkeleton; // Turn an array of CGPoints into a CGRect (if you want to box objects) -(CGRect) rectForImagePoints:(NSArray*)points; @end
The first thing to do here is to grab simple-iphone-image-processing off Google Code and take the Image.h and Image.mm files and import them into your project. After that, download the categories from here and add them to your project. Now I will take you through what can be done to the images with this processing library:
First things first, setup a view controller with UIImageView object in it, you can optionally choose the aspect fit attribute. Secondly add an image to your project (I chose an image named generic.png), now set the UIImageView’s image like so:
imageView.image = [UIImage imageNamed:@"generic.png"];
Once we have done that you should see something like this:
Now that we have done that, we can begin manipulating the image. Input this code into the viewDidAppear method to resize the image by a factor of 2:
UIImage* genericImage = [UIImage imageNamed:@"generic.png"]; imageView.image = [genericImage imageResize:CGSizeMake(genericImage.size.width/2.0,genericImage.size.height/2.0)];
The first thing you may notice is that the image is not only scaled by 2 (shown by the lack of quality), but it is also in black and white. The reason for this is colours are rarely used in generic image processing methods, by using grayscale (1 byte per pixel) the whole process is much quicker.
Canny Edge extraction can be performed to provide the outline of features in the image.
imageView.image = [genericImage imageByCannyEdgeExtractionLow:0.3 high:0.7];
Local Thresholding can be used to distinguish foreground objects from the images background:
imageView.image = [genericImage imageByLocalThreshold];
Thresholding in general provides a threshold using the entire image for its reference rather than just local pixels to a point:
imageView.image = [genericImage imageByThresholding];
Gaussian Blur provides smoothing around the images contours (and should preferably be run before the other techniques I have described here):
imageView.image = [genericImage imageByGaussianBlur];
My UIImageView+CoordinateTransform category comes in very handy here, as it allows you to convert touches to coordinates to extract blobs from.