7. Advanced operations of opencv-python image processing (4) - Histogram

learning target

Master the histogram calculation and display of images

Learn about mask applications

Be familiar with histogram equalization and understand adaptive equalization

1. Grayscale histogram

1. Principle

  Histograms are a method of statistics on data, and organize statistical values ​​into a series of implementation-defined bins. Bin is a concept often used in histograms, which can be translated as "straight bar" or "group distance". Its value is a characteristic statistic calculated from the data. These data can be such as gradient, direction, color or other any characteristics.
  Image Histogram is a histogram used to represent the brightness distribution in a digital image, plotting the number of pixels for each brightness value in the image. In this histogram, the left side of the abscissa is the darker area. Therefore, a dark image will have more data in the histogram concentrated on the left and middle parts, while the opposite will be true for an overall bright image with only a few shadows.
Insert image description here
NOTE : The histogram is plotted against a grayscale image, not a color image. Suppose there is information about an image (grayscale value 0-255). The range of known numbers contains 256 values, so this range can be divided into sub-regions (that is, bins) according to certain rules. For example:
Insert image description here
Then count the number of pixels in each bin(i). You can get the following picture (where the x-axis represents the bin and the y-axis represents the number of pixels in each bin):
Insert image description here
Here you need to pay attention to some professional terms in the histogram description:

dims:需要统计的特征数目,在上述例子中,dims=1,因为仅表示了灰度值
bins:每个特征空间子区段的数目,可译为“直条”或“组距”,在上例中,bins=16
range:要统计特征的取值范围。在上例中,range = [0,255]

The meaning of histogram:
Histogram is a graphical expression of the intensity distribution of pixels in an image.
It counts the number of pixels for each intensity value.
Histograms of different images may be the same.

2. Drawing of grayscale histogram

We generally use the method in opencv to count histograms and use matplotlib to draw them.
API:

cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])

parameter:

images: 原图像。当传入函数时应该用中括号 [] 括起来,例如:[img]。
channels: 如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。   
mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)   
histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。   
ranges: 像素值范围,通常为 [0,256]

Code example:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1 直接以灰度图的方式读入
img = cv.imread('./image/cat.jpeg',0)
# 2 统计灰度图
histr = cv.calcHist([img],[0],None,[256],[0,256])
# 3 绘制灰度图
plt.figure(figsize=(10,6),dpi=100)
plt.plot(histr)
plt.grid()
plt.show()

Insert image description here

3. The role of mask

Mask is to use a selected image, graphic or object to block the image to be processed to control the image processing area.

In digital image processing, we usually use two-dimensional matrix arrays for masking. The mask is a binary image composed of 0 and 1. The mask image is used to mask the image to be processed. The 1-value area is processed, and the 0-value area is masked and will not be processed.
The main uses of masks are:

1. Extract the area of ​​interest: Use the pre-made area of ​​interest mask to perform an "AND" operation with the image to be processed to obtain the area of ​​interest image. The image values ​​​​in the area of ​​interest remain unchanged, while the image values ​​outside the area are all 0. .
2. Shielding effect: Use a mask to shield certain areas on the image so that they do not participate in processing or calculation of processing parameters, or only the shielded area is processed or counted.
3. Structural feature extraction: Use similarity variables or image matching methods to detect and extract structural features in the image that are similar to the mask.
4. Special shape image production

Masks are often used in remote sensing image processing. When extracting roads, rivers, or houses, a mask matrix is ​​used to filter the pixels of the image, and then highlight the features or landmarks we need.
We use cv.calcHist() to find the histogram of the complete image. If you want to find the histogram of some area of ​​the image, just create a mask image of white over the area where you want to find the histogram, otherwise create black, and pass it as a mask.

Code example:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1. 直接以灰度图的方式读入
img = cv.imread('./image/cat.jpeg',0)
# 2. 创建蒙版
mask = np.zeros(img.shape[:2], np.uint8)
mask[400:650, 200:500] = 255
# 3.掩模
masked_img = cv.bitwise_and(img,img,mask = mask)
# 4. 统计掩膜后图像的灰度图
mask_histr = cv.calcHist([img],[0],mask,[256],[1,256])
# 5. 图像展示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8))
axes[0,0].imshow(img,cmap=plt.cm.gray)
axes[0,0].set_title("原图")
axes[0,1].imshow(mask,cmap=plt.cm.gray)
axes[0,1].set_title("蒙版数据")
axes[1,0].imshow(masked_img,cmap=plt.cm.gray)
axes[1,0].set_title("掩膜后数据")
axes[1,1].plot(mask_histr)
axes[1,1].grid()
axes[1,1].set_title("灰度直方图")
plt.show()

Insert image description here

2. Histogram equalization

1. Principle and application

Imagine what would happen if the pixel values ​​of most pixels in an image were concentrated within a small gray value range? If an image is very bright as a whole, then the number of values ​​in all pixel values ​​should be very high. Therefore, its histogram should be stretched horizontally (as shown below) to expand the distribution range of image pixel values ​​and improve the contrast of the image. This is what histogram equalization does.
Insert image description here

"Histogram equalization" is to change the grayscale histogram of the original image from a relatively concentrated grayscale interval to a distribution in a wider grayscale range. Histogram equalization is to nonlinearly stretch the image and redistribute the image pixel values ​​so that the number of pixels within a certain grayscale range is approximately the same.
This method improves the overall contrast of the image, especially when the pixel value distribution of the useful data is relatively close. It is widely used in X-ray images to improve the display of the skeleton structure. In addition, it can be better highlighted in over- or under-exposed images. detail. When using opencv for histogram statistics, the following API
is used :

dst = cv.equalizeHist(img)

Parameters:
img: grayscale image
Return:
dst: equalized result

Code example:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 1. 直接以灰度图的方式读入
img = cv.imread('./image/cat.jpeg',0)
# 2. 均衡化处理
dst = cv.equalizeHist(img)
# 3. 结果展示
fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(dst,cmap=plt.cm.gray)
axes[1].set_title("均衡化后结果")
plt.show()

Insert image description here

2. Adaptive histogram equalization

For the above histogram equalization, we consider the global contrast of the image. It is true that after performing histogram equalization, the contrast of the background of the picture is changed. The cat legs are too dark and we lose a lot of information, so in many cases, the effect of this is not good. As shown below, comparing the two images of the statue, we lost a lot of information because it was too bright.
Insert image description here
To solve this problem, adaptive histogram equalization needs to be used. At this time, the entire image will be divided into many small blocks, which are called "tiles" (the default size of tiles in OpenCV is 8x8), and then histogram equalization is performed on each small block. So in each area, the histogram will be concentrated in a small area). If there is noise, the noise will be amplified. To avoid this situation use contrast limiting. For each small block, if the bin in the histogram exceeds the upper limit of contrast, the pixels are evenly dispersed into other bins, and then the histogram is equalized.
Insert image description hereFinally, in order to remove the boundaries between each small block, bilinear differences are used to splice each small block.

API:
cv.createCLAHE(clipLimit, tileGridSize)
Parameters:
clipLimit: Contrast limit, default is 40
tileGridSize: Tile size, default is 8*88*8
Code example

import numpy as np
import cv2 as cv
# 1. 以灰度图形式读取图像
img = cv.imread('./image/cat.jpeg',0)
# 2. 创建一个自适应均衡化的对象,并应用于图像
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
# 3. 图像展示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img,cmap=plt.cm.gray)
axes[0].set_title("原图")
axes[1].imshow(cl1,cmap=plt.cm.gray)
axes[1].set_title("自适应均衡化后的结果")
plt.show()

Insert image description here

Summarize

1. Grayscale histogram

A histogram is a graphical representation of the intensity distribution of pixels in an image.

It counts the number of pixels for each intensity value.

Histograms of different images may be the same
cv.calcHist(images, channels, mask, histSize, ranges [, hist [, accumulate]])

2. Mask

3. Histogram equalization: a method to enhance image contrast

4. Adaptive histogram equalization

I haven't fully understood this part yet. Once I understand it, I will optimize it again.

Guess you like

Origin blog.csdn.net/weixin_44463519/article/details/126043626