How to apply adapthisteq only on part of an image
4 views (last 30 days)
Show older comments
Hi. I have an image of 1024 x 1024 px from a 16bit camera. I want to apply adapthisteq only to the right half and the bottom half of the image. Can someone please help me how this can be done?
0 Comments
Accepted Answer
Milan Bansal
on 27 Mar 2024
Hi Tomer
To apply "adapthisteq" (Adaptive Histogram Equalization) only to the right half and the bottom half of the image, please follow the steps given in the code snippet below.
% 1.) Read the image
img = imread('img.jpg');
% 2.) Get the size of the image
[rows, cols] = size(img);
% 3.) Get the midpoint for both dimensions
midRow = rows / 2; midCol = cols / 2;
% 4.) Separate the image into four quarters
topLeft = img(1:midRow, 1:midCol);
topRight = img(1:midRow, midCol+1:end);
botLeft = img(midRow+1:end, 1:midCol);
botRight = img(midRow+1:end, midCol+1:end);
% 5.) Apply "adapthisteq" to the quaters belonging to right half and bottom half
topRightEq = adapthisteq(topRight);
bottomLeftEq = adapthisteq(botLeft);
bottomRightEq = adapthisteq(botRight);
% 6.) Reconstruct the bottom and right halves
bottomHalfEq = [bottomLeftEq, bottomRightEq];
rightHalfEq = [topRightEq; bottomRightEq];
% 7.) Reconstruct the image with equalization applied only once to each part
imgModified = img; % Start with the original image
imgModified(1:midRow, midCol+1:end) = rightHalfEq(1:midRow, :); % Update right half
imgModified(midRow+1:end, :) = bottomHalfEq; % Update bottom half
% 8.) Display the original and modified images for comparison
figure;
subplot(1, 2, 1);
imshow(img, []);
title('Original Image');
subplot(1, 2, 2);
imshow(imgModified, []);
title('Modified Image');
Please refer to the following documentation link to learn more about the "adapthisteq" function.
Hope this helps.
3 Comments
Image Analyst
on 27 Mar 2024
@Tomer You can make a logical mask, then convert it to double and blur it with conv2 or imfilter. Then multiply the mask by one region and multiply one minus the mask to the other region, then add the regions together.
DGM
on 27 Mar 2024
Edited: DGM
on 27 Mar 2024
This is wrong. When requesting n scalar outputs from size(), the nth output argument is not the size of the nth dimension. It's the product of the sizes of the nth dimension and all trailing dimensions.
img = imread('peppers.png'); % 384x512x3
% 2.) Get the size of the image
[rows, cols] = size(img)
Either explicitly specify the dimensions needed, use vector output, or discard the last output argument. One of the three.
[rows, cols, ~] = size(img)
Adapthisteq() only operates on single-channel images, and you're interchangably operating on reshaped slices of RGB and otherwise only on the red channel alone. The result is going to be inconsistent and wrong.
That aside, the transformation applied by adapthisteq() is dependent on local information, so you can't just subdivide an image, process the segments, and then reassemble it and expect there to not be discontinuities at the segment boundaries.
% any RGB or gray image
inpict = imread('peppers.png');
% get the actual correct size
sz = size(inpict,1:3);
% split the image
LH = inpict(:,1:floor(sz(2)/2),:);
RH = inpict(:,floor(sz(2)/2)+1:end,:);
% process all channels of the entire image
for ch = 1:sz(3)
% set the parameters as needed
LH(:,:,ch) = adapthisteq(LH(:,:,ch),'cliplimit',0.005);
RH(:,:,ch) = adapthisteq(RH(:,:,ch),'cliplimit',0.005);
end
% reassemble the image
outpict = [LH RH];
% display it
imshow(outpict,'border','tight')
More Answers (1)
DGM
on 27 Mar 2024
Edited: DGM
on 27 Mar 2024
I'm going to assume that this is what you mean when you say "right half and bottom half". This will work regardless of whether the image is gray or RGB.
% any RGB or gray image
inpict = imread('peppers.png');
% get the actual correct size
sz = size(inpict,1:3);
% process all channels of the entire image
outpict = zeros(sz,class(inpict));
for ch = 1:sz(3)
% set the parameters as needed
outpict(:,:,ch) = adapthisteq(inpict(:,:,ch),'cliplimit',0.005);
end
% insert the NW corner back into the output
xrange = 1:round(sz(2)/2);
yrange = 1:round(sz(1)/2);
outpict(yrange,xrange,:) = inpict(yrange,xrange,:);
% display it
imshow(outpict,'border','tight')
There will be visible transitions, but only at the edge of the ROI, not within the ROI. If you want to ease those edges as well, then ...
% any RGB or gray image
inpict = imread('peppers.png');
% get the actual correct size
sz = size(inpict,1:3);
% process all channels of the entire image
outpict = zeros(sz,class(inpict));
for ch = 1:sz(3)
% set the parameters as needed
outpict(:,:,ch) = adapthisteq(inpict(:,:,ch),'cliplimit',0.005);
end
% create soft mask
mask = zeros(sz(1:2));
mask(1:round(sz(1)/2),1:round(sz(2)/2)) = 1;
mask = imgaussfilt(mask,10); % soften it by some amount
% insert the NW corner back into the output
outpict = mask.*double(inpict) + (1-mask).*double(outpict);
outpict = cast(outpict,class(inpict));
% display it
imshow(outpict,'border','tight')
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!