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直方图该怎么画
图像直方图是反映图像中像素分布特性的统计表,一般显示如下: 其中横坐标代表的是图像像素的种类,或者说是灰度级,纵坐标代表的是每一级灰度下像素数或者该灰度级下像素数在所有图像总像素数总所占的百分比. 直 ...
随机推荐
- c# 的类成员
1 字段和变量的区别 字段是在类中定义的数据成员 由访问修饰符+数据类型+字段名(public string name) 字段就像类的一个小数据库,用来存放和类相关的数据; 而变量是没有修饰符的(in ...
- 紫书 例题 10-10 UVa 10491(概率计算)
公式很好推,表示被高中生物遗传概率计算虐过的人 这个公式简直不需要动脑 #include<cstdio> using namespace std; int main() { double ...
- [APIO2010]巡逻(树的直径)
[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到 ...
- 修改MySQL默认字符集
今天发现有库级字符集和表级字符集,实验了下发现,库级字符集是该库内表的默认字符集,当创建表时,如果未指定字符集,默认使用该表所属库的字符集.表也可使用不同于所属库的字符集. MySQL对于字符集的指定 ...
- 洛谷—— P2934 [USACO09JAN]安全出行Safe Travel || COGS ——279|| BZOJ——1576
https://www.luogu.org/problem/show?pid=2934 题目描述 Gremlins have infested the farm. These nasty, ugly ...
- 基于Linux的智能家居的设计(2)
1 系统整体设计方案 智能家居系统的是一个实时查询家庭的温湿度.照明控制.自己主动控制的设定.集家庭娱乐.智能安防为一体,大量数据快处理.可靠的系统,因此在硬件和软件上都有非常大的要求,因此在这里进 ...
- 微软CEO纳德拉拥抱Linux意欲何为?
"我不喜欢打一场过时的战争."微软 CEO 萨蒂亚·纳德拉说道,"我想要打一场全新的战役." 上周日晚上.萨蒂亚·纳德拉来到旧金山 North Beach 区的 ...
- atitit.js 与c# java交互html5化的原理与总结.doc
atitit.js 与c# java交互html5化的原理与总结.doc 1. 实现html5化界面的要解决的策略 1 1.1. Js交互 1 1.2. 动态參数个数 1 1.3. 事件监听 2 2. ...
- Simditor用法
一不小心接触到Simditor,瞬间被它优美极简的界面所吸引.Simditor是Tower开源的所见即所得的在线富文本编辑器. Simditor的理念是保持简单,避免过度的功能,每个特性都追求极致的用 ...
- libsvm 的使用
1. libsvm 支持的SVM模型 官网地址:LIBSVM – A Library for Support Vector Machines libsvm 支持的 SVM 模型如下(C:classif ...