加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 03:37:39 所属栏目:百科 来源:网络整理
导读:我试图在OpenCV中使用人物检测功能: cv::HOGDescriptor hog;hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());std::vectorcv::Rect found;hog.detectMultiScale(noMask,found,0.2,cv::Size(8,8),cv::Size(16,16),1.05,2); 但我得到以下
我试图在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格式的数据.因此,如果颜色看起来很奇怪,请注意这一点.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读