# How to draw a histogram of an image in a triangle?

12 views (last 30 days)

Show older comments

I want to get the output image histogram this way

I found the following code from the tutorials of this site after searching, but unfortunately I could not get the output

If possible, please guide me

##### 0 Comments

### Accepted Answer

Image Analyst
on 24 Nov 2021

Triangle thresholding has nothing to do with the shape of the histogram, so you don't need the triangle_th() function.

I have a demo for how to get a histogram of any shape you want:

For the demo I made the histogram look like the profile of the woman as shown above. The original image histogram is on the left and the histogram of the modified image is on the right. You could make it a triangle. Basically you need to define the shape you want (a triangle), then cast the image to double, then add a half gray level of noise to the image (to make all pixels have a unique gray level), then sort the gray levels. Then start taking the darkest ones and assigning them to the gray level you're at, then move to the next bin and assign the proper number of pixels a gray level of that bin, and so on all the way across your profile until all pixels have been used up.

The image processing toolbox also has a histmatch() function that you might try.

### More Answers (2)

Image Analyst
on 25 Nov 2021

Really I think you could do it. I did it in just a few minutes.

Before I give you all the source code tell me if it's your homework, because I don't want you to get into trouble by submitting my code as your own.

Here's a snippet

clc; % Clear the command window.

fprintf('Beginning to run %s.m ...\n', mfilename);

close all; % Close all figures (except those of imtool.)

clearvars;

workspace; % Make sure the workspace panel is showing.

format long g;

format compact;

fontSize = 18;

grayImage = imread('cameraman.tif');

[rows, columns, numberOfColorChannels] = size(grayImage);

if numberOfColorChannels == 3

grayImage = rgb2gray(grayImage);

end

subplot(2, 3, 1);

imshow(grayImage);

title('Input Image', 'FontSize', fontSize);

subplot(2, 3, 2);

imhist(grayImage);

grid on;

title('Histogram of Input Image', 'FontSize', fontSize);

% Create noise image.

noiseImage = rand(rows, columns) - 0.5;

% Add noise to gray scale image to make all gray levels unique.

grayImage = double(grayImage) + noiseImage;

% Sort the image from lowest GL to brightest GL.

[sortedGLs, sortOrder] = sort(grayImage(:));

% Create triangle shape

numPixels = rows * columns;

triangle = [linspace(0, 1, 128), linspace(1, 0, 128)];

triangle = round(numPixels * triangle / sum(triangle));

% Sum should now equal the number of pixels.

sum(triangle)

subplot(2, 3, [3, 6]);

plot(triangle, 'b-', 'LineWidth', 2)

grid on;

title('Number of pixels per bin', 'FontSize', fontSize);

gl = 1;

k = 1;

outputImage = grayImage; % Initialize.

while k < numel(sortedGLs)

fprintf('Processing gray level %d\n', gl);

% find out how many pixels we need to put into this gray level.

numInBin = triangle(gl);

% TO DO finish code.

end

% Cast to uint8

outputImage = uint8(outputImage);

subplot(2, 3, 4);

imshow(outputImage, []);

impixelinfo

title('Output Image', 'FontSize', fontSize);

subplot(2, 3, 5);

imhist(outputImage)

grid on;

title('Histogram of Output Image', 'FontSize', fontSize);

Image Analyst
on 2 Jan 2022 at 22:38

OK, since your homework is over, I'll post a full demo. I also expanded it so that you can choose either a triangle output histogram or one in the shape of a parabola, sine wave, or perfectly flat (like histogram equalized). (NOTE: Students should consider whether it's ethical to turn in my code as their own work if they have an assignment to do this, lest they get into trouble.)

% Demo to transform a gray scale image so that its histogram is of a prescribed shape, such as triangle, parabola, flat, since wave.

% Initialization steps.

clc; % Clear the command window.

close all; % Close all figures (except those of imtool.)

clear; % Erase all existing variables. Or clearvars if you want.

workspace; % Make sure the workspace panel is showing.

format long g;

format compact;

fontSize = 15;

fprintf('Beginning to run %s.m ...\n', mfilename);

%----------------------------------------------------------------------------

% Read in original image and display its histogram.

grayImage = imread('cameraman.tif');

[rows, columns, numberOfColorChannels] = size(grayImage);

if numberOfColorChannels == 3

grayImage = rgb2gray(grayImage);

end

numPixels = rows * columns;

subplot(2, 3, 1);

imshow(grayImage);

title('Input Image', 'FontSize', fontSize);

subplot(2, 3, 2);

imhist(grayImage);

grid on;

title('Histogram of Input Image', 'FontSize', fontSize);

%----------------------------------------------------------------------------

% Create noise image.

noiseImage = rand(rows, columns) - 0.5;

% Add noise to gray scale image to make all gray levels unique.

grayImage = double(grayImage) + noiseImage;

% Sort the image from lowest GL to brightest GL.

[sortedGLs, sortOrder] = sort(grayImage(:));

%-------------------------------------------------------------------------------------------------------------

% Create desired shape of output histogram, for example a triangle shape or parabola or flat.

% First example: create a triangle.

triangle = [linspace(0, 1, 128), linspace(1, 0, 128)];

% Second example shape: a parabola.

g = 0:255;

parabola = -((g - 128).^2/150) + 100;

% Third example: perfectly flat, like for histogram equalization.

flat = ones(1, 256);

% Fourth example: sine wave

sineWave = 1 + sin(2 * pi * g / 256);

%-------------------------------------------------------------------------------------------------------------

% We need to pick only one example shape to use, either triangle, parabola, flat, or sine wave.

histShape = triangle;

% histShape = parabola;

% histShape = flat;

% histShape = sineWave;

% Make sure the function has no negative values.

histShape = max(histShape, 0);

% Make sure it sums to the number of pixels in the entire image.

histShape = round(numPixels * histShape / sum(histShape));

% Sum should now equal the number of pixels.

shapeSum = sum(histShape) % Not really needed - it's just to double check that it sums to the number of pixels.

%-------------------------------------------------------------------------------------------------------------

subplot(2, 3, [3, 6]);

plot(histShape, 'b-', 'LineWidth', 2)

grid on;

title('Number of pixels per bin', 'FontSize', fontSize);

% Process the vector that we'll use for the output

gl = 1;

k = 1; % k can be thought of as "the next pixel index".

outputImage = sortedGLs(:); % Initialize.

while k < numel(sortedGLs)

fprintf('Processing gray level %d.', gl);

% find out how many pixels we need to put into this gray level.

numInBin = histShape(gl);

fprintf(' Making %d pixels have gray level %d.\n', numInBin, gl);

% Make sure index doesn't go past end of vector..

lastIndex = min(k + numInBin - 1, numel(outputImage));

% Assign all those elements to the current gray level.

outputImage(k : lastIndex) = gl;

% Increment the gray level, and the pixel index that we'll be changing next.

gl = gl + 1;

k = k + numInBin; % Increment the next pixel index.

end

% Unscramble the image. Put pixels back where they came from.

outputImage2(sortOrder) = outputImage; % Unsort/unscramble.

% Convert from 1-D vector into 2-D image.

outputImage = reshape(outputImage2, [rows, columns]);

% Cast to uint8

outputImage = uint8(outputImage);

% Display processed image and display its histogram.

subplot(2, 3, 4);

imshow(outputImage, []);

impixelinfo

title('Output Image', 'FontSize', fontSize);

subplot(2, 3, 5);

imhist(outputImage)

grid on;

title('Histogram of Output Image', 'FontSize', fontSize);

% Maximize window

hFig = gcf;

hFig.WindowState = 'maximized';

Here is what it looks like if you tell it to use the other shapes. Sine wave shape below:

Flat shape below, like histogram equalized -- perfect equalization, not like the usual functions that do it.

Parabola shape below:

##### 0 Comments

### See Also

### Products

### Community Treasure Hunt

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

Start Hunting!