1 OpenCV iOS - Image Processing {#tutorial_image_manipulation}
2 =============================
7 In this tutorial we will learn how to do basic image processing using OpenCV in iOS.
12 In *OpenCV* all the image processing operations are usually carried out on the *Mat* structure. In
13 iOS however, to render an image on screen it have to be an instance of the *UIImage* class. To
14 convert an *OpenCV Mat* to an *UIImage* we use the *Core Graphics* framework available in iOS. Below
15 is the code needed to covert back and forth between Mat's and UIImage's.
17 - (cv::Mat)cvMatFromUIImage:(UIImage *)image
19 CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
20 CGFloat cols = image.size.width;
21 CGFloat rows = image.size.height;
23 cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)
25 CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
26 cols, // Width of bitmap
27 rows, // Height of bitmap
28 8, // Bits per component
29 cvMat.step[0], // Bytes per row
30 colorSpace, // Colorspace
31 kCGImageAlphaNoneSkipLast |
32 kCGBitmapByteOrderDefault); // Bitmap info flags
34 CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
35 CGContextRelease(contextRef);
41 - (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image
43 CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
44 CGFloat cols = image.size.width;
45 CGFloat rows = image.size.height;
47 cv::Mat cvMat(rows, cols, CV_8UC1); // 8 bits per component, 1 channels
49 CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
50 cols, // Width of bitmap
51 rows, // Height of bitmap
52 8, // Bits per component
53 cvMat.step[0], // Bytes per row
54 colorSpace, // Colorspace
55 kCGImageAlphaNoneSkipLast |
56 kCGBitmapByteOrderDefault); // Bitmap info flags
58 CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
59 CGContextRelease(contextRef);
64 After the processing we need to convert it back to UIImage. The code below can handle both
65 gray-scale and color image conversions (determined by the number of channels in the *if* statement).
68 cv::cvtColor(inputMat, greyMat, COLOR_BGR2GRAY);
70 After the processing we need to convert it back to UIImage.
72 -(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
74 NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
75 CGColorSpaceRef colorSpace;
77 if (cvMat.elemSize() == 1) {
78 colorSpace = CGColorSpaceCreateDeviceGray();
80 colorSpace = CGColorSpaceCreateDeviceRGB();
83 CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
85 // Creating CGImage from cv::Mat
86 CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
88 8, //bits per component
89 8 * cvMat.elemSize(), //bits per pixel
90 cvMat.step[0], //bytesPerRow
91 colorSpace, //colorspace
92 kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
93 provider, //CGDataProviderRef
95 false, //should interpolate
96 kCGRenderingIntentDefault //intent
100 // Getting UIImage from CGImage
101 UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
102 CGImageRelease(imageRef);
103 CGDataProviderRelease(provider);
104 CGColorSpaceRelease(colorSpace);
113 ![](images/output.jpg)
115 Check out an instance of running code with more Image Effects on
116 [YouTube](http://www.youtube.com/watch?v=Ko3K_xdhJ1I) .
118 @youtube{Ko3K_xdhJ1I}