Problem:
I'm encountering an issue with color while trying to apply a selected hue value into some image data using OpenCV.
After applying the hue value +50, the output color doesn't resemble what I see in Photoshop when I check its +50 result.
- The first screenshot shows the original image without applying the hue value.
- The second screenshot displays the image with a
+50hue value in Photoshop. - The third screenshot shows the image with a
+50hue value using the OpenCV code.
(as displayed in: ImGui).
Question:
How can I adjust the code to make the image appear similar to the one adjusted with a +50 hue value in Photoshop?
In the code below, currentImage contains the image data in CV::Mat format, and hueFactor represents the applied hue value, which is +50.
I've implemented the following function:
cv::Mat apply_hue_for_data(cv::Mat ¤tImage, float hueFactor) {
// Create the output image with the same size and type as the current
image cv::Mat outputImage = currentImage.clone();
// Separate the alpha channel
std::vector<cv::Mat> channels(4);
cv::split(outputImage, channels);
cv::Mat alpha = channels[3];
// Convert the image from BGR to HSV
cv::cvtColor(outputImage, outputImage, cv::COLOR_BGRA2BGR);
cv::cvtColor(outputImage, outputImage, cv::COLOR_BGR2HSV);
// Loop through the rows
for (int y = 0; y < outputImage.rows; ++y) {
// Loop through the columns
for (int x = 0; x < outputImage.cols; ++x) {
// Retrieve the pixel value
cv::Vec3b &pixelValue = outputImage.at<cv::Vec3b>(y, x);
// Adjust the hue value
int hue = static_cast<int>(pixelValue[0]) + static_cast<int>(hueFactor * 179.0f);
// Ensure the hue value wraps around correctly within the 0-179 range
hue = hue % 180;
if (hue < 0) {
hue += 180;
}
pixelValue[0] = static_cast<uchar>(hue);
}
}
// Convert the image back to BGR
cv::cvtColor(outputImage, outputImage, cv::COLOR_HSV2BGR);
// Merge the alpha channel back
std::vector<cv::Mat> bgrChannels;
cv::split(outputImage, bgrChannels);
std::vector<cv::Mat> bgraChannels = {bgrChannels[0], bgrChannels[1], bgrChannels[2], alpha};
cv::merge(bgraChannels, outputImage);
// Return the modified image data
return outputImage;
}
Any help please?
I have tried applying the hue value for the image data by using the above code, but after applying the hue value, the color doesn't resemble what I see in Photoshop.

Your code assumes
+50hue value to mean jumping near to 120 degrees (gives Greens), but Photoshop only goes half that distance to land near 60 degrees (gives Yellows).You can see that on an R-G-B colour wheel, Red always starts at 0 degrees.
Looking at an example of the "Reds" in your input image, you can see that the model's hair and jacket have a hue of: (Red) 0 degrees, now your code does a
+50hue shift (or colour wheel rotation) which rotates the red dot to be now positioned at 120 degrees, so the old hue Red is now replaced by a new hue of: (Green) 120.PS:
Your Greens have a strong hint of Yellow so I suspect you are actually landing in the 90 to 100 degree area.
Whats going on here? Let's investigate the docs...
Son of a... So they really mapped 360 degrees into 180 levels? Yes, crazy but true.
(note: There is a 360/255 option called
COLOR_BGR2HSV_FULLso they are trying to be helpful within the limits).Two Possible Solution(s):
(1) Fix at the input reading side:
You can counter the above equation with:
Where: In color, the code's resulting 25 degrees should match the Photoshop result at its
+50hue offsetting.(untested example, no C++ compiler here):
(2) Or Else.. Fix at the output writing side:
So you have green output, how can you still match Photoshop with these green pixels?
You can try ADDing the two images together. This means:
You need two arrays (or vectors) each of length 3, that is one to hold the Input's R-G-B and the other holds the Output's R-G-B.
Add 50% from each side's related component.
The new result should match (or be close) to the Photoshop output.
Some pseudo-code: