Histogram equalization
This method usually increases the global contrast of many images, especially when the usable data of the image is represented by close contrast values. Through this adjustment, the intensities
can be better distributed on the histogram. This allows for areas of
lower local contrast to gain a higher contrast. Histogram equalization
accomplishes this by effectively spreading out the most frequent
intensity values. The method is useful in images with backgrounds and foregrounds that
are both bright or both dark. In particular, the method can lead to
better views of bone structure in x-ray images, and to better detail in photographs that are over or under-exposed. A key advantage of the method is that it is a fairly straightforward technique and an invertible operator. So in theory, if the histogram equalization function is known, then the original histogram can be recovered. The calculation is not computationally intensive. A disadvantage of the method is that it is indiscriminate. It may increase the contrast of background noise, while decreasing the usable signal.
In scientific imaging where spatial correlation is more important than intensity of signal (such as separating DNA fragments of quantized length), the small signal to noise ratio usually hampers visual detection. Histogram equalization often produces unrealistic effects in photographs; however it is very useful for scientific images like thermal, satellite or x-ray images, often the same class of images that user would apply false-color to. Also histogram equalization can produce undesirable effects (like visible image gradient) when applied to images with low color depth. For example, if applied to 8-bit image displayed with 8-bit gray-scale palette it will further reduce color depth
(number of unique shades of gray) of the image. Histogram equalization
will work the best when applied to images with much higher color depth than palette size, like continuous data or 16-bit gray-scale images.
There are two ways to think about and implement histogram equalization, either as image change or as palette change. The operation can be expressed as P(M(I)) where I is the original image, M is histogram equalization mapping operation and P is a palette. If we define a new palette as P'=P(M) and leave image I unchanged then histogram equalization is implemented as palette change. On the other hand if palette P remains unchanged and image is modified to I'=M(I) then the implementation is by image change. In most cases palette change is better as it preserves the original data.
Image Enhancement by Histogram Equalization
The Histogram Equalization algorithm enhances the contrast of images by transforming the values in an intensity image so that the histogram of the output image is approximately flat.I = imread('pout.tif');
J = histeq(I);
subplot(2,1,1);
imhist(I)
subplot(2,1,2);
imhist(J)
MATLAB Design
design_name = 'mlhdlc_heq.m'; testbench_name = 'mlhdlc_heq_tb.m';Let us take a look at the MATLAB design
type(design_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % heq.m % Histogram Equalization Algorithm %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [x_out y_out pixel_out] = ... mlhdlc_heq(x_in, y_in, pixel_in, width, height) persistent histogram persistent transferFunc persistent histInd persistent cumSum if isempty(histogram) histogram = zeros(1, 2^14); transferFunc = zeros(1, 2^14); histInd = 0; cumSum = 0; end % Figure out indexes based on where we are in the frame if y_in < height && x_in < width % valid pixel data histInd = pixel_in + 1; elseif y_in == height && x_in == 0 % first column of height+1 histInd = 1; elseif y_in >= height % vertical blanking period histInd = min(histInd + 1, 2^14); elseif y_in < height % horizontal blanking - do nothing histInd = 1; end %Read histogram (must be outside conditional logic) histValRead = histogram(histInd); %Read transfer function (must be outside conditional logic) transValRead = transferFunc(histInd); %If valid part of frame add one to pixel bin and keep transfer func val if y_in < height && x_in < width histValWrite = histValRead + 1; %Add pixel to bin transValWrite = transValRead; %Write back same value cumSum = 0; elseif y_in >= height %In blanking time index through all bins and reset to zero histValWrite = 0; transValWrite = cumSum + histValRead; cumSum = transValWrite; else histValWrite = histValRead; transValWrite = transValRead; end %Write histogram (must be outside conditional logic) histogram(histInd) = histValWrite; %Write transfer function (must be outside conditional logic) transferFunc(histInd) = transValWrite; pixel_out = transValRead; x_out = x_in; y_out = y_in;
type(testbench_name);
%Test bench for Histogram Equalization testFile = 'mlhdlc_img_drive1.tif'; imgOrig = imread(testFile); [height width] = size(imgOrig); imgOut = zeros(height,width); hBlank = 20; % make sure we have enough vertical blanking to filter the histogram vBlank = ceil(2^14/(width+hBlank)); for frame = 1:2 disp(['working on frame: ', num2str(frame)]); for y_in = 0:height+vBlank-1 %disp(['frame: ', num2str(frame), ' of 2, row: ', num2str(y_in)]); for x_in = 0:width+hBlank-1 if x_in < width && y_in < height pixel_in = double(imgOrig(y_in+1, x_in+1)); else pixel_in = 0; end [x_out y_out pixel_out] = ... mlhdlc_heq(x_in, y_in, pixel_in, width, height); if x_out < width && y_out < height imgOut(y_out+1,x_out+1) = pixel_out; end end end figure(1) subplot(2,2,1); imshow(imgOrig, []); title('Original Image'); subplot(2,2,2); imshow(imgOut, []); title('Equalized Image'); subplot(2,2,3); hist(double(imgOrig(:)),2^14-1); title('Histogram of original Image'); subplot(2,2,4); hist(double(imgOut(:)),2^14-1); title('Histogram of equalized Image'); endIt is always a good practice to simulate the design with the testbench prior to code generation to make sure there are no runtime errors.
mlhdlc_heq_tb
working on frame: 1 working on frame: 2
Executing the following lines copies the necessary files into a temporary folder
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_heq']; % create a temporary folder and copy the MATLAB files cd(tempdir); [~, ~, ~] = rmdir(mlhdlc_temp_dir, 's'); mkdir(mlhdlc_temp_dir); cd(mlhdlc_temp_dir); % copy files to the temp dir copyfile(fullfile(mlhdlc_demo_dir, design_name), mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, testbench_name), mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_img_drive1.tif'), mlhdlc_temp_dir);
coder -hdlcoder -new mlhdlc_heq_prjNext, add the file 'mlhdlc_heq.m' to the project as the MATLAB Function and 'mlhdlc_heq_tb.m' as the MATLAB Test Bench.
You can refer to Getting Started with MATLAB to HDL Workflow tutorial for a more complete tutorial on creating and populating MATLAB HDL Coder projects.
Launch HDL Advisor and right click on the 'Code Generation' step and choose the option 'Run to selected task' to run all the steps from the beginning through the HDL code generation.
Examine the generated HDL code by clicking on the hyperlinks in the Code Generation Log window.
You can run the following commands to clean up the temporary project folder.
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_heq']; clear mex; cd (mlhdlc_demo_dir); rmdir(mlhdlc_temp_dir, 's');