前言
1.OpenCV有专门的iOS平台的包,可以真接下载导入工程,也可以用cmake把OpenCV源码编成.a文件,以静态库的形式导入工程。
2.我这里用的Xcode11,OpenCV用的是最4.20这个版本。
图像转换
1.iOS所支持的图像格式是UIImage,OpenCV的图像格式是Mat,如果要在iOS用OpenCV处理图像,那得先把UIImage转成Mat,才能使用OpenCV的库来做相关的操作。这里要写一个转换函数把数据格式转换过来就可以了,OC是可以调用C++函数的,这里直接用C++写就可以了。
UIImage转Mat:
void UIImageToMat(UIImage *ui_image, cv::Mat &cv_dst)
{
assert(ui_image.size.width > 0 && ui_image.size.height > 0);
assert(ui_image.CGImage != nil || ui_image.CIImage != nil);
//开缓冲区
NSInteger width = ui_image.size.width;
NSInteger height = ui_image.size.height;
cv::Mat cv_mat8uc4 = cv::Mat((int)height, (int)width, CV_8UC4);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (ui_image.CGImage)
{
CGContextRef contextRef = CGBitmapContextCreate(cv_mat8uc4.data, cv_mat8uc4.cols, cv_mat8uc4.rows, 8, cv_mat8uc4.step, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, width, height), ui_image.CGImage);
CGContextRelease(contextRef);
}
else
{
static CIContext* context = nil;
if (!context)
{
context = [CIContext contextWithOptions:@{ kCIContextUseSoftwareRenderer: @NO }];
}
CGRect bounds = CGRectMake(0, 0, width, height);
[context render:ui_image.CIImage toBitmap:cv_mat8uc4.data rowBytes:cv_mat8uc4.step bounds:bounds format:kCIFormatRGBA8 colorSpace:colorSpace];
}
CGColorSpaceRelease(colorSpace);
cv::Mat cv_mat8uc3 = cv::Mat((int)width, (int)height, CV_8UC3);
cv::cvtColor(cv_mat8uc4, cv_mat8uc3, cv::COLOR_RGBA2BGR);
cv_dst = cv_mat8uc3;
}
2.OpenCV处理过的图像是Mat的,如果要在iOS的UIImageView显示出来,还是要把Mat转成UIImage.
Mat转UIImage:
UIImage *MatToUIImage(cv::Mat &cv_src)
{
assert(cv_src.elemSize() == 1 || cv_src.elemSize() == 3);
cv::Mat cv_rgb;
if (cv_src.elemSize() == 1)
{
cv::cvtColor(cv_src, cv_rgb, cv::COLOR_GRAY2RGB);
} else if (cv_src.elemSize() == 3)
{
cv::cvtColor(cv_src, cv_rgb, cv::COLOR_BGR2RGB);
}
NSData *data = [NSData dataWithBytes:cv_rgb.data length:(cv_rgb.elemSize() * cv_rgb.total())];
CGColorSpaceRef colorSpace;
if (cv_rgb.elemSize() == 1)
{
colorSpace = CGColorSpaceCreateDeviceGray();
} else
{
colorSpace = CGColorSpaceCreateDeviceRGB();
}
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(cv_rgb.cols, cv_rgb.rows, 8, 8 * cv_rgb.elemSize(), cv_rgb.step.p[0], colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);
UIImage *ui_image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ui_image;
}