• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![](images/output.jpg)
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