mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
5.5 KiB
129 lines
5.5 KiB
.. _OpenCViOSImageManipulation: |
|
|
|
OpenCV iOS - Image Processing |
|
******************************* |
|
|
|
Goal |
|
==== |
|
|
|
In this tutorial we will learn how to do basic image processing using OpenCV in iOS. |
|
|
|
|
|
*Introduction* |
|
============== |
|
|
|
In *OpenCV* all the image processing operations are usually carried out on the *Mat* structure. In iOS however, to render an image on screen it have to be an instance of the *UIImage* class. To convert an *OpenCV Mat* to an *UIImage* we use the *Core Graphics* framework available in iOS. Below is the code needed to covert back and forth between Mat's and UIImage's. |
|
|
|
|
|
.. code-block:: cpp |
|
|
|
- (cv::Mat)cvMatFromUIImage:(UIImage *)image |
|
{ |
|
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); |
|
CGFloat cols = image.size.width; |
|
CGFloat rows = image.size.height; |
|
|
|
cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha) |
|
|
|
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data |
|
cols, // Width of bitmap |
|
rows, // Height of bitmap |
|
8, // Bits per component |
|
cvMat.step[0], // Bytes per row |
|
colorSpace, // Colorspace |
|
kCGImageAlphaNoneSkipLast | |
|
kCGBitmapByteOrderDefault); // Bitmap info flags |
|
|
|
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); |
|
CGContextRelease(contextRef); |
|
|
|
return cvMat; |
|
} |
|
|
|
.. code-block:: cpp |
|
|
|
- (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image |
|
{ |
|
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); |
|
CGFloat cols = image.size.width; |
|
CGFloat rows = image.size.height; |
|
|
|
cv::Mat cvMat(rows, cols, CV_8UC1); // 8 bits per component, 1 channels |
|
|
|
CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data |
|
cols, // Width of bitmap |
|
rows, // Height of bitmap |
|
8, // Bits per component |
|
cvMat.step[0], // Bytes per row |
|
colorSpace, // Colorspace |
|
kCGImageAlphaNoneSkipLast | |
|
kCGBitmapByteOrderDefault); // Bitmap info flags |
|
|
|
CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); |
|
CGContextRelease(contextRef); |
|
|
|
return cvMat; |
|
} |
|
|
|
After the processing we need to convert it back to UIImage. The code below can handle both gray-scale and color image conversions (determined by the number of channels in the *if* statement). |
|
|
|
.. code-block:: cpp |
|
|
|
cv::Mat greyMat; |
|
cv::cvtColor(inputMat, greyMat, CV_BGR2GRAY); |
|
|
|
After the processing we need to convert it back to UIImage. |
|
|
|
.. code-block:: cpp |
|
|
|
-(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat |
|
{ |
|
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()]; |
|
CGColorSpaceRef colorSpace; |
|
|
|
if (cvMat.elemSize() == 1) { |
|
colorSpace = CGColorSpaceCreateDeviceGray(); |
|
} else { |
|
colorSpace = CGColorSpaceCreateDeviceRGB(); |
|
} |
|
|
|
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); |
|
|
|
// Creating CGImage from cv::Mat |
|
CGImageRef imageRef = CGImageCreate(cvMat.cols, //width |
|
cvMat.rows, //height |
|
8, //bits per component |
|
8 * cvMat.elemSize(), //bits per pixel |
|
cvMat.step[0], //bytesPerRow |
|
colorSpace, //colorspace |
|
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info |
|
provider, //CGDataProviderRef |
|
NULL, //decode |
|
false, //should interpolate |
|
kCGRenderingIntentDefault //intent |
|
); |
|
|
|
|
|
// Getting UIImage from CGImage |
|
UIImage *finalImage = [UIImage imageWithCGImage:imageRef]; |
|
CGImageRelease(imageRef); |
|
CGDataProviderRelease(provider); |
|
CGColorSpaceRelease(colorSpace); |
|
|
|
return finalImage; |
|
} |
|
|
|
*Output* |
|
================================== |
|
|
|
.. image:: images/output.jpg |
|
:alt: header |
|
:align: center |
|
|
|
Check out an instance of running code with more Image Effects on `YouTube <http://www.youtube.com/watch?v=Ko3K_xdhJ1I>`_ . |
|
|
|
.. raw:: html |
|
|
|
<div align="center"> |
|
<iframe width="560" height="350" src="http://www.youtube.com/embed/Ko3K_xdhJ1I" frameborder="0" allowfullscreen></iframe> |
|
</div>
|
|
|