c++opencvmaskhsvbgr

How do I convert HSV mask to BGR?


For this colour detection program I'm writing, I essentially convert an image to HSV and mask it to detect yellow (so white where yellow is, black otherwise) & then simply see if a given pixel is white or not.

    const cv::Mat roiImage = // read in image ... ;

    cv::Mat tmpMask ;
    cv::cvtColor(roiImage, tmpMask, cv::COLOR_BGR2HSV) ;
    cv::inRange(tmpMask, cv::Scalar(20, 100, 100), cv::Scalar(30, 255, 255), tmpMask) ;

Problem is, to see if a given pixel is white in value, I try to convert it back to BGR, but opencv keeps throwing an error regarding the fact the mask has one channel, BGR has 3 (I don't need explaining as to why this is the case, question is further below)

    cv::Mat yellowMask ; cv::cvtColor(tmpMask, yellowMask, cv::COLOR_HSV2BGR) ;
                                               // ^ error here
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.2.0) ../modules/imgproc/src/color.simd_helpers.hpp:92: error: (-2:Unspecified error) in function 'cv::impl::{anonymous}::CvtHelper<VScn, VDcn, VDepth, sizePolicy>::CvtHelper(cv::InputArray, cv::OutputArray, int) [with VScn = cv::impl::{anonymous}::Set<3>; VDcn = cv::impl::{anonymous}::Set<3, 4>; VDepth = cv::impl::{anonymous}::Set<0, 5>; cv::impl::{anonymous}::SizePolicy sizePolicy = cv::impl::<unnamed>::NONE; cv::InputArray = const cv::_InputArray&; cv::OutputArray = const cv::_OutputArray&]'
> Invalid number of channels in input image:
>     'VScn::contains(scn)'
> where
>     'scn' is 1

The only work around I've found is to write the mask externally (ie save it as an image) and then read it in, and presto that works, but is horribly inefficient.

How can I find a workaround for this issue? Thanks for your time

(ps. for context, yellow is a horrible colour to detect. I use distancing to see if a pixel is closest to BGR orange, black, blue, white or grey. If the pixel is orange, I then check if the corresponding pixel in the mask was detected as yellow. If the pixel is white, I say it’s yellow, else its actually orange. the system works perfectly, I just want to not have to save it externally)


Solution

  • "Your tmpMask is a single channel (i.e. grayscale) image, so you can't convert from HSV, which would be a three channel (i.e. color) image. Also, you don't need to convert to BGR. Simply check, where tmpMask is 255 (white in "grayscale color space")." ~ @HansHirse

    cv::cvtColor(tmpMask, yellowMask, cv::COLOR_GRAY2BGR) ;