2

I know you can just use numpy.histogram(), and that will create the histogram for a respective image. What I don't understand is, how to create histograms without using that function.

Everytime I try to use sample code, it has issues with packages especially OpenCV.

Is there anyway to create histograms without using OpenCV or skimage, maybe using something like imageio?

HansHirse
  • 18,010
  • 10
  • 38
  • 67
math-engr
  • 23
  • 2
  • 3
    Welcome! I recommend [taking the tour](https://stackoverflow.com/tour) first.You might want to rephrase your question a bit. It's unclear what you mean by "create it without using it". (do you mean without using the image, but a different data source ?) It's impossible for others to guess what issues you run into using opencv. You should post a minimal example of your attempt with clear notes on how you expect the code to work and how it's actually behaving (what is the actual issue). Have you tried using existing guide on Python OpenCV / numpy histograms ? Here are few examples... – George Profenza Feb 12 '21 at 02:32
  • [Oldschool OpenCV Histograms Tutorial](https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html#histogram-calculation), [OpenCV Python Tutorial on Histograms](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_histograms/py_histogram_begins/py_histogram_begins.html#histograms-getting-started), [PyImageSearch histograms post](https://www.pyimagesearch.com/2014/01/22/clever-girl-a-guide-to-utilizing-color-histograms-for-computer-vision-and-image-search-engines/) – George Profenza Feb 12 '21 at 02:35

1 Answers1

1

You'd need to implement the histogram calculation using lists, dictionaries or any other standard Python data structure, if you explicitly don't want to have NumPy as some kind of import. For image histograms, you basically need to count intensity occurences, most of the time these are values in the range of 0 ... 255 (when dealing with 8-bit images). So, iterate all channels of an image, iterate all pixels within that channel, and increment the corresponding "counter" for the observed intensity value of that pixel.

For example, that'd be a solution:

import imageio

# Read image via imageio; get dimensions (width, height)
img = imageio.imread('path/to/your/image.png')
h, w = img.shape[:2]

# Dictionary (or any other data structure) to store histograms
hist = {
    'R': [0 for i in range(256)],
    'G': [0 for j in range(256)],
    'B': [0 for k in range(256)]
}

# Iterate every pixel and increment corresponding histogram element
for i, c in enumerate(['R', 'G', 'B']):
    for x in range(w):
        for y in range(h):
            hist[c][img[y, x, i]] += 1

I added some NumPy code to test for equality:

import numpy as np

# Calculate histograms using NumPy
hist_np = {
    'R': list(np.histogram(img[:, :, 0], bins=range(257))[0]),
    'G': list(np.histogram(img[:, :, 1], bins=range(257))[0]),
    'B': list(np.histogram(img[:, :, 2], bins=range(257))[0])
}

# Comparisons
print(hist['R'] == hist_np['R'])
print(hist['G'] == hist_np['G'])
print(hist['B'] == hist_np['B'])

And, the corresponding output in fact is:

True
True
True
----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
imageio:       2.9.0
NumPy:         1.20.1
----------------------------------------
HansHirse
  • 18,010
  • 10
  • 38
  • 67