我正在使用openCV 3.1.0(我已经尝试使用2.4.9,有同样的问题)。我想将HSV垫输出到jpeg:

// .. Getting JPEG content into memory
// JPEG to mat
Mat imgBuf=Mat(1, jpegContent, CV_8UC3, jpegSize);
Mat imgMat=imdecode(imgBuf, CV_LOAD_IMAGE_COLOR);
free(jpegContent);
if(imgMat.data == NULL) {
    // Some error handling
}
// Now the JPEG is decoded and reside in imgMat
cvtColor(imgMat, imgMat, CV_BGR2HSV); // Converting to HSV
Mat tmp;
inRange(imgMat, Scalar(0, 0, 0), Scalar(8, 8, 8), tmp); // Problem goes here
cvtColor(tmp, imgMat, CV_HSV2BGR);
// Mat to JPEG
vector<uchar> buf;
imencode(".jpg", imgMat, buf, std::vector<int>());
outputJPEG=(unsigned char*)malloc(buf.size());
memcpy(outputJPEG, &buf[0], buf.size());
// ... Output JPEG

问题是,当我用cvtColor(tmp, imgMat, CV_HSV2BGR)进行inRange时,我的程序将因以下原因而失败:



如果我删除了inRange,程序运行正常。我试图删除cvtColor调用,让imencode进行工作,自动将HSV转换为BGR,然后转换为JPEG。这次,没有其他断言失败,但是由于GStreamer抱怨,我的JPEG图像损坏了:



同样,删除inRange也可以解决此问题,它可以产生良好的JPEG数据。

那么,我是否不当调用inRange导致了图像数据损坏?如果是,使用inRange的正确方法是什么?

最佳答案

inRange产生一个单通道二进制矩阵,即一个CV_8UC1矩阵,其值为0255

因此,您无法将tmp转换为HSV2BGR,因为源图像tmp没有3个通道。

OpenCV恰恰告诉您这一点:scn(源通道)不是3。

由于您可能只想保留范围内的一部分图像,然后再转换为BGR,因此您可以:

  • 将范围之外的所有内容设为黑色:imgMat.setTo(Scalar(0,0,0), ~tmp);
  • 将生成的图像转换为BGR:cvtColor(imgMat, imgMat, CV_HSV2BGR);
  • 10-04 14:26