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直方图该怎么画
图像直方图是反映图像中像素分布特性的统计表,一般显示如下: 其中横坐标代表的是图像像素的种类,或者说是灰度级,纵坐标代表的是每一级灰度下像素数或者该灰度级下像素数在所有图像总像素数总所占的百分比. 直 ...
随机推荐
- ora_tool
#!/bin/ksh # # Copyright (c) 1998, 2002, Oracle Corporation. All rights reserved. # version() { ...
- 4、Go for循环
package main import "fmt" func main(){ //for 循环是go语言唯一的循环结构,分为三种类型 //第一种 类似while i:=1 for ...
- 有用的 Bash 快捷键清单
作者: Sk 译者: LCTT Sun Yongfei 现如今,我在终端上花的时间更多,尝试在命令行完成比在图形界面更多的工作.随着时间推移,我学了许多 BASH 的技巧.这是一份每个 Linux 用 ...
- docker切换默认镜像源
docker切换默认镜像源 基于 debian8 默认安装的 docker 镜像源是在国外,pull 镜像的时候奇慢无比,需要自己手动切换成国内的镜像源. 1. 修改配置文件 docker 默认的 ...
- 用Python讲述冯绍峰和赵丽颖的爱情故事
昨天刷头条时得知赵丽颖当妈妈了.作为一名程序员突发奇想,不如用Python简单叙述一下冯绍峰和赵丽颖的爱情故事,于是有了本文. 代码十分简单,适合编程小白和有一些Python基础的准程序员,其中用到了 ...
- Zookeeper入门:基本概念、5项配置、启动
起源 最早接触Zookeeper,是在学习Hadoop权威指南这本书的时候,印象中是Hadoop项目的一个子工程. 最近,项目中需要用到"分布式锁". 之前,在 ...
- Unity 编辑器学习(三)之 Light & Baked
上一篇博客已经详细的介绍GI了,接下来我们讲点实际的,怎么烘焙场景及注意事项. 一.Light Property: Function: Type 当前灯光的类型.有四种类型:Directional, ...
- 洛谷 P3199 [HNOI2009]最小圈
P3199 [HNOI2009]最小圈 题目背景 如果你能提供题面或者题意简述,请直接在讨论区发帖,感谢你的贡献. 题目描述 对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点 ...
- 两个对象值同样(x.equals(y) == true),但却可有不同的hash code,这句话对不正确?
1.网上面试题 这是一道Java面试题.看了非常多答案都说不正确.能够看下面代码.就知道结果了 http://www.iteye.com/topic/485046第45题 答案是错误的 package ...
- dropify,不错的图片上传预览插件
引言 传统的图片上传,很丑.点击选择之后,还无法预览. 有一种方案是传到服务器,然后返回地址,然后显示,比较麻烦. 用这个dropify,就可以解决之歌问题. 看效果 用法 1.引入文件,需要jque ...