11

I am using a Scalar to define the color of a rectangle I am drawing with OpenCV:

rectangle(imgOriginal, Point(0, 0), Point(25, 50), Scalar(H, S, V), CV_FILLED);

However, the color is defined in HSV color space rather than RGB (imgOriginal is RGB).

How do I convert Scalar (or its input, the integer variables H, S, and V) to RGB?

(So far I only found answers telling me how to convert a whole image with cvtColor which is not what I want.)

fuenfundachtzig
  • 7,952
  • 13
  • 62
  • 87
  • https://stackoverflow.com/questions/35737032/convert-a-single-color-with-cvtcolor Does this help or does this fall into "convert a whole image"? – Tony J Apr 04 '17 at 21:32
  • Yes, similar to Rama's solution below -- I'm still surprised that it takes two additional structures to perform this seemlingly simple task, whereas everything else is so sleek in OpenCV. – fuenfundachtzig Apr 05 '17 at 06:23

4 Answers4

8

Although not optimal, You can use the following:

Scalar ScalarHSV2BGR(uchar H, uchar S, uchar V) {
    Mat rgb;
    Mat hsv(1,1, CV_8UC3, Scalar(H,S,V));
    cvtColor(hsv, rgb, CV_HSV2BGR);
    return Scalar(rgb.data[0], rgb.data[1], rgb.data[2]);
}
Morris Franken
  • 2,435
  • 3
  • 19
  • 13
  • 1
    Gives `error: could not convert ‘rgb.cv::Mat::at >(0)’ from ‘cv::Vec’ to ‘cv::Scalar {aka cv::Scalar_}’` on the last line. – fuenfundachtzig Apr 05 '17 at 16:57
  • @fuenfundachtzig maybe a direct conversion from Vec3b to Scalar is only an OpenCV3 thing, I'll update the code to be compatible. – Morris Franken Apr 05 '17 at 17:06
4

This worked for me,

Mat rgb;
Mat hsv(1, 1, CV_8UC3, Scalar(224, 224, 160));

cvtColor(hsv, rgb, CV_HSV2BGR);
Scalar rgb = Scalar((int)rgb.at<cv::Vec3b>(0, 0)[0],(int)rgb.at<cv::Vec3b>(0, 0)[0],(int)rgb.at<cv::Vec3b>(0, 0)[0])
tinkerbell
  • 421
  • 4
  • 12
1

OpenCV 3.2.0. Note: h is in range [0,360] and l and s is in [0,1]

        Mat hls(1, 1, CV_32FC3, Scalar(h, l, s));
        Mat rgb;
        cvtColor(hls, rgb, COLOR_HLS2RGB);
        Scalar c = Scalar(255*rgb.at<float>(0,0), 255*rgb.at<float>(0,1), 255*rgb.at<float>(0,2));
j-a
  • 1,780
  • 1
  • 21
  • 19
-1

Use this to convert a single value:

cv::Vec3f rgb;
cv::Vec3f hsv;
hsv[0] = H;
hsv[1] = S;
hsv[2] = V;
cvtColor(hsv, rgb, CV_HSV2BGR);

Then you can use it:

rectangle(imgOriginal, Point(0, 0), Point(25, 50), 
    Scalar(rgb[0], rgb[1], rgb[2]), CV_FILLED);
Rama
  • 3,222
  • 2
  • 11
  • 26
  • 1
    This throws an exception: `OpenCV Error: Assertion failed (scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F)) in cvtColor, file /build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/imgproc/src/color.cpp, line 4040` – fuenfundachtzig Apr 05 '17 at 06:31
  • 2
    Sorry, but that still gives the same exception...? – fuenfundachtzig Apr 05 '17 at 16:02