图像直方图反向投影Histogram Backprojection的代码注释为:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
def back_projection_demo():
sample = cv.imread("dataset/train/bees/1.png")
# hist2d_demo(sample)
target = cv.imread("dataset/train/bees/2.png")
# hist2d_demo(target)
roi_hsv = cv.cvtColor(sample, cv.COLOR_BGR2HSV)
target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV)
# show images
cv.imshow("sample", sample)
cv.imshow("target", target)
roiHist = cv.calcHist([roi_hsv], [0, 1], None, [32, 32], [0, 180, 0, 256])
cv.normalize(roiHist, roiHist, 0, 255, cv.NORM_MINMAX)
dst = cv.calcBackProject([target_hsv], [0, 1], roiHist, [0, 180, 0, 256], 1)
cv.imshow("backProjectionDemo", dst)
def hist2d_demo(image):
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
hist = cv.calcHist([hsv], [0, 1], None, [32, 32], [0, 180, 0, 256])
dst = cv.resize(hist, (400, 400))
cv.imshow("image", image)
cv.imshow("hist", dst)
plt.imshow(hist, interpolation='nearest')
plt.title("2D Histogram")
plt.show()
back_projection_demo()
cv.waitKey(0)
cv.destroyAllWindows()
运行结果:
反向投影:
反向投影是反映直方图模型在目标图像中的分布情况(此直方图模型是由目标图像计算生成的)。
简单点说就是用直方图模型去目标图像中寻找是否有相似的对象。通常用HSV色彩空间的HS两个通道直方图模型。
图像直方图反向投影是通过构建指定模板图像的二维直方图与目标的二维直方图空间,进行直方图数据归一化之后,进行比率操作,对所有得到非零数值,生成查找表对原图像进行像素映射之后,再进行图像模糊输出的结果。
直方图反向投影步骤:
- 计算直方图
- 计算比率R
- LUT查找表
- 卷积模糊
- 归一化输出
API:
void mixChannels(const Mat* src,
size_t nsrcs,
Mat* dst,
size_t ndsts,
const int* fromTo,
size_t npairs);
src:矩阵的输入数组或向量,所有矩阵必须具有相同的大小和相同的深度。
nsrcs: src中矩阵的数量。
dst: 输出矩阵或向量;必须分配所有矩阵; 其大小和深度必须与src[0]中的相同。
ndsts: dst中矩阵的数量。
fromTo:指定要复制哪些通道以及在何处复制;
fromTo[k * 2]是src中输入通道的从0开始的索引,
fromTo[k * 2 + 1]是dst中输出通道的索引。
使用连续通道编号:
第一个输入图像通道从0索引到src[0].channels()-1,
第二个输入图像通道从src[0].
channels()索引到src[0].channels()+ src[1] .channels()-1,
依此类推,相同的方案用于输出图像通道。
作为一种特殊情况,当fromTo [k * 2]为负时,相应的输出通道将填充为零。
npairs: “fromto”中的索引对数.