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直方图该怎么画
图像直方图是反映图像中像素分布特性的统计表,一般显示如下: 其中横坐标代表的是图像像素的种类,或者说是灰度级,纵坐标代表的是每一级灰度下像素数或者该灰度级下像素数在所有图像总像素数总所占的百分比. 直 ...
随机推荐
- append生成新变量的时候,没有如预期(It's a feature,not a bug?)
这是我在写一个项目中,遇到的一个golang的feature,如代码所示,我在for循环里,每次用append生成一个新的数组,(当然我以前一直以为可以这样,直到我在stackoverflow上发现不 ...
- caffe(4) 激活层(Activation Layers)及参数
在激活层中,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的.从bottom得到一个blob数据输入,运算后,从top输入一个blob数据.在运算过程中,没有改变数据的大小,即输入 ...
- 洛谷1726 上白泽慧音 tarjan模板
题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...
- 容器配置https
生成秘钥库 通过jdk的keytool工具生成秘钥库 keytool -genkeypair -alias "localhost" -keyalg "RSA" ...
- UnrealEngine4编码风格的思考
第一次拿到UE4源码,扫了一遍.各种宏定义,各种模板,各种类层次.杂乱无章. 后来慢慢明确其规律: UE4的编码风格是在匈牙利命名法的基础下做了改进,使其更适用游戏引擎业务(业务特点:数据可视编辑.脚 ...
- [Poi] Use Markdown as React Components by Adding a Webpack Loader to Poi
Poi ships with many webpack loaders included, but you may run into scenarios where you'll need to cu ...
- HNU13303 Counting substhreengs(递推)
题目:http://acm.hnu.cn/online/? action=problem&type=show&id=13303&courseid=0 题意:给你一个字符串,由数 ...
- 将IP表存入SQL里的程序
将IP表存入SQL里的程序 写得比較粗糙,另一点错误,只是能达到效果.请大家測试 create.asp ---------------------------------------------- ...
- Visual Code的调试
Run 'Debug: Download .NET Core Debugger' in the Command Palette or open a .NET project directory to ...
- 逆波兰表达式解数学运算(c#)
逆波兰表达式解数学运算 感谢作者 http://blog.csdn.net/liuyuxusuixiang/article/details/25289715 public class TCalcula ...