我在iOS上开始使用OpenCV,我想要实现的第一件事就是将彩色图像转换为灰色图像。
我的第一次尝试是成功的
我正在使用“CV_8UC1”选项获取Mat,然后将其转换回图像。
代码如下:
UIImage *image = [UIImage imageNamed:kImageName];
image = [UIImage greyedImage:image];
[imageView setImage:image];
+ (UIImage*)greyedImage:(UIImage*)image
{
return [UIImage imageFromMat:[image toGrayMat]];
}
+ (UIImage*)imageFromMat:(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;
}
- (cv::Mat)toGrayMat
{
cv::Mat tmp = [self toMatWithChannelOption:CV_8UC1];
//cvCvtColor(&tmp, &tmp, CV_BGR2GRAY);
return tmp;
}
- (cv::Mat)toMatWithChannelOption:(int)channelOption
{
CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
CGFloat cols = self.size.width;
CGFloat rows = self.size.height;
cv::Mat cvMat(rows, cols, channelOption); // 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), self.CGImage);
CGContextRelease(contextRef);
return cvMat;
}
但是它导致了这个错误
“CGBitmapContextCreate:不支持的参数组合:8个整数位/分量; 32位/像素; 3分量颜色空间; kCGImageAlphaNoneSkipLast; 610字节/行。 5月18日15:32:23 MacBook-Air.local test [12677]:CGContextDrawImage:无效的上下文0x0。这是一个严重的错误。该应用程序或其使用的库正在使用无效的上下文,从而导致系统稳定性和可靠性的整体降低。此通知是礼貌的:请解决此问题。在即将到来的更新中,它将成为一个致命的错误。“
之后我尝试使用cvtColor:
- (cv::Mat)toGrayMat
{
cv::Mat tmp = [self toMatWithChannelOption:CV_8UC4];
cvCvtColor(&tmp, &tmp, CV_BGRA2GRAY);
return tmp;
}
但我知道
“函数cvarrToMat中的未知数组类型”..不知怎的,它告诉我传递给cvtColor的参数不正确。
请说明可能的原因。
P.S。我在许多问题中观察到其他人将该函数称为“cvtColor”,而我只能将其编写为cvCvtColor,否则Xcode会对其进行纠正,并迫使我将“&”放入其中。在mat函数属性之前。
我的导入:“opencv2 / imgproc / imgproc_c.h” iOS:8 +
答案 0 :(得分:4)
将cvCvtColor
与CV_BGRA2GRAY
一起使用作为参数可将彩色图像转换为灰度图像。每个都是Mat
不同类型。彩色图像具有4个通道(例如CV_8UC4),灰度级具有单个通道(例如CV_8UC1)。因此,为输入和输出声明单独的参数。以下示例。
#include "opencv2/opencv.hpp"
cv::Mat gray;
cv::Mat tmp = [self toMatWithChannelOption:CV_8UC4];
cv::cvtColor( tmp, gray, CV_BGRA2GRAY );
注意a)避免使用cvCvtColor
,因为它是已弃用的C API(1)的一部分。而是使用cvtColor
。 b)避免使用标题imgproc_c.h
。它仅出于兼容性原因提供。而是使用imgproc.hpp
或简单opencv.hpp