Contrast Stretching with law
3 views (last 30 days)
Show older comments
Hello, I want implementation contrast stretching with the below law. But i can't success perfectly :(
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/155697/image.jpeg)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/155698/image.jpeg)
img = imread('rice.png');
%Get Maximum and minimum Of Image
oldMin = min(img(:));
oldMax = max(img(:));
% New Min and Max value
newMin = 0 ;
newMax = 255;
newImg = uint8(zeros(size(img)));
for i = 1:1:length(img)
for j = 1:1:length(img)
if ( img(i,j) <50)
newImg(i,j) = 0;
elseif ( (img(i,j) >200))
newImg(i,j) = 1;
else
newImg(i,j) = ((img(i,j)-oldMin)*((newMax-newMin)/(oldMax-oldMin))+newMin);
end
end
end
figure;
subplot(2,2,1);
imshow(img);
title('Original Image');
subplot(2,2,2);
imhist(img);
title('Histogram Of Original Image');
subplot(2,2,3);
imshow(newImg);
title('Modify Image');
subplot(2,2,4);
imhist(newImg);
title('Histogram Of Modify Image');
0 Comments
Answers (1)
DGM
on 23 Mar 2022
Edited: DGM
on 23 Mar 2022
Here:
% inputs
inpict = imread('peppers.png');
invec = linspace(0,1,100); % for creating line plot
% k is [alpha beta gamma]
% but calling things gamma is only going to create confusion
% this vector can be variable-length
% breakpoints will be spaced uniformly on x
k = [0.5 1 0.5];
% process things
outvec = kcurves(invec,k);
inpict = im2double(inpict);
outpict = kcurves(inpict,k);
outpict = im2uint8(outpict);
% plot stuff
imshow(outpict)
figure
plot(invec,outvec)
axis square
grid on
xlim([0 1])
ylim([0 1])
xlabel('input')
ylabel('output')
This seems like a cumbersome way of parameterizing the task. You have control over slopes, but usually levels are at least as important. The fact that the curve is pinned at 0 seems limiting.
It almost seems more convenient to just pick the breakpoints directly. Any set of points (see xx and yy) on this unit interval can be defined to create an arbitrary curve. Also, the interpolation options available with interp1() means that it can be a smooth curve. Using a piecewise-linear curve is a good way to create noticeable banding artifacts in local contrast.
If all that's desired is a simplified means to trade midtone contrast for highlight/shadow contrast, a single-parameter method might be:
% a test vector
invec = linspace(0,1,100);
% process
kcont = 2; % contrast factor
outvec = stretchcurve(invec,kcont);
% plot things
plot(invec,outvec)
axis square
grid on
xlim([0 1])
ylim([0 1])
xlabel('input')
ylabel('output')
Much like a simple gamma adjustment, this method preserves black and white. This is the same as the 'contrast' term used in MIMT imlnc() (on the File Exchange).
% the support functions %%%%%%%%%%%%%%%%%%%%%%%%
function outpict = kcurves(inpict,k)
% input breakpoints
xx = linspace(0,1,numel(k)+1);
% output breakpoints
va = xx(2)*k(1);
vb = (xx(3)-xx(2))*k(2) + va;
vc = (xx(4)-xx(3))*k(3) + vb;
yy = [0 va vb vc];
outpict = interp1(xx,yy,inpict,'linear');
end
function outpict = stretchcurve(inpict,kc)
if kc == 1
outpict = inpict;
return;
end
c = 0.5; % input pivot point
mk = abs(kc) < 1;
mc = c < 0.5;
if ~xor(mk,mc)
pp = kc; kk = kc*c/(1-c);
else
kk = kc; pp = (1-c)*kc/c;
end
hi = inpict > c; lo = ~hi;
outpict = zeros(size(inpict));
outpict(lo) = 0.5*((1/c)*inpict(lo)).^kk;
outpict(hi) = 1-0.5*((1-inpict(hi))*(1/(1-c))).^pp;
end
0 Comments
See Also
Categories
Find more on Histograms in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!