首页 > 其他分享 >【OpenCV】- 直方图反向投影

【OpenCV】- 直方图反向投影

时间:2023-02-08 11:37:02浏览次数:39  
标签:Mat int 投影 hist OpenCV 直方图 反向

文章目录

  • ​​1 引言​​
  • ​​2 反向投影的工作原理​​
  • ​​3 反向投影的作用​​
  • ​​4 反向投影的结果​​
  • ​​5 计算反向投影:calcBackProject()函数​​
  • ​​6 通道复制:mixChannels()函数​​
  • ​​7 综合示例:反向投影​​

1 引言

反向投影就是一种记录给定图像中的像素点适应直方图模型像素分布方式的一种方法。也就是计算某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征的方法

2 反向投影的工作原理

  • 建立直方图模型
  • 计算待测图像直方图并映射到模型中
  • 从模型中反向计算生成图像

3 反向投影的作用

反向投影用于输入图像中查找与特定图像最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。

4 反向投影的结果

反向投影的结果包含了以输入图像像素点为起点的直方图对比结果。可以看作一个二维的浮点型数组、二维矩阵,或者单通道的浮点型图像。

5 计算反向投影:calcBackProject()函数

void calcBackProject(const Mat * images,int nimages,const int* channels,InputArray hist,OutputArray backProject,const float** ranges,double scale=1,bool uniform=true)
  • 第一个参数:输入的数组
  • 第二个参数:输入数组的个数,也就是有多少张图片,通常为1
  • 第三个参数:通道数目
  • 第四个参数:输入的直方图
  • 第五个参数:目标反向投影阵列,单通道,与image[0]有相同的大小和深度
  • 第六个参数:表示每一个维度数组的每一维的边界矩阵,每一个维度的取值范围
  • 第七个参数:默认值1,输出的方向投影可选的缩放因子
  • 第八个参数:直方图是否均匀的标识符,默认值True

6 通道复制:mixChannels()函数

说明:此函数由输入参数复制某通道到输出参数特定的通道中。该函数是为重排图像通道提供比较先进的机制。之前接触的split()和merge()以及cvtColor()都是mixChannels()函数一部分

void mixChannels(const Mat * src,size_t nsrcs,Mat * dst,size_t ndsts,const int * fromTo,size_t npairs)
  • 第一个参数:输入的数组(hsv),所有的矩阵必须有相同的尺寸和深度
  • 第二个参数:第一个参数src输入的矩阵数
  • 第三个参数:输出数组(hue),所有矩阵必须初始化,大小和深度必须与src[0]相同

hue.create(hsv.szie(),hsv.depth())

  • 第四个参数:第三个参数dst的输出矩阵数
  • 第五个参数:对指定的通道进行复制的数组索引
  • 第六个参数:第五个参数fromTo的索引数

示例说明:将一个4通道的RGBA图像转化为3通道BGR和一个单独的Alpha通道图像

Mat rgba(100,100,CV_8UC4,Scalar(1,2,3,4));
Mat bgr(rgba.rows,rgba.cols,CV_8UC3);
Mat alpha(rgba.rows,rgba.cols,CV_8UC1);
//组成矩阵数组来进行操作
Mat out[]={bgr,alpha};
//将rgba[0]->bgr[2]
//将rgba[1]->bgr[1]
//将rgba[2]->bgr[1]
//将rgba[3]->alpha[0]
int fromTo[]={0,2,1,1,2,0,3,3};
mixChannels(&rgba,1,out,2,fromTo,4);

7 综合示例:反向投影

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【反射投影图】"
Mat g_srcImage; Mat g_hsvImage; Mat g_hueImage;
int g_bins = 30;//直方图组距
void on_BinChange(int, void *);
int main()
{
g_srcImage = imread("E:\\Pec\\手.jpg", 1);
cvtColor(g_srcImage, g_hsvImage, COLOR_BGR2HSV);
//分离Hue色调通道
g_hueImage.create(g_hsvImage.size(), g_hsvImage.depth());
int ch[] = { 0,0 };
mixChannels(&g_hsvImage, 1, &g_hueImage, 1, ch, 1);
//创建Trackbar来输入bin数目
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
createTrackbar("色调组距:", WINDOW_NAME2, &g_bins, 180, on_BinChange);
on_BinChange(0, 0);
imshow(WINDOW_NAME1, g_srcImage);
waitKey(0);
return 0;
}
void on_BinChange(int, void *)
{
//参数准备
MatND hist;//Mat表示二维数组,MatND表示三维或者以上
int histSize = MAX(g_bins, 2);
float hue_range[] = { 0,180 };
const float * ranges = { hue_range };
//计算直方图并归一化
calcHist(&g_hueImage, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);
normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());
//计算反射投影
Mat backproj;
calcBackProject(&g_hueImage, 1, 0, hist, backproj, &ranges, 1, true);
imshow(WINDOW_NAME2, backproj);
//绘制直方图
int hist_w = 400, hist_h = 400;
//cvRound:对double类型的数四舍五入并返回一个整型
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage = Mat::zeros(hist_w, hist_h, CV_8UC3);
for (int i = 0; i < g_bins; i++)
{
//pt1 -- 矩形的一个顶点。pt2 -- 矩形对角线上的另一个顶点
rectangle(histImage, Point(i*bin_w, hist_h),
Point((i + 1)*bin_w, hist_h - cvRound(hist.at<float>(i)*hist_h / 255.0)),
Scalar(100, 123, 255),-1);
}
imshow("直方图", histImage);
}

(1)原图展示

【OpenCV】- 直方图反向投影_直方图

(2)组距bin为 6 的反向投影

【OpenCV】- 直方图反向投影_opencv_02

(3)组距bin为 30 的反向投影

【OpenCV】- 直方图反向投影_反向投影_03


标签:Mat,int,投影,hist,OpenCV,直方图,反向
From: https://blog.51cto.com/u_14935708/6043788

相关文章

  • pip安装opencv-python
    安装opencv-python时,需要安装与环境中python匹配的版本,要不然会报错ImportError:DLLloadfailedwhileimportingcv2:找不到指定的模块。安装命令#匹配python=3.8.......
  • 利用DlibDotNet和OpenCvSharp实现头像裁剪
    起因:由于OA入职后提供的人员照片需要经过裁剪后再上传至门禁等其他需要使用到人脸的系统,虽然有小软件可以解决需求,但是还是希望通过自动化的形式进行处理,参考网上的资料和......
  • VisualStudio2022+Opencv配置
    下载OpenCVOpenCV官网下载下来的是一个exe可执行文件,运行后是一个解压程序,解压路径设置为找得到的就可以了。添加系统路径VisualStudio安装选择使用C++的桌面开发就可......
  • OpenCV-Python快速入门(十二):轮廓拟合
    OpenCV-Python快速入门(十二):轮廓拟合​​前言​​​​前提条件​​​​实验环境​​​​轮廓拟合​​​​矩形包围框(cv2.boundingRect())​​​​最小包围矩形框(cv2.minAreaRe......
  • VS2022 MFC OpenCV环境搭建
    无法打开opencv2/opencv.hpp文件错误:在项目属性,配置属性,VC++目录:可执行目录: C:\opencv\build\x64\vc15\bin包含目录:C:\opencv\build\includeC:\opencv\build\i......
  • 接雨水/直方图的水量
    题目:给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为1。输入:[0,1,0,2,1,0,1,3,2,1,2,1]输出:6一个单位的水不会流......
  • Qt6+OpenCV4人脸识别应用程序面部标志图(共计68点)
    我们可以看到,由索引号所代表的点在面部具有固定的位置,因此我们可以通过点的以下索引(包含下限,不含上限)来访问这些面部特征:mouth(嘴巴)[48,68]。righteyebrow(右眉)[17,22]。......
  • Opencv中Mat数据的复制
    cv::Matimage=cv::imread("C:\\Users\\Acer\\Desktop\\pfm\\volume\\ref_000.pfm",cv::IMREAD_ANYDEPTH); cv::Matclone_img=image.clone(); cv::Matcopy_img; i......
  • 【学习OpenCV4】如何学习OpenCV
    曾经在某乎上看到有人提问:靠OpenCV吃饭的图像算法工程师在深度学习的冲击下还有活路吗?不知道提问这位有没有了解卷积神经网络这个东西,早在二三十年之前就有手写数字识别......
  • opencv中ptr的使用
    #include<QCoreApplication>#include<stdio.h>#include<opencv2/highgui/highgui.hpp>#include<opencv2/core/core.hpp>usingnamespacecv;voidcolorReduce(Mat&i......