Home | History | Annotate | Download | only in image_manipulation
      1 OpenCV iOS - Image Processing {#tutorial_image_manipulation}
      2 =============================
      3 
      4 Goal
      5 ----
      6 
      7 In this tutorial we will learn how to do basic image processing using OpenCV in iOS.
      8 
      9 Introduction
     10 ------------
     11 
     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.
     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
     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).
     66 @code{.m}
     67 cv::Mat greyMat;
     68 cv::cvtColor(inputMat, greyMat, COLOR_BGR2GRAY);
     69 @endcode
     70 After 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 
    110 Output
    111 --------
    112 
    113 ![](images/output.jpg)
    114 
    115 Check 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