Python code to create histogram from an image

Hi, can anyone explain how to write a code to count the frequencies of intensities of the pixels in an 8 gray scale image.

thank you

I pure Python or in ImageJ?

In Python I prefer to use matplotlib.pyplot.hist for this.

Here’s a quick sketch on how to do this

# Some imports
import matplotlib.pylab as plt  # for display
from skimage import data  # for loading example data
from skimage.color import rgb2gray  # for converting to grayscale

# Load image, convert to grayscale and show it
image = rgb2gray(data.astronaut())
plt.imshow(image)

# show histogram
plt.hist(image.ravel(), bins=32)
plt.show()

Or is loading the image a problem?

Good day!

Why not take the easy road and use the ImageJ recorder functionality:

Here is what I get with the Java-option:

import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;

public class My_Plugin implements PlugIn {
	public void run(String arg) {
		ImagePlus imp = IJ.createImage("Untitled", "8-bit noise", 256, 256, 1);
		IJ.run(imp, "Histogram", "");
		imp.show();
	}
}

Regards

Herbie

1 Like

I must have misunderstood @survive, I thought he wanted to do this in “pure” Python and not in ImageJ :slight_smile:

Hi,
thank you for replying
I have to do this in ImageJ but without using any pseudocode or histgram function from the tools bar

and its she btw :grinning:

Hi,
thanks for your reply
I have tried to convert this using python but i am not sure where I have made a mistake

from ij.gui import NewImage
from ij import IJ
from ij import ij.plugin
imp = IJ.getImage() #get the current image
processor = imp.getProcessor()  #technical bit - get a part of the image structure we can actually work with 
pix = processor.getPixels()

#get width and height of image
w = processor.getWidth()   
h = processor.getHeight()

#getting and putting pixels using x and y variables which we need to set
processor.getPixel (x,y)
processor.getPixel(x,y,255)

public class My_Plugin implements PlugIn {
	public void run(String arg) {
		ImagePlus imp = IJ.createImage("Untitled", "8-bit noise", 256, 256, 1);
		IJ.run(imp, "Histogram", "");
		imp.show();

this is a sample of the question

“write a python program which will create a histogram from the image. This MUST be done WITHOUT the use of the built-in histogram function. In other words, you must read pixel values and maintain a list of frequencies yourself. More specifically you must:
a. Write code to count the frequencies of intensities of the pixels in an 8-bit greyscale image. You should store frequencies of intensities for each intensity value, 0-255.
b. Print out a list of the frequencies for each intensity
c. For bonus marks, display this histogram in a new image, similar to the built-in function. You do not need to label axes, just display the plot. You might want to consider scaling the values.”

The code I’ve posted creates a sample image with random noise first:

ImagePlus imp = IJ.createImage(“Untitled”, “8-bit noise”, 256, 256, 1);

Evidently you don’t need this.

I think the only code line you need is

IJ.run(imp, “Histogram”, “”);

because the ImagePlus is already defined. BTW shouldn’t it read

ImagePlus imp = IJ.getImage() 

Th ehistogram is taken from the whole image or, if a selection exist, from the selected area.

I have zero experience with Python/Jython coding.

Regards

Herbie

Sorry, didn’t want to assume something!

Ah, but you did! :wink: (Not being judgy — pretty sure I’ve done the same a bunch of times! But I wanted to point out that “he” isn’t neutral. I prefer “they” if I can remember!)

1 Like

Use the getStatistics() method to get the histogram, as in this JavaScript example:

  img = IJ.createImage("noise", "8-bit noise", 500, 500, 1)
  stats = img.getStatistics()
  for (i in stats.histogram)
      print(i+" "+stats.histogram[i])

Based on the text of the assignment, I infer that none of the built-in pixel-counting routines may be used. @survive I have mixed feelings about posting a solution for you, though, because I get the impression this is a school assignment that you are supposed to solve to learn more about programming. Is that right?

Here is a block of code to get you started with coding it using the ImageJ1 API:

from ij import IJ
imp = IJ.getImage()
ip = imp.getProcessor()
for y in range(0, imp.getHeight()):
	for x in range(0, imp.getWidth()):
		v = ip.getf(x, y)
		print("({}, {}) = {}".format(x, y, v))
		# TODO: tally the value v into a histogram array.

The program still needs the addition of a histogram array and code to tally the values v into it. Note also that as written, it works for single image planes only.

Here is a block of code to do the same using the ImageJ2 API:

#@ Img img
for sample in img:
	v = sample.get().getRealDouble()
	print(v)
	# TODO: tally the value v into a histogram array.

Hope that helps get you started!

3 Likes

You can access all the pixels in an image using

ip = IJ.getProcessor()
for i in range(0, ip.getPixelCount()):
    v = ip.get(i)
    print(v)

You can easily add code to calculate the histogram.

The latest ImageJ daily build (1.52j38) adds the ImagePlus.plotHistogram() method that you can use to verify your code is working correctly.

img = IJ.openImage("http://wsr.imagej.net/images/boats.gif")
img.plotHistogram()

1 Like

Hi, I need help with a similar question, have you managed to do it?Thanks!

Could you please tell us how similar your question is?

The OP has received substantial help and it should be very easy to now solve the task that, as far as I understand, was meant as an exercise and as such should be solved by the OP alone.

Regards

Herbie

I am completely new to programming and have been set this assignment without any guidelines so I still don’t get what I have to do and how

and have been set this assignment without any guidelines

Who gave you this task and why?

Do you know what a histogram means and how it is mathematically computed?

Which programming language are you going to use and why?

Regards

Herbie

4 Likes