Python OpenCV learning notes: how to draw a histogram, pythonopencv
This article mainly introduces how to draw a histogram using python OpenCV learning notes. I think it is quite good. I will share it with you and give you a reference. Let's take a look at it with xiaobian.
Documents-https://docs.opencv.org/3.4.0/d1/db7/tutorial_py_histogram_begins.html
The histogram gives you a comprehensive understanding of the intensity distribution of the image. It is a graph with a pixel value (from 0 to 255, but not always) on the X axis, corresponding to the number of pixels in the image on the Y axis.
This is just another way to understand the image. By observing the histogram of the image, you can intuitively see the contrast, brightness, intensity distribution, and so on of the image. Almost all image processing tools now provide the histogram feature. The following is an image of the Cambridge color website. We recommend that you visit this website to learn more.
You can see the image and its histogram. (This histogram is drawn from a gray image, not a color image ). The left part of the histogram shows the number of darker pixels in the image, and the right part shows brighter pixels. From the histogram, we can see that the number of pixels in the dark area is more than that in the bright area, while the number of intermediate colors (about 127 in the middle) is much less.
Histogram
Now we know what a histogram is. We can see how to find it. OpenCV and Numpy both have built-in functions. Before using these functions, we need to understand some terms related to histograms.
BINS: the histogram above shows the number of pixels for each pixel value, from 0 to 255. You need 256 values to display the preceding histogram. However, if you do not need to find the number of pixels for all the pixel values, but the number of pixels in a pixel value range, what should you do? For example, you need to find the number of shards between 0 and 15, then 16 to 31 ...... 240 to 255. You only need 16 values to represent this histogram. OpenCV Tutorials on histograms shows this example.
So what you need to do is to divide the entire histogram into 16 sub-parts. The value of each sub-part is the sum of all the bins. Each sub-part is called "BIN ". In the first case, the number of BINS is 256 (one pixel per pixel), and in the second case, it has only 16 BINS. In the OpenCV document, the term histSize is used to represent BINS.
DIMS: the number of parameters for data collection. In this case, we only collect one thing, the intensity value. So here is 1.
RANGE: the RANGE of the intensity value you want to measure. Generally, it is [0,256], that is, all the intensity values.
Histogram calculation in OpenCV
Now we usecv.calcHist()
Function to find the histogram. Let's get familiar with this function and its parameters:
cv.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
Images: it is a uint8 type or float32 source image. It should be enclosed in square brackets, that is, "[img]".
Channels: it is also enclosed in square brackets. It is the channel index of the histogram. For example, if the input is a grayscale image, its value is 0. For color images, you can use 0, 1, or 2 to calculate the histograms of the blue, green, or red channels respectively.
Mask: mask graph. To locate the full image histogram, it is specified as "None ". But if you want to find the histogram of a specific area of the image, you must create a mask image for it and use it as a mask.
HistSize: This indicates the number of BINS. It must be represented by square brackets. In the entire range, we passed the 256.
Ranges: intensity value range, usually [0,256]
Let's start with a sample image. You only need to load the image in grayscale mode and find its complete histogram.
img = cv.imread('home.jpg', 0)hist = cv.calcHist([img], [0], None, [256], [0,256])
Hist is a x 1 array. Each value corresponds to the pixel value in the image and its corresponding pixel value.
Calculate the histogram in Numpy
Numpy providesnp.histogram()
Method
hist, bins = np.histogram(img.ravel(), 356, [0,256])
Hist is the same as previously calculated. However, bins have 257 elements, because Numpy calculates bins as 0-0.99, 1-1.99, and so on, so the last one is 255-255.99. To indicate this, they also added 256 to the end of bins. But we don't need 256. To 255 is enough.
Numpy has another function,np.bincount()
, Rationp.histograme()
It is much faster (about 10 X ). You can try a one-dimensional histogram. Do not forget to set minlength = 256 in np. bincount. For example,hist=np.bincount(img.ravel(),minlength=256)
OpenCV function Rationp.histogram()
Fast (about 40X ). Therefore, we insist on using OpenCV functions.
Draw a Histogram
1. Use Matplotlib
Matplotlib has a function to draw a histogram:matplotlib.pyplot.hist()
It finds the histogram and draws it. You do not need to usecalcHist()
Ornp.histogram()
Function to find the histogram. See the following code:
import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg = cv.imread('home.jpg', 0)plt.hist(img.ravel(), 256, [0,256])plt.show()
Or you can use the normal matplotlib, which is very helpful for the BGR plot. Therefore, you must first find the histogram data. Try the following code:
import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg = cv.imread('home.jpg')color = ('b', 'g', 'r')for i, col in enumerate(color): histr = cv.calcHist([img], [i], None, [256], [0,256]) plt.plot(histr, color=col) plt.xlim([0,256])plt.show()
You can deduct it from the figure above. Blue has some high-value areas in the image (obviously, it should be caused by the sky)
2. Use OpenCV
Here, you can adjust the histogram value and its bin value to make it look like the x and y coordinates, so that you can use cv. line () or cv. the polyline () function is used to plot the image and generate the same image as above. This is already an official sample of OpenCV-Python2. Check the sampl/python/hist. py code.
Application mask
We usecv.calcHist()
Function to find a complete histogram of the image. But what if we only need a part of the histogram of the image? Create a white mask image in the area you want to find. Use it as a mask.
img = cv.imread('home.jpg', 0)# create a maskmask = np.zeros(img.shape[:2], np.uint8)mask[100:300, 100:400] = 255masked_img = cv.bitwise_and(img, img, mask=mask)#Calculate histogram with mask and without maskCheck third argument for maskhist_full = cv.calcHist([img], [0], None, [256], [0,256])hist_mask = cv.calcHist([img], [0], mask, [256], [0,256])plt.subplot(221), plt.imshow(img, 'gray')plt.subplot(222), plt.imshow(mask,'gray')plt.subplot(223), plt.imshow(masked_img, 'gray')plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)plt.xlim([0,256])plt.show()
Blue Line indicates the histogram of the complete image
Green line indicates the histogram after the mask
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.