反向投影

  • 反向投影是反映直方图模型在目标图像中的分布情况(此直方图模型是由目标图像计算生成的)
  • 简单点说就是用直方图模型去目标图像中寻找是否有相似的对象。通常用HSV色彩空间的HS两个通道直方图模型

反向投影 – 步骤

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

实现步骤与相关API

  1. 加载图片imread
  2. 将图像从RGB色彩空间转换到HSV色彩空间cvtColor
  3. 计算直方图和归一化calcHist与normalize
  4. Mat与MatND其中Mat表示二维数组,MatND表示三维或者多维数据,此处均可以用Mat表示。
  5. 计算反向投影图像 - calcBackProject

  • mixChannels()参数说明:
    mixChannels(//用于将输入数组的指定通道复制到输出数组的指定通道
    const Mat* src, //输入数组或向量矩阵,所有矩阵的大小和深度必须相同。
    size_t nsrcs, //矩阵的数量
    Mat* dst, //输出数组或矩阵向量,大小和深度必须与src[0]相同
    size_t ndsts,//矩阵的数量
    const int* fromTo,//指定被复制通道与要复制到的位置组成的索引对
    size_t npairs //fromTo中索引对的数目
    );

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

/*
参数1:const Mat类型的images,输入的数组(或数组集),它们需为相同的深度(CV_8U或CV_32F)和相同的尺寸,而通道数可以任意。
参数2:int类型的nimages,输入数组的个数,也就是第一个参数中存放了多少张图像,有几个源数组
参数3:const int
类型的channels,需要统计的通道索引。第一个数组通道从0到image[0].channels-1,第二个数组通道从images[0].channes()计算到images[0].channels()+images[1].channels()-1
参数4:InputArray类型的hist,输入的直方图
参数5:OutputArray类型的backProject,目标反向投影阵列,其须为单通道,并且和image[0]有相同的大小和深度
参数6:const float**类型的ranges,表示每一个维度数组(第六个参数dims)的每一维边界阵列,可以理解为每一维数值的取值范围。
参数7:double scale,有默认值1,输出的方向投影可选的缩放因子,默认值为1
参数8:boo类型的uniform,指示直方图是否均匀的标识符,有默认值true
*/

程序代码:

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;// 申明图像矩阵,初始化bin数目:
Mat src, hsv, hue;
int bins = 25;void Hist_and_Backproj(int, void* );int main( int argc, char** argv )
{// 1. 读取输入图像并转换到HSV 空间src=imread("E:/Experiment/OpenCV/Pictures/dog2.jpg");cvtColor( src, hsv, CV_BGR2HSV );// 2. 使用Hue通道来创建1维直方图:// 分离 Hue 通道。 色调在HSV颜色空间定义取值为0°到360°,实际在OpenCV中取值为0-180hue.create( hsv.size(), hsv.depth() );// 这里要传深度,传type会报错int nchannels[] = { 0, 0 };/*  // 将输入数组的指定通道复制到输出数组的指定通道mixChannels( const Mat* src, //输入数组或向量矩阵,所有矩阵的大小和深度必须相同。size_t nsrcs, //矩阵的数量Mat* dst, //输出数组或矩阵向量,大小和深度必须与src相同size_t ndsts,//矩阵的数量const int* fromTo,//指定被复制通道与要复制到的位置组成的索引对size_t npairs //fromTo中索引对的数目);*/mixChannels( &hsv, 1, &hue, 1, nchannels, 1 );imshow("hue", hue);// 3. 创建 Trackbar 来输入bin的数目char* window_image = "Source image";namedWindow( window_image, CV_WINDOW_AUTOSIZE );createTrackbar("* Hue  bins: ", window_image, &bins, 180, Hist_and_Backproj );Hist_and_Backproj(0, 0);// 现实图像imshow( window_image, src );// 等待用户反应waitKey(0);return 0;
}void Hist_and_Backproj(int, void* )
{MatND hist;int histSize = MAX( bins, 2 );float hue_range[] = { 0, 180 };const float* ranges = { hue_range };// 计算直方图并归一化到范围[0,255]calcHist( &hue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false );normalize( hist, hist, 0, 255, NORM_MINMAX, -1, Mat() );// 调用函数 calcBackProject 计算同一张图像的反向投影:MatND backproj;/*calcBackProject ( // 反向投影const Mat * images, // 输入图像,图像深度必须位CV_8U,CV_16U或CV_32F中的一种,尺寸相同,每一幅图像都可以有任意的通道数 int nimages, // 输入图像的数量const int * channels, // 用于计算反向投影的通道列表,通道数必须与直方图维度相匹配,第一个数组的通道是从0到image[0].channels()-1,第二个数组通道从图像image[0].channels()到image[0].channels()+image[1].channels()-1计数InputArray hist, // 输入的直方图,直方图的bin可以是密集(dense)或稀疏(sparse)OutputArray backProject, // 目标反向投影输出图像,是一个单通道图像,与原图像有相同的尺寸和深度const float ** ranges, // 直方图中每个维度bin的取值范围double scale = 1, // 可选输出反向投影的比例因子bool uniform = true // 直方图是否均匀分布(uniform)的标识符,默认值true)*/calcBackProject( &hue, 1, 0, hist, backproj, &ranges, 1, true );// 显示反向投影imshow( "BackProj", backproj );// 绘制直方图int w = 400; int h = 400;int bin_w = cvRound( (double) w / histSize );Mat histImg = Mat::zeros( w, h, CV_8UC3 );for( int i = 0; i < bins; i ++ ){ rectangle( histImg, Point( i*bin_w, h ), Point( (i+1)*bin_w, h - cvRound( hist.at<float>(i)*h/255.0 ) ), Scalar( 0, 0, 255 ), -1 ); //-1表示填充矩形}imshow( "Histogram", histImg );
}

运行截图

参考博客

  1. (强烈推荐阅读)http://wiki.opencv.org.cn/index.php/Cv图像处理
  2. https://blog.csdn.net/LYKymy/article/details/83210431
  3. https://blog.csdn.net/huanghuangjin/article/details/81178582
  4. https://blog.csdn.net/simonforfuture/article/details/78863667

其他

– 参考自:http://blog.sina.com.cn/s/blog_6b7d710b0102v5m1.html
1.反向投影的作用是什么?
反向投影用于在输入图像(通常较大)中查找特定图像(通常较小或者仅1个像素,以下将其称为模板图像)最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。

2.反向投影如何查找(工作)?
查找的方式就是不断的在输入图像中切割跟模板图像大小一致的图像块,并用直方图对比的方式与模板图像进行比较。

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
(1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
(2)生成临时图像的直方图;
(3)用临时图像的直方图和模板图像的直方图对比,对比结果记为c;
(4)直方图对比结果c,就是结果图像(0,0)处的像素值;
(5)切割输入图像从(0,1)至(10,11)的临时图像,对比直方图,并记录到结果图像;
(6)重复(1)~(5)步直到输入图像的右下角。

3.反向投影的结果是什么?
反向投影的结果包含了:以每个输入图像像素点为起点的直方图对比结果。可以把它看成是一个二维的浮点型数组,二维矩阵,或者单通道的浮点型图像。

4.特殊情况怎么样?
如果输入图像和模板图像一样大,那么反向投影相当于直方图对比。如果输入图像比模板图像还小,直接罢工~~。

5.使用时有什么要注意的地方?
需要注意的地方比较多,我们对照反向投影函数来说:
void cvCalcBackProjectPatch(
IplImage** image,
CvArr* dst,
CvSize patch_size,
CvHistogram* hist,
int method,
float factor
);

还有最需要注意的地方:这个函数的执行效率非常的低,在使用之前尤其需要注意图像的大小,直方图的维数,对比方式。如果说对比单个直方图对现在的电脑来说是清风拂面,那么反向投影是狂风海啸。对于1010x1010的RGB输入图像,10x10的模板图像,需要生成1百万次3维直方图,对比1百万次3维直方图。

OpenCV-图像处理(26、直方图反向投影(Back Projection))相关推荐

  1. opencv python 直方图反向投影_python OpenCV学习笔记直方图反向投影的实现

    本文介绍了python OpenCV学习笔记直方图反向投影的实现,分享给大家,具体如下: 它用于图像分割或寻找图像中感兴趣的对象.简单地说,它创建一个与我们的输入图像相同大小(但单通道)的图像,其中每 ...

  2. OpenCV中直方图反向投影算法详解与实现

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达本文转自:opencv学堂 一:直方图交叉 OpenCV中直方图反向 ...

  3. opencv进阶学习笔记7:直方图,直方图均衡化,直方图比较,直方图反向投影

    基础版传送门: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 直方图基础讲解: opencv学 ...

  4. opencv 直方图_OpenCV之图像直方图反向投影

    python代码: import cv2 as cv import numpy as np from matplotlib import pyplot as pltdef back_projectio ...

  5. opencv 直方图反向投影

    转载至:http://www.cnblogs.com/zsb517/archive/2012/06/20/2556508.html 直方图反向投影式通过给定的直方图信息,在图像找到相应的像素分布区域, ...

  6. Mean Shift算法(2)在OpenCV上的实现目标跟踪——直方图反向投影

    直方图反向投影 直方图反向投影的结果是一个概率分布图,表示一个指定图像片段出现在特定位置的概率.假设我们已经知道图像中某个物体的大致位置,就可以用概率分布图找到物体的准确位置.最可能出现的位置就是窗口 ...

  7. Python+OpenCV:直方图反向投影(Histogram Backprojection)

    Python+OpenCV:直方图反向投影(Histogram Backprojection) Algorithm in Numpy 1. First we need to calculate the ...

  8. OpenCV + CPP 系列(十九)直方图比较 与 直方图反向投影,投影分割

    文章目录 一.直方图比较 计算公式 效果演示 二.直方图反向投影 三.投影分割 一.直方图比较 对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间,然后可以通过计算H1与H2的之间的距离 ...

  9. [python opencv 计算机视觉零基础到实战] 十五 直方图反向投影

    一.学习目标 了解了直方图反向投影的一般流程 了解2D直方图的使用 如有错误欢迎指出~ 二.了解直方图反向投影 2.1 了解2D直方图 需要对直方图进行反向投影,需要使用2D直方图.2D直方图需要使用 ...

  10. python-opencv 图像处理基础 (五)颜色直方图+直方图均衡化+直方图比较+直方图反向投影

    1.颜色直方图 #-------------------------------绘制颜色直方图------ import cv2 import numpy as np import matplotli ...

最新文章

  1. python配置文件密码管理_python – 可以在django管理员中实现“下次登录时更改密码”类型功能吗?...
  2. 友情链接优化的技巧分享
  3. Flutter+百度人工智能实现测验值app
  4. 【一】Windows API 零门槛编程指南——MessageBox 基本使用及基础讲解
  5. 深度解析Cocoa异步请求和libxml2.dylib教程(1)
  6. mysql 创建视图 主键_MySQL数据库基础操作命令,本文助你更上一层楼!
  7. 带有示例的Python File readline()方法
  8. 认识死锁之生产者与消费者
  9. WF4 常用类第二篇
  10. 自写小函数处理 javascript 0.3*0.2 浮点类型相乘问题
  11. UVA474 Heads / Tails Probability【数学】
  12. 【高等数学】上册知识点复习
  13. 多项式算法的常数问题
  14. java ocr文字识别_java文字识别技术
  15. 怎么样域名绑定服务器显示成功,域名备案成功后怎么绑定服务器
  16. qq文件未上传至平台服务器,QQ传送离线文件慢是什么原因?原因及处理方法
  17. 网络空间同样需要“天朗气清”
  18. 怎么查看计算机簇大小,分区格式与簇的大小讲解
  19. UE4 单面模型法线翻转及碰撞问题
  20. MT7621_移植篇(3) uboot编译+配置项分析

热门文章

  1. 异常排查_Python-日志模块.NoSectionError: No section: '*' 错误?
  2. 获得数据库连接池中数据连接资源的两种方式
  3. 分金币 (UVA 11300)
  4. Hadoop连载系列之六:Hadoop数据仓库工具Hive
  5. 转两好文防丢:Debian 版本升级/降级 Linux 应用程序失去输入焦点问题的解决...
  6. yum [Errno -1] Metadata file does not match checksum
  7. 2010年篮球规则(FIBA)
  8. html语言添加点击事件,vue 中拼接html时添加点击事件
  9. Java使用Cipher类实现加密,包括DES,DES3,AES和RSA加密
  10. python网络爬虫实践_第18,Python网络爬虫实践(1)