我试图在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格式的数据.因此,如果颜色看起来很奇怪,请注意这一点.