Opencv study notes - histogram and template matching


1. Histogram

A histogram is a statistical graphical representation of the numerical distribution of pixels, that is, the number of occurrences of each point, which allows us to understand the density estimation and probability distribution of the data.
insert image description here

cv2.calcHist(images,channels,mask,histSize,ranges)

images : The original image image format is uint8 or float32. When passing in a function, you need to use square brackets [] to enclose it, for example [img]
channels : also use square brackets to enclose it. It will tell the function the histogram of our unified image. If the input image is a grayscale image, its value is [0] If it is a color image, the incoming parameters can be [0][1][2] They correspond to BGR respectively.
mask : The mask image. To count the histogram of the entire image, set it to None. But if you want to count the histogram of a certain part of the image, you make a mask image and use it.
histSize : The number of BINs. Brackets should also be used, such as [256]
ranges : the pixel value range is usually [0-256]

1. Draw a histogram

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/cat2.jpg',0) #0表示灰度图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
plt.hist(img.ravel(),256);
plt.show()

Effect:
insert image description here

2. The use of mask

Use mask to shield certain areas on the image so that they do not participate in processing or calculation of processing parameters, or only process or count the masked areas.
Use masks:

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/cat2.jpg',0) #0表示灰度图
# 创建mast
mask = np.zeros(img.shape[:2], np.uint8)
print (mask.shape)
mask[100:200, 100:300] = 255#mask[起始点横坐标,起始点纵坐标]=255,255为白色,也就是需要保留的地方
masked_img = cv2.bitwise_and(img, img,mask=mask)#与操作
res=res = np.hstack((img,masked_img))#t图像拼接
cv_show(res,'res')

Among them, the parameter img of cv2.bitwise_and
: the first input image
img: the second input image
mask: mask image
Because cv2.bitwise_and requires two input images, so both of us are img
effects:insert image description here

3. Histogram averaging

Histogram equalization is a method of transforming the original image to obtain a new image whose grayscale histogram is evenly distributed. The basic idea of ​​the histogram equalization method is to widen the gray level with a large number of pixels in the image, and to shrink the gray level with a small number of pixels. So as to achieve the purpose of clear image.
insert image description here
insert image description here

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/cat2.jpg',0) #0表示灰度图
equ = cv2.equalizeHist(img)
res = np.hstack((img,equ))
cv_show(res,'res')

Effect:
insert image description here

4. Adaptive histogram equalization

Adaptive histogram equalization (a computer image processing technique used to enhance the contrast of an image. Unlike ordinary histogram equalization, the AHE algorithm changes the image contrast by calculating the local histogram of the image and then redistributing the brightness. Therefore, This algorithm is more suitable for improving the local contrast of the image and obtaining more image details.
Due to the problem of the light and dark distribution of the picture, the global histogram equalization of a picture may lead to the loss of details in the bright or dark parts. In order to optimize the equalization Effect, we can perform histogram equalization on different areas to obtain a more suitable effect.

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/cat2.jpg',0) #0表示灰度图
equ = cv2.equalizeHist(img)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
res_clahe = clahe.apply(img)
res = np.hstack((img,res_clahe,equ))
cv_show(res,'res')

cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) Among them, the threshold of clipLimit color contrast, the grid size of titleGridSize for pixel equalization, that is, how many grids are used to perform the histogram equalization operation.
Effect:
insert image description here
Figure 2 is the image after adaptive histogram equalization, and it can be found that more details are preserved than Figure 3.

2. Template matching

1. Match a single object

The principle of template matching and convolution is very similar. The template slides from the origin on the original image, and the degree of difference between the template and (the place where the image is covered by the template) is calculated. There are 6 methods for calculating the degree of difference in opencv, and then each time The result of the calculation is put into a matrix and output as the result. If the original figure is AxB size, and the template is axb size, then the output matrix is ​​(A-a+1)x(B-b+1). There are six methods for template matching, which are:
TM_SQDIFF : Calculate the square difference, the smaller the calculated value, the more relevant, the formula is: [
R(x,y)= \sum _{x',y'} (T( x',y')-I(x+x',y+y'))^2]

TM_CCORR : Calculate the correlation, the larger the calculated value, the more relevant, the formula is: [R(x,y)= \sum _{x',y'} (T(x',y') \cdot I( x+x',y+y'))]

TM_CCOEFF : Calculate the correlation coefficient, the larger the calculated value, the more relevant, the formula is: [
R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I '(x+x',y+y'))]
where
[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h ) \cdot \sum _{x'',y''} T(x'',y'') \ I'(x+x',y+y')=I(x+x',y+y ') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}]

TM_SQDIFF_NORMED : Calculate the normalized square difference, the closer the calculated value is to 0, the more relevant, the formula is: [R(x,y)= \frac{\sum_{x',y'} (T(x',y ')-I(x+x',y+y')) 2}{\sqrt{\sum_{x',y'}T(x',y') 2 \cdot \sum_{x',y' } I(x+x',y+y')^2}}]

TM_CCORR_NORMED : Calculate the normalized correlation. The closer the calculated value is to 1, the more relevant it is. The formula is: [R(x,y)= \frac{\sum_{x',y'} (T(x',y ') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y '} I(x+x',y+y')^2}}]

TM_CCOEFF_NORMED : Calculate the normalized correlation coefficient. The closer the calculated value is to 1, the more relevant it is. The formula is: [R(x,y)= \frac{ \sum_{x',y'} (T'(x', y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x ',y'} I'(x+x',y+y')^2} }]

code:

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()
img = cv2.imread('D:/renxiang.jpg') #0表示灰度图
img2=img[20:150,150:300]#截取人脸
img3 = img.copy()
h, w = img2.shape[:2]#人脸的长和高
res = cv2.matchTemplate(img, img2, cv2.TM_SQDIFF_NORMED)
# 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)#min_val最小值,max_val最大值,min_loc最小值坐标,max_loc最大值坐标
#起始点
top_left = min_loc
#终止点
bottom_right = (top_left[0] + w, top_left[1] + h)
#画框
cv2.rectangle(img3, top_left, bottom_right, (0,0,255), 2)
cv_show(img3,'img')

Effect:
insert image description here

2. Match multiple objects

Template matching matches multiple objects, which is equivalent to setting a threshold. If it is greater than this threshold, we consider it a match.
Code:

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('D:/eryu.jpg') #0表示灰度图
img2 = img[60:200,50:180]#截取图像
img3 = img.copy()
h, w = img2.shape[:2]#截取图像的长宽
#计算归一化相关系数,计算出来的值越接近1,越相关
res = cv2.matchTemplate(img, img2, cv2.TM_CCOEFF_NORMED)
#设置阈值为0.8
threshold = 0.8
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):  # *号表示可选参数
    bottom_right = (pt[0] + w, pt[1] + h)
    cv2.rectangle(img3, pt, bottom_right, (0, 0, 255), 1)
cv_show(img3,'img')

Effect:
insert image description here

Guess you like

Origin blog.csdn.net/Thousand_drive/article/details/124649604