Interpreting color function and adjusting pixels values

c++, computer-vision, image, image-processing, opencv

Solution

I think in this case, Shadows, Midtones and Highlights defines the range of trackbars values.

- Shadows - precise adjusting (small range);

- Midtones - medium adjusting (medium range);

- Highlights - heavy adjusting (wide range).

It allows fast and precise color correction.

The code snippet:

#include <iostream>
#include <vector>
#include <stdio.h>
#include <functional>
#include <algorithm>
#include <numeric>
#include <cstddef>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;

int val_Cyan_Red=0;
int val_Magenta_Green=0;
int val_Yellow_Blue=0;
Mat result;
Mat Img;

void on_trackbar( int, void* )
{
float SH=0.1; // The scale of trackbar ( depends on ajusting mode Shadows/Midtones/Highlights )

float cr_val=(float)val_Cyan_Red/255.0;
float mg_val=(float)val_Magenta_Green/255.0;
float yb_val=(float)val_Yellow_Blue/255.0;
// Cyan_Red
float R1=0;
float G1=1;
float B1=1;

float R2=1;
float G2=0;
float B2=0;

float DR=(1-cr_val)*R1+(cr_val)*R2-0.5;
float DG=(1-cr_val)*G1+(cr_val)*G2-0.5;
float DB=(1-cr_val)*B1+(cr_val)*B2-0.5;

result=Img+(Scalar(DB,DG,DR)*SH);

// Magenta_Green
 R1=1;
 G1=0;
 B1=1;

 R2=0;
 G2=1;
 B2=0;

 DR=(1-mg_val)*R1+(mg_val)*R2-0.5;
 DG=(1-mg_val)*G1+(mg_val)*G2-0.5;
 DB=(1-mg_val)*B1+(mg_val)*B2-0.5;

result+=(Scalar(DB,DG,DR)*SH);

// Yellow_Blue

 R1=1;
 G1=1;
 B1=0;

 R2=0;
 G2=0;
 B2=1;

 DR=(1-yb_val)*R1+(yb_val)*R2-0.5;
 DG=(1-yb_val)*G1+(yb_val)*G2-0.5;
 DB=(1-yb_val)*B1+(yb_val)*B2-0.5;

result+=(Scalar(DB,DG,DR)*SH);

imshow("Result",result);
waitKey(10);
}

// ---------------------------------
// 
// ---------------------------------
int main( int argc, char** argv )
{
    namedWindow("Image",cv::WINDOW_NORMAL);
    namedWindow("Result");

    Img=imread("D:\\ImagesForTest\\cat2.jpg",1);
    Img.convertTo(Img,CV_32FC1,1.0/255.0);  

   createTrackbar("CyanRed", "Image", &val_Cyan_Red, 255, on_trackbar);
   createTrackbar("MagentaGreen", "Image", &val_Magenta_Green, 255, on_trackbar);
   createTrackbar("YellowBlue", "Image", &val_Yellow_Blue, 255, on_trackbar);

    imshow("Image",Img);
    waitKey(0);
}

Yhe result for approximately the values above (zero offset is 128):

Problem

Here is the definition which i read from the net source 1st is `Midtone: Situated between the darkest tone (Black), and the brightest tone (White). For a 24 bit colour image, this occurs when Red = Green = Blue = 128.` and the other is ``` Tones created by dots between 30% and 70% of coverage ``` and `Midtone also refers to the range of colors that aren't mixed with black (the shadows) or white (the highlights).` What i got from these definition is that the pixels whose values are 0 or 255 we should adjust them to 128 . Am i taking the definition right ? I don't want to use the way of Histogram Equalization as according to my knowledge its also use for brightness of image I want to perform the function like below , like i want to perform this function in `OpenCV C++` but i don't know the idea of how to deal with Midtones and CYMK values as it has both RGB and CMYK at the same time For example Sample image After applying the above values I want to do the same in OpenCV My concern is only with the result if we can perform this with only RGB EDIT Answer from Andrey is good but still waiting for the best answer as this answer is difficult for other images to adjust other values of color balance

Original source