OpenCV C++: Convert RGBA to HSL and then split channels

15,565

Solution 1

The error is that you're passing to cvSplit a vector of CVMat. Try to look here : http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=cvsplit

Solution 2

If you still want to use a vector for storing the matrices, you need to preallocate them (e.g. vector< Mat > hslChannels(3) will create 3 elements in the vector of type Mat.)

So your code will be:

cv::Mat src;
cv::Mat hsl;

cv::cvtColor(srcRgba , src , CV_RGBA2RGB);
cv::cvtColor(src, hsl, CV_RGB2HLS);

std::vector<cv::Mat> hslChannels(3);
cv::split(hsl, hslChannels);
Share:
15,565
dom
Author by

dom

Full-time geek enthusiastic about longboards &amp; code written in js, c++ or objective-c

Updated on June 04, 2022

Comments

  • dom
    dom almost 2 years

    For some image segmentation work I'd like to use the lightness channel of an image in HSL color space.

    To accomplish this I convert a RGBA image to RGB and then so HSL. After the color conversion I split the image into it's color planes using cv::mixChannels, which gives me black output for the saturation / lightness plane.

    Code:

    cv::Mat src;
    cv::Mat hsl;
    
    cv::cvtColor(srcRgba , src , CV_RGBA2RGB);
    cv::cvtColor(src, hsl, CV_RGB2HLS);
    
    cv::Mat hue = cv::Mat::Mat(hsl.size(), hsl.depth());
    cv::Mat saturation = cv::Mat::Mat(hsl.size(), hsl.depth());
    cv::Mat lightness = cv::Mat::Mat(hsl.size(), hsl.depth());
    
    cv::Mat matsOut[] = { hue, saturation, lightness };
    
    // hsv[0] => hue[0], hsv[1] => saturation[0], hsv[2] => lightness[0]
    int ch[] = { 0,0, 1,0, 2,0 };
    
    // number of elements in hsl -> 1
    // number of elements in matsOut -> 3
    // number of pairs in ch -> 3
    cv::mixChannels(&hsl, 1, matsOut, 3, ch, 3);
    

    Maybe I messed something up with cv::mixChannels?

    EDIT

    This is the cv::split code I used and the error Xcode gives me:

    Code:

    cv::Mat src;
    cv::Mat hsl;
    
    cv::cvtColor(srcRgba , src , CV_RGBA2RGB);
    cv::cvtColor(src, hsl, CV_RGB2HLS);
    
    std::vector<cv::Mat> hslChannels;
    cv::split(hsl, hslChannels);
    

    Error:

    Undefined symbols for architecture x86_64:
      "cv::split(cv::Mat const&, std::__1::vector<cv::Mat, std::__1::allocator<cv::Mat> >&)", referenced from:
          hsvTest(cv::Mat) in test.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    EDIT 2

    Got it, this works:

    cv::Mat src;
    cv::Mat hsl;
    
    cv::cvtColor(srcRgba , src , CV_RGBA2RGB);
    cv::cvtColor(src, hsl, CV_RGB2HLS);
    
    cv::Mat hslChannels[3];
    cv::split(hsl, hslChannels);
    

    Now the hue plane is completely black, but saturation and lightness plane are looking okay …