Python OpenCV histogram calculation and display method example, pythonopencv
This article introduces how to use OpenCV Python to calculate histograms, and briefly introduces how to use NumPy and Matplotlib to calculate and draw histograms.
The background knowledge and usage of the histogram are omitted. Here we will introduce the method directly.
Calculate and display the Histogram
Like in C ++, The OpenCV histogram calculation function called in Python is cv2.calcHist.
The prototype of cv2.calcHist is:
Cv2.calcHist (images, channels, mask, histSize, ranges [, hist [, accumulate]) # Return hist
The following example shows the parameters:
# Coding = UTF-8 import cv2 import numpy as np image = cv2.imread ("D:/histTest.jpg", 0) hist = cv2.calcHist ([image], [0], # The used channel is None, # mask [256] is not used, # HistSize [0.0, 255.0]) # histogram bar range
The first parameter must be enclosed in square brackets.
The second parameter is the channel used to calculate the histogram. Here, the grayscale graph is used to calculate the histogram, so the first channel is used directly;
The third parameter is Mask, which is not used here, so None is used.
The fourth parameter is histSize, which indicates the number of parts of the histogram (that is, the number of straight square columns ). In the second example, we will plot a histogram, which will be clearer at that time.
The fifth parameter indicates the value of each pixel in the histogram. [0.0, 256.0] indicates that the Histogram can represent the pixel value from 0.0 to 256.
Finally, there are two optional parameters. Because the histogram is returned as the function result, the sixth hist is meaningless (to be determined)
The last accumulate is a Boolean value used to indicate whether the histogram is superimposed.
Histogram of different channels of color images
Next let's take a look at the histogram processing of the color image. Taking the most famous lena.jpg as an example, first read and separate the channels:
import cv2 import numpy as np img = cv2.imread("D:/lena.jpg") b, g, r = cv2.split(img)
Calculate the histogram of each channel and encapsulate it as a function:
def calcAndDrawHist(image, color): hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0]) minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist) histImg = np.zeros([256,256,3], np.uint8) hpt = int(0.9* 256); for h in range(256): intensity = int(hist[h]*hpt/maxVal) cv2.line(histImg,(h,256), (h,256-intensity), color) return histImg;
This is just a simple encapsulation of the previous code, so annotations are saved.
Use the following in the main function:
if __name__ == '__main__': img = cv2.imread("D:/lena.jpg") b, g, r = cv2.split(img) histImgB = calcAndDrawHist(b, [255, 0, 0]) histImgG = calcAndDrawHist(g, [0, 255, 0]) histImgR = calcAndDrawHist(r, [0, 0, 255]) cv2.imshow("histImgB", histImgB) cv2.imshow("histImgG", histImgG) cv2.imshow("histImgR", histImgR) cv2.imshow("Img", img) cv2.waitKey(0) cv2.destroyAllWindows()
In this way, we can obtain the histograms of the three channels, as shown below:
Further steps
This is a bit cumbersome. Refer to abid rahman's practice and do not need to separate channels. Using a line to describe the border of a Histogram can draw a histogram of three channels at the same time in a graph. The method is as follows:
# Coding = UTF-8 import cv2 import numpy as np img = cv2.imread ('d:/lena.jpg ') h = np. zeros (256,256, 3) # create a full 0 image bins = np for plotting a histogram. arange (256 ). reshape (0,255) # color = [(255, 0), (, 0), (,)] # BGR three colors for ch, col in enumerate (color): originHist = cv2.calcHist ([img], [ch], None, [256], [0,256]) cv2.normalize (originHist, originHist, 0,255*0.9, cv2.NORM _ MINMAX) hist = np. int32 (np. around (originHist) pts = np. column_stack (bins, hist) cv2.polylines (h, [pts], False, col) h = np. flipud (h) cv2.imshow ('colorhist', h) cv2.waitKey (0)
The result is shown in:
Code Description:
Here, the for loop traverses three channels and draws the line of the histogram of the corresponding channel each time. The first line of the for Loop is to calculate the histogram of the corresponding channel. After the above introduction, it should be easy to understand.
The difference here is that we did not manually calculate the maximum value of the histogram and multiply it by a factor, but directly called the normalization function of OpenCV. This function limits the histogram range to 0-× 0. 9, which is the same as the previous one. The following hist = np. int32 (np. aroinhist (originHist) first rounds every element in the generated original histogram into an array of the float32 type (the cv2.calcHist function obtains an array of the float32 type ), then convert the integer to np. int32 type. That is, 61.123 is first converted to 61.0, and then to 61. Note: np must be used here. int32 (...) the numpy conversion function can convert every element in the array, while the Python int (...) only one element can be converted. If int (...) is used (...), this will cause only length-1 arrays can be converted to Python scalars errors.
The following pts = np. column_stack (bins, hist) converts the values of each bin in the histogram to the corresponding coordinates. For example, hist [0] = 3 ,..., hist [126] = 178 ,..., hist [255] = 5; the bins value is [[0], [1], [2]..., [255]. Use np. column_stack to combine them into an array composed of elements such as [0, 3], [126,178], and [255, 5.
Use the cv2.polylines function to draw a line based on these points. The third False parameter indicates that the line does not need to be closed. The fourth parameter specifies the line color.
When all is done, do not forget to use h = np. flipud (h) to reverse the drawn histogram, because [0, 0] is in the upper left corner of the image. This is described in the histogram visualization section.
NumPy histogram Calculation
When reading abid rahman's data, we found that he used NumPy's histogram to calculate the np. histogram function, which also achieved the same effect. As follows:
#coding=utf-8 import cv2 import numpy as np img = cv2.imread('D:/lena.jpg') h = np.zeros((300,256,3)) bins = np.arange(257) bin = bins[0:-1] color = [ (255,0,0),(0,255,0),(0,0,255) ] for ch,col in enumerate(color): item = img[:,:,ch] N,bins = np.histogram(item,bins) v=N.max() N = np.int32(np.around((N*255)/v)) N=N.reshape(256,1) pts = np.column_stack((bin,N)) cv2.polylines(h,[pts],False,col) h=np.flipud(h) cv2.imshow('img',h) cv2.waitKey(0)
It is the same as the one above. The histogram function of NumPy will be introduced in this blog post on NumPy general functions, which will not be explained in detail here. Here we use the same proportional coefficient as in the beginning. refer to section 2 of this article.
In addition, NumPy and matplotlib can be used to draw a histogram more conveniently. The following code is for your reference. If you have the opportunity, I will write a special article about matplotlib.
import matplotlib.pyplot as plt import numpy as np import cv2 img = cv2.imread('D:/lena.jpg') bins = np.arange(257) item = img[:,:,1] hist,bins = np.histogram(item,bins) width = 0.7*(bins[1]-bins[0]) center = (bins[:-1]+bins[1:])/2 plt.bar(center, hist, align = 'center', width = width) plt.show()
The histogram of the green channel is displayed here.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.