9.4 反向投影(back projection)

9.4.1 反向投影原理

1.基本思想:
  反向投影中储存的数值代表了图像中该像素属于区域的概率,计算某一特征的直方图模型,使用模型寻找图像中存在的该特征
2.基本原理:
(1)对图像中每个像素(p(i,j)),获取色调数据并找到该色调/饱和度在直方图中的bin的位置
(2)查询模型直方图中对应的bin的数值
(3)将此数值存储在新的反射投影图像中。也可以先归一化直方图数值到0-255范围内,这样可以直接显示反射投影图像
(4)使用统计学语言进行分析,反向投影中储存的数值代表了图像中该像素属于区域的概率
3.作用:
  在输入图像中查找与特定图像最匹配的点或区域,即定位模板图像出现在输入图像的位置
4.结果:
  包含了以每个输入图像像素点为起点的直方图对比结果的二维浮点型数组/二维矩阵/单通道浮点型图像

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

1.作用:
  计算直方图反向投影
2.函数原型:

void calcBackProject(const Mat* image, int nimages, const int* channels, InputArray hist, OutputArray backProject, const float** ranges, double scale=1, bool uniform=true)

3.参数说明:
(1)输入数组(集)
(2)输入数组个数
(3)需要统计的通道(dim)索引,第一个数组通道从0到images[0].channels()-1,第二个数组通道从images[0].channels()计算到images[0].channels()+images[1].channels()-1。
(4)输入直方图
(5)目标反向投影阵列,单通道且与image[0]大小深度相同
(6)表示每一个维度数组的每一维的边界阵列,即每一维数值的取值范围
(7)输出方向投影可选的缩放因子,默认1
(8)指示直方图是否均匀的标识符,默认true

9.4.3 通道复制:mixChannels()函数

1.作用:
  由输入参数复制到某通道到输出参数特定的通道中,实现图像通道重排
2.函数原型:

(1)void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs)
(2)void mixChannels(const vector<Mat>& src, vector<Mat>& dst, const int* fromTo, size_t npairs)

3.参数说明(1):
(1)输入数组
(2)src输入的矩阵数
(3)输出的数组,所有矩阵必须被初始化,且大小和深度必须与src[0]相同
(4)dst输入的矩阵数
(5)对指定的通道进行复制的数组索引
(6)参数fromTo的索引数
4.参数说明(2):
(1)输入的矩阵向量
(2)输出的矩阵向量,所有矩阵必须被初始化,且大小和深度必须与src[0]相同
(3)对指定的通道进行复制的数组索引
(4)参数fromTo的索引数
5.示例:
  将一个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[0]->bgr[0],rgba[3]->alpha[0]
int from_to[] = { 0,2,1,1,2,0,3,3 };
mixChannels{ &rgba,1,out,2,from_to,4 };

9.4.4 综合示例

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
//定义辅助宏
#define WINDOW_NAME1 "【原始图】"
#define WINDOW_NAME2 "【反向投影图】"
//全局变量
Mat g_srcImage, g_hsvImage, g_hueImage;
int g_bins = 30;//直方图组距
//全局函数
void on_BinChange(int, void*);
int main()
{//【1】载入原图,转换到HSV空间g_srcImage = imread("1.jpg", 1);if (!g_srcImage.data){printf("载入原图失败~!\n");return false;}cvtColor(g_srcImage, g_hsvImage, COLOR_BGR2HSV);//【2】分离Hue色调通道g_hueImage.create(g_hsvImage.size(), g_hsvImage.depth());int ch[] = { 0,0 };mixChannels(&g_hsvImage, 1, &g_hueImage, 1, ch, 1);//【3】创建Trackbar来输入bin的数目namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);createTrackbar("色调组距", WINDOW_NAME1, &g_bins, 180, on_BinChange);on_BinChange(0, 0);//【4】显示原图imshow(WINDOW_NAME1, g_srcImage);waitKey(0);return 0;
}
void on_BinChange(int, void*)
{//【1】参数准备MatND hist;int histSize = MAX(g_bins, 2);float hue_range[] = { 0,180 };const float* ranges = { hue_range };//【2】计算直方图并归一化calcHist(&g_hueImage, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());//【3】计算反向投影MatND backproj;calcBackProject(&g_hueImage, 1, 0, hist, backproj, &ranges, 1, true);//【4】显示反向投影imshow(WINDOW_NAME2, backproj);//【5】绘制直方图的参数准备int w = 400, h = 400;int bin_w = cvRound((double)w / histSize);Mat histImg = Mat::zeros(w, h, CV_8UC3);//【6】绘制直方图for (int i = 0; i < g_bins; i++){rectangle(histImg, Point(i*bin_w, h), Point((i + 1)*bin_w, h - cvRound(hist.at<float>(i)*h / 255.0)), Scalar(100, 123, 255), -1);}//【7】显示直方图窗口imshow("直方图", histImg);
}

运行效果:


《OpenCV3编程入门》学习笔记9 直方图与匹配(四)反向投影(back projection)相关推荐

  1. 原创 OpenCV3编程入门 学习笔记(总)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36163358/article/ ...

  2. OpenCV3编程入门 学习笔记(总)

    OpenCV3编程入门 学习笔记 2018.12.12-2018.12.29 此博客为在看过毛星云版<OpenCV3编程入门>后所总结的一本笔记,可供复习使用. 文章目录 OpenCV3编 ...

  3. Opencv3编程入门学习笔记(五)之通道分离(split)与合并(merge)

    若要对Opencv中(BGR)颜色通道进行单一处理,那必然会涉及到通道分离(split)与合并(merge).那么本篇博客笔者记录了两个方法的使用方法和案例.案例来源于<Opencv3编程入门学 ...

  4. Opencv3编程入门学习笔记(三)之访问图像像素的三种方法

    访问图像像素的三种方法:指针访问,迭代器访问,动态地址访问.访问最快的为指针访问,以下算法在几毫秒,但指针访问容易造成内存泄漏:其次为迭代器访问:最后为动态地址访问. 以下程序是根据<OpenC ...

  5. 【OpenCV3编程入门学习笔记】——第1章 邂逅OpenCV

    邂逅OpenCV 文章目录 邂逅OpenCV 前言 1.1 OpenCV周边概念认知 1.1.1 图像处理.计算机视觉与OpenCV 1.1.2 OpenCV概述 1.1.3 起源及发展 1.1.4 ...

  6. Opencv3编程入门学习笔记(四)之split通道分离Debug过程中0xC0000005内存访问冲突问题

    这是笔者学习<Opencv3编程入门>的第四篇博客,这篇博客主要是解决在Windows系统下VS 2013中Debug含有split分离通道色彩函数时报出的0xC0000005内存访问冲突 ...

  7. 【OpenCV3编程入门学习笔记】——第3章 HighGUI图形用户界面初步

    文章目录 前言 3.1 图形的载入.显示和输出到文件 3.1.1 OpenCV的命名空间 3.1.2 Mat类简析 3.1.3 图像的载入与显示概述 3.1.4 图像的载入:imread()函数 3. ...

  8. Opencv3编程入门学习笔记(二)之显式创建Mat对象

    以下总结是基于<Opencv3编程入门>一书4.1节总结的内容进行验证与总结,验证环境均为Windows10 ---VS2013 C++环境,验证Opencv3.0提供的开发包. 1. 方 ...

  9. 01.Java 编程入门学习笔记20210307

    Java 编程入门学习笔记-day01 第0章:编程入门 1.计算机的概述 计算机 = 硬件 + 软件 1.1硬件:冯诺依曼体系 CPU: CPU的衡量标准:速度的计量单位是赫兹(Hz),1Hz相当于 ...

  10. Python快速编程入门#学习笔记01# |第一章 :Python基础知识 (Python发展历程、常见的开发工具、import模块导入)

    全文目录 ==先导知识== 1 认识Python 1.1.1 Python的发展历程 1.1.2 Python语言的特点 2. Python解释器的安装与Python程序运行 1.2.1 安装Pyth ...

最新文章

  1. Linux shell 学习笔记(9)— 循环语句(for、while)以及更改字段分隔符
  2. 敏捷开发中Scrum方法
  3. Ubuntu16.04安装NVIDIA显卡(RTX20系列)驱动+CUDA10.0+cudnn+Pytorch1.1.0
  4. k8s学习(一)——kubectl与api-server之间的交互核心过程
  5. linux跳转乌班图服务器,Linux-Ubuntu环境安装Nginx和配置二级域名跳转
  6. UIAlterController-ios8弹出菜单
  7. STM32+SIM800C采用MQTT协议登录OneNet上传温湿度、MQ2烟雾浓度、GPS数据
  8. ContentNegotiation内容协商机制(一)---Spring MVC内置支持的4种内容协商方式【享学Spring MVC】
  9. SVN强制编写注释才能提交,提交中不允许删除文件操作。
  10. 机械结构day_13
  11. Google谷歌未来如何占领“Web3高地”?
  12. 车型识别API调用与批量分类车辆图片
  13. 华清远见Qt作业网络聊天室1014
  14. SpringBoot2.6.x集成swagger: Failed to start bean ‘documentationPluginsBootstrapper问题解决
  15. 图说Fourier变换
  16. Android反向进度条(ProgressBar)的实现——从右到左的进度条
  17. 于Mozilla平台的扩展开发
  18. 2019国际计算机音乐联会韩国,温州大学音乐学院与韩国全南大学2019年联合培养博士招生及培养商谈会...
  19. 1份专业的数据分析报告到底怎么写?
  20. Java中枚举类型Enum的一种使用方式

热门文章

  1. 2022-2028年中国文化产业园投资分析及前景预测报告(全卷)
  2. 数据结构(03)— 数据处理基本操作(数据的查找、新增、删除、修改)
  3. 快速给shell脚本加上使用提示
  4. 【J2SE】语言基础
  5. virtualenv创建虚拟环境为主_多版本
  6. java锁(公平锁和非公平锁、可重入锁(又名递归锁)、自旋锁、独占锁(写)/共享锁(读)/互斥锁、读写锁)
  7. GPU加速:宽深度推理
  8. 标题 相机标定(Camera calibration)原理和步骤
  9. Android自定义ViewGroup基本步骤
  10. AttributeError: ‘dict‘ object has no attribute ‘append‘