OpenCV —— 直方图与匹配
直方图就是对数据进行统计,将统计值组织到一系列事先定义好的bin中。bin中的数值是从数据中计算出来的特征的统计量,这些数据可以是诸如梯度,方向,色彩或任何其他特征。
直方图获得是是数据分布的统计图
直方图的基本数据结构 CvHistogram
创建一个新的直方图 cvCreateHist
dims 直方图维数的数目
sizes 直方图维数尺寸的数组
type 直方图的表示格式: CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges 图中方块范围的数组. 它的内容取决于参数 uniform 的值。这个范围的用处是确定何时计算直方图或决定反向映射(backprojected ),每个方块对应于输入图像的哪个/哪组值。
uniform 归一化标识。 如果不为0,则ranges[i](0<=i<cDims,译者注:cDims为直方图的维数,对于灰度图为1,彩色图为3)是包含两个元素的范围数组,包括直方图第i维的上界和下界。在第i维上的整个区域 [lower,upper]被分割成 dims[i] 个相等的块(译者注:dims[i]表示直方图第i维的块数),这些块用来确定输入象素的第 i 个值(译者注:对于彩色图像,i确定R, G,或者B)的对应的块;如果为0,则ranges[i]是包含dims[i]+1个元素的范围数组,包括lower0, upper0, lower1, upper1 == lower2, ..., upperdims[i]-1, 其中lowerj 和upperj分别是直方图第i维上第 j 个方块的上下界(针对输入象素的第 i 个值)。任何情况下,输入值如果超出了一个直方块所指定的范围外,都不会被 cvCalcHist 计数,而且会被函数 cvCalcBackProject 置零。
cvSetHistBinRanges —— 在使用直方图之前给rangs设置数值
cvSetHistRanges()
cvClearHist 对直方图进行清零 cvReleaseHist 释放直方图
cvMakeHistHeaderForArray 根据已给出的数据创建直方图 (直方图的内部数据类型描述永远是浮点数)
访问直方图
cvQueryHistValue_1D cvQueryHistValue_2D cvQueryHistValue_3D 每个函数都返回相应bin中的值的浮点数,同样,可以利用函数返回的bin的指针来设置直方图bin的值
cvGetHistValue_1D cvGetHistValue_2D
在稀疏直方图中,如果想利用函数 GetHist*() 来访问不存在的bin,这个不存在的bin会被自动创建,并且其值被设置为0
直方图的基本操作
cvNormalizeHist 归一化直方图
cvThreshHist 直方图阈值函数,小于给定阈值的各个bin都被社为0
cvCopyHist 将一个直方图的信息复制到另一个直方图
cvGetMinMaxHistValue 输出直方图中找到的最小值和最大值 (如果不需要其中的一个,可以设置为NULL)
cvCalcHist 自动从图像中计算直方图 (对于多通道图像,先要用函数cvSplit将图像分为单通道的)
对比两个直方图
cvCompareHist
相关 CV_COMP_CORREL 线性相关 —— 两个向量协方差除以两个变量的标准差
卡方 CV_COMP_CHISQR 低分比高分的匹配程度高,完全匹配的值为0
直方图相交 CV_COMP_INTERSECT 高分表示好匹配
Bhattacharyya 距离 CV_COMP_BHATTACHARYYA 低分表示好匹配
在对比直方图之前,都应该自行进行归一化操作,因为如果不规一化,没有任何意义
// 直方图的计算与显示 #include <cv.h>
#include <highgui.h> int main(int argc,char** argv)
{
IplImage* src=cvLoadImage("wukong.jpg",CV_LOAD_IMAGE_COLOR);
IplImage* hsv=cvCreateImage(cvGetSize(src),,);
cvCvtColor(src,hsv,CV_RGB2HSV); IplImage* h_plane=cvCreateImage(cvGetSize(src),,);
IplImage* s_plane=cvCreateImage(cvGetSize(src),,);
IplImage* v_plane=cvCreateImage(cvGetSize(src),,);
IplImage* planes[]={h_plane,s_plane};
cvCvtPixToPlane(hsv,h_plane,s_plane,v_plane,); int h_bins=,s_bins=;
CvHistogram* hist; {
int hist_size[]={h_bins,s_bins};
float h_ranges[]={,};
float s_ranges[]={,};
float* ranges[]={h_ranges,s_ranges};
hist=cvCreateHist(,hist_size,CV_HIST_ARRAY,ranges,);
} cvCalcHist(planes,hist,,);
cvNormalizeHist(hist,1.0); int scale=;
IplImage* hist_img=cvCreateImage(cvSize(h_bins*scale,s_bins*scale),,);
cvZero(hist_img); float max_value=;
cvGetMinMaxHistValue(hist,,&max_value,,); for (int h=;h<h_bins;h++)
{
for (int s=;s<s_bins;s++)
{
float bin_val=cvQueryHistValue_2D(hist,h,s);
int intensity=cvRound(bin_val*/max_value); cvRectangle(hist_img,cvPoint(h*scale,s*scale),cvPoint((h+)*scale-,(s+)*scale-),CV_RGB(intensity,intensity,intensity),CV_FILLED);
}
} cvNamedWindow("w1",CV_WINDOW_AUTOSIZE);
cvShowImage("w1",hist_img); cvWaitKey(); cvReleaseImage(&hsv);
cvReleaseImage(&h_plane);
cvReleaseImage(&s_plane);
cvReleaseImage(&v_plane);
cvReleaseHist(&hist);
cvReleaseImage(&hist_img);
cvDestroyAllWindows(); return ; }
陆地移动距离
光线引起图像颜色值的漂移(没有改变颜色直方图的形状,但引起了颜色位置的变化,导致匹配策略失效)
陆地移动距离 —— 实际上度量的是怎样将一个直方图的形状转变为另一个直方图的形状,包括移动直方图的部分到一个新的位置,可以在任何维的直方图上进行这种度量
EMD 算法本身是一个通用的算法 —— 允许用户自己设置距离度量或者自己的移动代价矩阵 cvCalcEMD2
#include <cv.h>#include <highgui.h>#include <IOSTREAM.H>int main(int argc, char** argv){IplImage *src = cvLoadImage("wukong.jpg",CV_LOAD_IMAGE_COLOR);IplImage *hsv = cvCreateImage(cvGetSize(src),8,3);cvCvtColor(src,hsv,CV_BGR2HSV);IplImage *h_plane = cvCreateImage(cvGetSize(src),8,1);IplImage *s_plane = cvCreateImage(cvGetSize(src),8,1);IplImage *v_plane = cvCreateImage(cvGetSize(src),8,1);IplImage *planes[]={h_plane,s_plane};cvSplit(hsv,h_plane,s_plane,v_plane,0);//求得直方图int h_bins=30,s_bins=32;CvHistogram *hist1,*hist2;int size[]={h_bins,s_bins};float h_ranges[]={0,180};float s_ranges[]={0,255};float *ranges[]={h_ranges,s_ranges};hist1=cvCreateHist(2,size,CV_HIST_ARRAY,ranges,1);cvCalcHist(planes,hist1,0,0);//只能一个通道一个通道的写入直方图,所以上面分成H、S、VcvNormalizeHist(hist1,1.0);//归一化直方图,使所有块的值加起来为1hist2=cvCreateHist(2,size,CV_HIST_ARRAY,ranges,1);cvCalcHist(planes,hist2,0,0);cvNormalizeHist(hist2,1.0);//求得signature用于比较直方图CvMat *sig1,*sig2;int numrows=h_bins*s_bins;sig1=cvCreateMat(numrows,3,CV_32FC1);//由于是2维图像直方图,所以只需保存每个点的(值,横坐标,纵坐标)三个数,一共numrows个点sig2=cvCreateMat(numrows,3,CV_32FC1);for(int h=0;h<h_bins;h++){for(int s=0;s<s_bins;s++){float bin_val=cvQueryHistValue_2D(hist1,h,s);cvSet2D(sig1,h*s_bins+s,0,cvScalar(bin_val));cvSet2D(sig1,h*s_bins+s,1,cvScalar(h));cvSet2D(sig1,h*s_bins+s,2,cvScalar(s));bin_val=cvQueryHistValue_2D(hist2,h,s);cvSet2D(sig2,h*s_bins+s,0,cvScalar(bin_val));cvSet2D(sig2,h*s_bins+s,1,cvScalar(h));cvSet2D(sig2,h*s_bins+s,2,cvScalar(s));}}float emd=cvCalcEMD2(sig1,sig2,CV_DIST_L2);cout<<emd<<endl;return 0;}
反向投影
一种记录像素点或像素块如何适应直方图模型中分布的方式 —— 有一个颜色直方图,可以利用反向投影在图象中找到该区域
cvCalcBackProject —— 在输入图像平面上的滑动块来设置目标图像上相应的像素(块的中心);对于归一化直方图模型来说,结果图像可以被解释为一个概率图(存储的数值代表了该像素属于皮肤区域的概率)
可以通过 cvMinMaxLoc () 来寻找目标
模板匹配
cvMatchTemplate —— 在另一幅图像上移动模板图像块来寻找匹配
CV_TM_SQDIFF 平方差匹配法
CV_TM_CCORR 相关匹配法
CV_TM_CCOEFF 相关匹配法
归一化方法
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h> int main(int argc,char** argv)
{
IplImage *src,*templ,*ftmp[]; // ftmp 用来保存结果
int i; src=cvLoadImage("wukong.jgp",CV_LOAD_IMAGE_COLOR);
templ=cvLoadImage("templ.jpg",CV_LOAD_IMAGE_COLOR); int iwidth=src->width-templ->width+;
int iheight=src->height-templ->height+;
for (i=;i<;i++)
{
ftmp[i]=cvCreateImage(cvSize(iwidth,iheight),,);
} for (i=;i<;i++)
{
cvMatchTemplate(src,templ,ftmp[i],i);
cvNormalize(ftmp[i],ftmp[i],,,CV_MINMAX);
} cvNamedWindow("template",);
cvShowImage("template",templ); cvNamedWindow("image",);
cvShowImage("image",src); cvNamedWindow("sqdiff");
cvShowImage("sqdiff",ftmp[]); // 各种显示太烦了,不写了 cvDestroyAllWindows();
}
OpenCV —— 直方图与匹配的更多相关文章
- OPENCV直方图与匹配
直方图可以用来描述不同的参数和事物,如物体的色彩分布,物体的边缘梯度模版以及目标位置的当前假设的概率分布. 直方图就是对数据进行统计的一种方法,并且将统计值定义到一系列定义好的bin(组距)中,获得一 ...
- 基于OpenCV的双目视觉匹配测距系统
刚读研究生的时候,自己导师研究的方向是双目视觉,于是让自己研究OpenCV,折腾了几个月,算法上没啥突破,不过工程上还是折腾出了一个能用的小玩意,基于OpenCV实现了相机的标定.双目视觉图片的矫正. ...
- opencv 7 直方图与匹配
图像直方图概述 直方图的计算与绘制 计算直方图:calcHist()函数 找寻最值:minMaxLoc()函数 示例程序:绘制H-S直方图 #include "opencv2/highgui ...
- OpenCV直方图(直方图、直方图均衡,直方图匹配,原理、实现)
1 直方图 灰度级范围为 \([0,L-1]\) 的数字图像的直方图是离散函数 \(h(r_k) = n_k\) , 其中 \(r_k\) 是第\(k\)级灰度值,\(n_k\) 是图像中灰度为 \( ...
- OpenCV——直方图计算、寻早最值位置和对比匹配(判断两幅图的相似程度)
- openCV 直方图统计
直方图显示 #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main(int argc ...
- OpenCV——直方图均衡化(用于图像增强)
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...
- opencv:直方图操作
示例程序: #include <opencv.hpp> using namespace cv; using namespace std; int main() { Mat src, dst ...
- opencv直方图该怎么画
图像直方图是反映图像中像素分布特性的统计表,一般显示如下: 其中横坐标代表的是图像像素的种类,或者说是灰度级,纵坐标代表的是每一级灰度下像素数或者该灰度级下像素数在所有图像总像素数总所占的百分比. 直 ...
随机推荐
- PostgreSQL Replication之第四章 设置异步复制(1)
执行完您的第一个即时恢复(PITR,Point-In-Time-Recovery),我们准备在一个真正的复制设置上工作.在本章,您将学会如何设置异步复制和流.我们的目标是确保您可以实现更高的高可用和更 ...
- c# 静态成员和实例成员的区别
静态成员也称为共享成员,例如静态属性 静态字段 静态方法:静态成员可以在类的实例之间共享. 静态类中只能有静态成员,不能有实例成员,因为静态类不能进行实例化: 在非静态类中 即可以有静态成员 也可以有 ...
- SSD-tensorflow-2 制作自己的数据集
VOC2007数据集格式: VOC2007详细介绍在这里,提供给大家有兴趣作了解.而制作自己的数据集只需用到前三个文件夹,所以请事先建好这三个文件夹放入同一文件夹内,同时ImageSets文件夹内包含 ...
- nginx设置可以默认访问index.php
vim /usr/local/nginx/conf/nginx.conf: 在 location /{ index index.php index.html i ...
- 陌上开花(CDQ分治)
题解 三维偏序裸题... 一般三维偏序是第一维排序,第二维CDQ分治,第三维树状数组. 模板题还是看代码吧... #include<iostream> #include<cstrin ...
- [洛谷P2394]yyy loves Chemistry I
题目大意:给你一个实数x($0<x\leq 1$),要你求x/23的值(保留8位小数). 解题思路:此题用double读的精度是不够的,用long double直接读入也会WA,正确做法是“sc ...
- celery 学习
1. 列出计划的ETA任务(worker) celery -A proj inspect scheduled 参考文档:http://docs.celeryproject.org/en/latest/ ...
- python 进阶:修饰器的介绍
参考链接:Python 函数装饰器 我认为python中的装饰器是一个很厉害的功能,他能瞬间提升代码的逼格,但对于我这样的小白来说,别说为所欲为的使用了,就连简单的尝试一下,却也是难于登天.经过长达半 ...
- C++模板中重要的术语
- Canvas与Paint的0基础使用
看了非常多android自己定义方面的资料,了解了非常多原理,遇到人家自己定义的东西也可以看得懂,可是.当自己去自己定义的时候.发现脑袋一片空白,所以就先从认识Canvas和Paint開始吧! Can ...