2015-05-18 89 views
1

我從iOS上的OpenCV開始,我想要實現的第一件事是將彩色圖像轉換爲灰色圖像。iOS OpenCV cvtColor未知陣列類型錯誤

我第一次嘗試是成功的

我獲得了「CV_8UC1」選項墊,然後將其轉換回圖像。

的代碼如下:

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字節/行。 May 18 15:32:23 MacBook-Air.local test [12677]:CGContextDrawImage:invalid context 0x0。這是一個嚴重的錯誤。此應用程序或其使用的庫正在使用無效的上下文,從而導致系統穩定性和可靠性的整體降級。這個通知是禮貌的:請解決這個問題。它將成爲一個致命的錯誤在即將到來的更新「

之後,我嘗試使用cvtColor這樣的:

- (cv::Mat)toGrayMat 
{ 
    cv::Mat tmp = [self toMatWithChannelOption:CV_8UC4]; 

    cvCvtColor(&tmp, &tmp, CV_BGRA2GRAY); 

    return tmp; 
} 

但是要知道,我得到

‘在功能上cvarrToMat未知的數組類型’..不知怎的,它告訴我,傳遞給cvtColor參數不正確。

請建議什麼都可以的原因。

PS我的觀察很多其他人稱這個函數爲「cvtColor」的問題,而我只能將它寫成cvCvtColor,否則Xcode會糾正它,並迫使我在mat函數屬性之前放置「&」。

我的進口: 「opencv2/imgproc/imgproc_c.h」 的iOS:8+

回答

2

使用cvCvtColorCV_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

+0

感謝您的詳細解釋,它真的與導入什麼混淆,數據類型是什麼..如何使用它..我希望OpenCV官方教程將有更詳細的解釋。 – Fawkes