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

懵懂的女人 提交于 2019-12-12 00:09:08

问题


I am using openCV 3.1.0 (I have tried with 2.4.9, with same problem). I want to output a HSV mat to 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

The problem is, when i do cvtColor(tmp, imgMat, CV_HSV2BGR) with inRange, my program will fail with:

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

If i removed inRange, the program work just fine. I have tried to remove the cvtColor call, letting imencode to do its job, automatically converting HSV to BGR then to JPEG. This time, no more assertion failed, but i got corrupted JPEG image, as GStreamer complains:

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

Again, removing inRange also solves this issue, it produces good JPEG data.

So, is that i am invoking inRange improperly that cause corrupted image data? If yes, what is the correct way to use inRange?


回答1:


inRange produces a single channel binary matrix, i.e. a CV_8UC1 matrix with values either 0 or 255.

So you cannot convert tmp with HSV2BGR, because the source image tmp doesn't have 3 channels.

OpenCV is telling you exactly this: scn (source channels) is not 3.


Since you probably want to keep and then convert to BGR only part of the image in your range, you can:

  1. set to black everything outside the range: imgMat.setTo(Scalar(0,0,0), ~tmp);
  2. convert the resulting image to BGR: cvtColor(imgMat, imgMat, CV_HSV2BGR);


来源:https://stackoverflow.com/questions/37922555/error-when-converting-from-hsv-to-bgr-or-hsv-to-jpeg-in-opencv-after-using-inra

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!