Question

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

enter image description here

For example Sample image

enter image description here

After applying the above values

enter image description here

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

Was it helpful?

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): enter image description here

OTHER TIPS

Mid-Tone regions are the intermediate shaded areas in any image, at almost halfway between brightest and the darkest area of an image, it is not necessary that they have to be around 128. In case of overexposed image the mid-tones region will be at much higher value compared to a dark or under-exposed image. However if you perform histrogram equalization, then it will be set to a value close to 128[for 8-bit image].

Regarding how to obtain the mid-tonal region, I think you can simply get this information from histrogram.

  1. convert your image to gray scale.
  2. Get the histrogram.
  3. Do Histrogram equalization.
  4. Now the centeral intersity values(e.g between 255/3 to 2*255/3) are the mid-tones.

Use OpenCV's split function to split the image into red, green, and blue channels.

Now, from the looks of the second image, it appears that the blues and greens are more prominent and the reds are being suppressed. So, divide the red channel by, say, 1.5.

Then use the OpenCV's merge function to recombine the channels. Now, you have the same image but the reds are weaker than the blues and greens, and this should result in the desired image.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top