opencv-020-图像直方图反向投影

知识点

文字解释
图像直方图反向投影是通过构建指定模板图像的二维直方图空间与目标的二维直方图空间,进行直方图数据归一化之后, 进行比率操作,对所有得到非零数值,生成查找表对原图像进行像素映射之后,再进行图像模糊输出的结果。

直方图反向投影流程

  • 计算直方图
  • 计算比率R
  • LUT查找表
  • 卷积模糊
  • 归一化输出

API

代码(c++,python)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

void backProjection_demo(Mat &mat, Mat &model);

/*
* 图像直方图反向投影
*/
int main() {
Mat src = imread("../images/target.png");
Mat model = imread("../images/sample.png");
if (src.empty() || model.empty()) {
cout << "could not load image.." << endl;
}
namedWindow("model", WINDOW_NORMAL);
imshow("input", src);
imshow("model", model);

backProjection_demo(src, model);

waitKey(0);
return 0;
}

void backProjection_demo(Mat &image, Mat &model) {
Mat image_hsv, model_hsv;
cvtColor(image, image_hsv, COLOR_BGR2HSV);
cvtColor(model, model_hsv, COLOR_BGR2HSV);

// 定义直方图参数与属性
int h_bins = 32, s_bins = 32;
int histSize[] = {h_bins, s_bins};
float h_ranges[] = {0, 180}, s_ranges[] = {0, 256};
const float* ranges[] = {h_ranges, s_ranges};
int channels[] = {0, 1};

Mat roiHist;
calcHist(&model_hsv, 1, channels, Mat(), roiHist, 2, histSize, ranges);
normalize(roiHist, roiHist, 0, 255, NORM_MINMAX, -1, Mat());
MatND backproj;
calcBackProject(&image_hsv, 1, channels, roiHist, backproj, ranges);
imshow("BackProj", backproj);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


def back_projection_demo():
sample = cv.imread("D:/javaopencv/sample.png")
# hist2d_demo(sample)
target = cv.imread("D:/javaopencv/target.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()

结果

代码地址

github