1OpenCV iOS - Image Processing {#tutorial_image_manipulation} 2============================= 3 4Goal 5---- 6 7In this tutorial we will learn how to do basic image processing using OpenCV in iOS. 8 9Introduction 10------------ 11 12In *OpenCV* all the image processing operations are usually carried out on the *Mat* structure. In 13iOS however, to render an image on screen it have to be an instance of the *UIImage* class. To 14convert an *OpenCV Mat* to an *UIImage* we use the *Core Graphics* framework available in iOS. Below 15is the code needed to covert back and forth between Mat's and UIImage's. 16@code{.m} 17- (cv::Mat)cvMatFromUIImage:(UIImage *)image 18{ 19 CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); 20 CGFloat cols = image.size.width; 21 CGFloat rows = image.size.height; 22 23 cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha) 24 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 33 34 CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); 35 CGContextRelease(contextRef); 36 37 return cvMat; 38} 39@endcode 40@code{.m} 41- (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image 42{ 43 CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); 44 CGFloat cols = image.size.width; 45 CGFloat rows = image.size.height; 46 47 cv::Mat cvMat(rows, cols, CV_8UC1); // 8 bits per component, 1 channels 48 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 57 58 CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); 59 CGContextRelease(contextRef); 60 61 return cvMat; 62 } 63@endcode 64After the processing we need to convert it back to UIImage. The code below can handle both 65gray-scale and color image conversions (determined by the number of channels in the *if* statement). 66@code{.m} 67cv::Mat greyMat; 68cv::cvtColor(inputMat, greyMat, COLOR_BGR2GRAY); 69@endcode 70After the processing we need to convert it back to UIImage. 71@code{.m} 72-(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat 73{ 74 NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()]; 75 CGColorSpaceRef colorSpace; 76 77 if (cvMat.elemSize() == 1) { 78 colorSpace = CGColorSpaceCreateDeviceGray(); 79 } else { 80 colorSpace = CGColorSpaceCreateDeviceRGB(); 81 } 82 83 CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 84 85 // Creating CGImage from cv::Mat 86 CGImageRef imageRef = CGImageCreate(cvMat.cols, //width 87 cvMat.rows, //height 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 94 NULL, //decode 95 false, //should interpolate 96 kCGRenderingIntentDefault //intent 97 ); 98 99 100 // Getting UIImage from CGImage 101 UIImage *finalImage = [UIImage imageWithCGImage:imageRef]; 102 CGImageRelease(imageRef); 103 CGDataProviderRelease(provider); 104 CGColorSpaceRelease(colorSpace); 105 106 return finalImage; 107 } 108@endcode 109 110Output 111-------- 112 113 114 115Check out an instance of running code with more Image Effects on 116[YouTube](http://www.youtube.com/watch?v=Ko3K_xdhJ1I) . 117 118\htmlonly 119<div align="center"> 120<iframe width="560" height="350" src="http://www.youtube.com/embed/Ko3K_xdhJ1I" frameborder="0" allowfullscreen></iframe> 121</div> 122\endhtmlonly 123