使用 inRange 后在 openCV 中从 HSV 转换为 BGR 或从 HSV 转换为 JPEG 时出错

Error when converting from HSV to BGR, or HSV to JPEG in openCV after using inRange

我使用的是 openCV 3.1.0(我试过 2.4.9,但有同样的问题)。我想输出一个 HSV mat 到 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

问题是,当我使用 inRange 执行 cvtColor(tmp, imgMat, CV_HSV2BGR) 时,我的程序将失败并显示:

OpenCV Error: Assertion failed (scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F)) in cvtColor, file /home/pi/opencv/src/opencv-3.1.0/modules/imgproc/src/color.cpp, line 8176

terminate called after throwing an instance of 'cv::Exception' what(): /home/pi/opencv/src/opencv-3.1.0/modules/imgproc/src/color.cpp:8176: error: (-215) scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) in function cvtColor

如果我删除了 inRange,程序工作正常。我试图删除 cvtColor 调用,让 imencode 完成它的工作,自动将 HSV 转换为 BGR,然后再转换为 JPEG。这一次,没有更多的断言失败,但我得到了损坏的 JPEG 图像,正如 GStreamer 抱怨的那样:

gstrtpjpegpay.c(581): gst_rtp_jpeg_pay_read_sof (): /GstPipeline:pipeline0/GstRtpJPEGPay:rtpjpegpay0 WARNING: from element /GstPipeline:pipeline0/GstRtpJPEGPay:rtpjpegpay0: Wrong SOF length 11.

同样,删除 inRange 也解决了这个问题,它产生了良好的 JPEG 数据。

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

inRange 生成单通道二进制矩阵,即 CV_8UC1 矩阵,其值可以是 0255.

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

OpenCV 准确地告诉您:scn(源频道)不是 3.


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

  1. 设置为黑色范围外的所有内容:imgMat.setTo(Scalar(0,0,0), ~tmp);
  2. 将生成的图像转换为 BGR:cvtColor(imgMat, imgMat, CV_HSV2BGR);