objective-c – CV_8UC3的CGBitmapContextCreate(在OpenCV中使用)

前端之家收集整理的这篇文章主要介绍了objective-c – CV_8UC3的CGBitmapContextCreate(在OpenCV中使用)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在OpenCV中使用人物检测功能
cv::HOGDescriptor hog;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
std::vector<cv::Rect> found;
hog.detectMultiScale(noMask,found,0.2,cv::Size(8,8),cv::Size(16,16),1.05,2);

但我得到以下断言:

OpenCV Error: Assertion Failed (img.type() == CV_8U || img.type() ==
CV_8UC3) in computeGradient,file
/Users/robin/Projects/OpenCVForiPhone/opencv/opencv/modules/objdetect/src/hog.cpp,
line 174

这是有道理的,因为我传递的是CV_8UC4图像.

所以我猜我应该创造一个具有这种特性的cvmat.现在我有这两种方法.这让我得到灰色或彩色cvmats(CV_8UC1 / CV_8UC4)

对于颜色:

-(cv::Mat)CVMat
{

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
    CGFloat cols = self.size.width;
    CGFloat rows = self.size.height;

    cv::Mat cvMat(rows,cols,CV_8UC4); // 8 bits per component,4 channels

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,// Pointer to backing 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,rows),self.CGImage);
    CGContextRelease(contextRef);

    return cvMat;
}

对于灰度:

-(cv::Mat)CVGrayscaleMat
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGFloat cols = self.size.width;
    CGFloat rows = self.size.height;

    cv::Mat cvMat = cv::Mat(rows,CV_8UC1); // 8 bits per component,1 channel

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,// Colorspace
                                                    kCGImageAlphaNone |
                                                    kCGBitmapByteOrderDefault); // Bitmap info flags

    CGContextDrawImage(contextRef,self.CGImage);
    CGContextRelease(contextRef);
    CGColorSpaceRelease(colorSpace);

    return cvMat;
}

这是我的猜测,使其成为3个频道:

-(cv::Mat)CVMat3Channels
{

    //CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat cols = self.size.width;
    CGFloat rows = self.size.height;

    cv::Mat cvMat(rows,CV_8UC3); // 8 bits per component,3 channels

    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,self.CGImage);
    CGContextRelease(contextRef);
    CGColorSpaceRelease(colorSpace);

    return cvMat;
}

但是我收到以下错误

<Error>: CGBitmapContextCreate: invalid data bytes/row: should be 
         at least 9792 for 8 integer bits/component,3 components,kCGImageAlphaNoneSkipLast. 
<Error>: CGContextDrawImage: invalid context 0x0

所以我的问题是,创建兼容8UC3的CGBitmapContext的正确方法是什么?
(我假设8UC3意味着每个像素有8位RGB通道)

谢谢.

PD:图像转换代码来自Robin Summerhill.

解决方法

您正在使用CV_8UC3正确创建3通道图像.由于CGBitmapContextCreate需要9792字节/行,这意味着应该有3264列(3通道像素).如果我运行以下代码,
int cols = 3264;
int rows = 1960; // assuming a ~1.66 aspect ratio here...
Mat temp(rows,CV_8UC3);
cout << temp.step[0] << endl;

它根据CGBitmapContextCreate的要求输出9792.你能告诉cvMat.step [0]在你的代码中返回什么吗?它看起来是正确的,但也许正在发生其他事情.

另外,如果您从OpenCV函数(如imread等)获取图像数据,请注意OpenCV本地存储BGR格式的数据.因此,如果颜色看起来很奇怪,请注意这一点.

猜你在找的C&C++相关文章