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++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...