How to manually adjust contrast of Image and then Display (percent Contrast)

11 ビュー (過去 30 日間)
R.S.
R.S. 2017 年 11 月 13 日
回答済み: DGM 2024 年 7 月 3 日
Hi, I'm a bit confused with how Percent contrast is calculated within Imaging software (eg 0% to 100%). This may be more a mathematical question than a MATLAB question, but I'll post the code. I have an matrix image "Im" let's say [1024 1024] with various intensity values. I understand a subset of intensity values is stretched to the desired output range, let's assume linearly, to change contrast. But what in the world does a "percentage" mean? 50% on most programs denotes no change in contrast. Contrast stretching is given by the following equation (which is a pixel operation)
Im_new = a.*(Im - Imid)+Imid
(brightness has been taken out of this equation). This is how I think it is performed in most imaging softwares, where a is some coefficient that should be
a = (highestIntensityOutput - lowestIntensityOutput)/(highestIntensityInitial-lowestIntensityInitial).
If a>1, some percentage of histogram above and below certain mid-range intensity values is threshholded, but I may be wrong.
Here is my code for adjusting contrast display manually: (Im is for original image)
%%Create and Show histogram
vec = I(:);
minn =min(vec);
maxx =max(vec);
nbins = maxx-minn;
edges = linspace(minn,maxx,nbins);
hist_c = histcounts(vec,nbins);
% bar(edges(1:nbins), hist_c); hold on; % if want bar plot
plot(edges(1:nbins), hist_c); %easier to work with a plot
Now let's say you have chosen to use a subset of the intensity values in the image and have selected loValue and hiValue as the range for your intensity values. Then we find the midpoint of this range for our contrast calculation (Note: this may be either wrong, or clunky).
%%calculate midpoint intensity within desired intensity range
lo = abs(edges-loValue);
hi = abs(edges-hiValue);
[~, i] = sort(lo);
[~,j]=sort(hi);
mid = round((j(1)-i(1))/2)+i(1);
midI = edges(mid);
Now we have the mid-Intensity value about which we will adjust the contrast. For the desired percent <50% contrast, I would assume the following (and this is where I might be horribly wrong), where cPer is "percent contrast". Note, this is only for percent contrast <50%.
a = (cPer/100)*2;
Ig = a.*(I-midI)+midI; %calculate new image Ig
Ig(Ig<loValue) = loValue; %threshhold with desired min/max intensity values permitted
Ig(Ig>hiValue) = hiValue;
Is this correct? Is this how the "percent contrast" is calculated below 50% (I will make another post for above 50%). Comparison to the software tells me no. What I essentially did was map 0 (%) to 50(%) to values from 0 to 1 for the "a" stretch coefficient, which is what I assumed the software was doing. Sorry if this is such a confusing question, I'm probably making it 50x more complicated than it actually is.
  1 件のコメント
R.S.
R.S. 2017 年 11 月 14 日
編集済み: R.S. 2017 年 11 月 14 日
I see Image Analyst has previously responded to a slightly similar question, and put the equation from slider bars as
y = slope * (x - offset) + 0.5; % Output gray level
where "offset" was the brightness on slider bar and slope was the contrast from a slider bar, and input values were in range [0,1]. Perhaps if I normalized my histogram in the [0 1] range I could use this equation. Still confused by the Percentages in the slider bars on Image analysis software. Many thanks for any help you all can provide.

サインインしてコメントする。

回答 (1 件)

DGM
DGM 2024 年 7 月 3 日
I'm not really sure from what context the term "percent contrast" was taken here. It seems like it's referring to the arbitrary labels on UI controls.
If that's the case, then it varies. Whoever writes the software can dream up any relationship between the user controls and the end result. Disregarding the particular limits of the user slider, there's no guarantee that two apps perform the same underlying transformation.
That said, I think that the common assumption is something like the following. For simple linear contrast curve with a fixed pivot at 50% gray, the transformation is something like:
% inputs
A = linspace(0,1,100); % an "image"
contrast = 0.5; % the parameter
% the transformation
th = tan((contrast + 1)*pi/4);
B = (A - 0.5)*th + 0.5;
% plot the curve
plot(A,B)
unitaxes(gca)
This is fundamentally the same transformation performed by the brightness-contrast tools in both GIMP and ImageMagick, as well as MIMT imbcg(). The only difference here is the parameter mapping. This example comes straight from imbcg(), where the control parameter is in the range [-1 1]. In GIMP, it would be [-127 127]. In ImageMagick, it would be [-100 100]. It would be trivial to map it to [0 100], though I would find it confusing to put the null point anywhere other than 0.
Of course, the simpler the task, the more ways there tends to be to get the job done. ImageMagick and a few MIMT tools offer "contrast" controls which are nonlinear (sigmoidal). I don't even know whether MIMT and IM implementations are performed similarly. Similarly, the common additive brightness adjustment that's usually paired with such simple brightness-contrast tools isn't actually what's used by GIMP. Likewise, the MATLAB tool called brighten() isn't even a linear brightness tool. It's a bidirectional gamma adjustment tool implemented using a piecewise mapping between linear controls and the nonlinear gamma parameter. While the underlying transformation is as trivial as X.^gamma, the process is only obfuscated by mapping [0 1 Inf) to [-1 0 1].
So I guess the takeaway is that unless you test it (or dig through the source code *cough*) it's hard to always know what the core transformation exactly is. It's easily obfuscated using whatever control mapping the dev wants for whatever reason they want. Considering nonlinear variants, I think the control extents are more generally descriptive of the underlying math or some chosen limits than they are some sort of maximal state of image properties. Remember that a given image may achieve maximal contrast well before the control parameter is maximized.
I don't even know if I answered anything. Probably not.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by