How to apply adapthisteq only on part of an image

12 views (last 30 days)
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?

Accepted Answer

Milan Bansal
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
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
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)
rows = 384
cols = 1536
Either explicitly specify the dimensions needed, use vector output, or discard the last output argument. One of the three.
[rows, cols, ~] = size(img)
rows = 384
cols = 512
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')

Sign in to comment.

More Answers (1)

DGM
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')

Categories

Find more on Image Processing Toolbox 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!