在包里
  • 灰度直方图
  • 彩色直方图

葵花宝典
直方图的理论还是非常丰富的,应用也非常多,诸如:
直方图均衡化
直方图匹配(meanshift,camshift)

在这里,我先介绍基础。怎样绘制图像的直方图。

拿灰度图像来说。直方图就是不同的灰度相应的个数,横轴(x)就是[0,256), 纵轴(y)就是相应的个数
例如以下图,各自是灰度直方图和彩色直方图

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjZDE5OTI3MTln/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="600" height="461" alt="">




初识API
C++: void calcHist(const
Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges,
bool uniform=true, bool accumulate=false )
 
  • images – 是一个图像数组。简单起见。我们都仅仅传一个图像.
  • nimages – 图片数组大小。我们固定为1
  • channels – 是一个数组,灰度图像为0就能够,彩色图像要0,1,2
  • mask – 这里我们不须要。传Mat()就能够
  • hist – 输出的直方图
  • dims – 计算彩色RGB要3,gray传1
  • histSize – 是一个数组。一般来说内容就是256
  • ranges – 是一个二维数组,每一个数组包含的都是一个范围,[0,255]最经常使用,以下会看到
  • uniform – 在这里用默认就足够.
  • accumulate – 在这里用默认就足够.

如果我们要计算灰度图像的直方图,例如以下调用就可以:

int histSize[1]; // number of bins

float hranges[2]; // min and max pixel value

const float* ranges[1];

int channels[1]; // only 1 channel used here


histSize[0]= 256;

hranges[0]= 0.0;

hranges[1]= 255.0;

ranges[0]= hranges;

channels[0]= 0; // by default, we look at channel 0



// Computes the 1D histogram.

Mat hist;

// Compute histogram

calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);



荷枪实弹
先看看设计的一个灰度类
第一个方法是构造函数
第二个方法是获得直方图
第三个方法是绘制直方图
class Histogram1D {
private:
int histSize[1]; // number of bins
float hranges[2]; // min and max pixel value
const float* ranges[1];
int channels[1]; // only 1 channel used here
public:
Histogram1D() {
histSize[0]= 256;
hranges[0]= 0.0;
hranges[1]= 255.0;
ranges[0]= hranges;
channels[0]= 0; // by default, we look at channel 0
} // Computes the 1D histogram.
Mat getHistogram(const cv::Mat &image) {
Mat hist;
// Compute histogram
calcHist(&image,1,channels,Mat(),hist,1,histSize,ranges);
return hist;
} Mat getHistogramImage(const cv::Mat &image){
// Compute histogram first
Mat hist= getHistogram(image);
// Get min and max bin values
double maxVal=0;
double minVal=0;
minMaxLoc(hist, &minVal, &maxVal, 0, 0);
// Image on which to display histogram
Mat histImg(histSize[0], histSize[0],CV_8U,Scalar(255));
// set highest point at 90% of nbins
int hpt = static_cast<int>(0.9*histSize[0]);
// Draw a vertical line for each bin
for( int h = 0; h < histSize[0]; h++ ) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
// This function draws a line between 2 points
line(histImg,Point(h,histSize[0]),
Point(h,histSize[0]-intensity),
Scalar::all(0));
}
return histImg;
}
};

然后,主函数调用

Mat image,gray;
image = imread( argv[1], 1 );
if( !image.data )
return -1;
cvtColor(image, gray, CV_BGR2GRAY); Histogram1D h;
namedWindow("Histogram");
imshow("Histogram",h.getHistogramImage(gray));

灰度直方图已经画好,以下画彩色直方图

画彩色直方图的过程和灰度直方图差点儿相同,是把RGB三通道分别独自出来,各自计算
/// Separate the image in 3 places ( B, G and R )
vector<Mat> bgr_planes;
split( src, bgr_planes );

如今,你就有了3个Mat存放在bgr_planes,再次强调下。OpenCV里面彩色图像的第一个通道是blue,BGR哦

然后。你用我们之前的Histogram1D类分别调用就能够了


举一反三
有时候。我们还能够绘制不同色彩空间的直方图
以下我们绘制2D Hue-Saturation histogram for a color image

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYWJjZDE5OTI3MTln/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="600" height="450" alt="">


因为我对HSV色彩空间的理论没有学过。所以以下就贴出官方教程的代码
#include <cv.h>
#include <highgui.h> using namespace cv; int main( int argc, char** argv )
{
Mat src, hsv;
if( argc != 2 || !(src=imread(argv[1], 1)).data )
return -1; cvtColor(src, hsv, CV_BGR2HSV); // Quantize the hue to 30 levels
// and the saturation to 32 levels
int hbins = 30, sbins = 32;
int histSize[] = {hbins, sbins};
// hue varies from 0 to 179, see cvtColor
float hranges[] = { 0, 180 };
// saturation varies from 0 (black-gray-white) to
// 255 (pure spectrum color)
float sranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges };
MatND hist;
// we compute the histogram from the 0-th and 1-st channels
int channels[] = {0, 1}; calcHist( &hsv, 1, channels, Mat(), // do not use mask
hist, 2, histSize, ranges);
double maxVal=0;
minMaxLoc(hist, 0, &maxVal, 0, 0); int scale = 10;
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3); for( int h = 0; h < hbins; h++ )
for( int s = 0; s < sbins; s++ )
{
float binVal = hist.at<float>(h, s);
int intensity = cvRound(binVal*255/maxVal);
rectangle( histImg, Point(h*scale, s*scale),
Point( (h+1)*scale - 1, (s+1)*scale - 1),
Scalar::all(intensity),
CV_FILLED );
} namedWindow( "Source", 1 );
imshow( "Source", src ); namedWindow( "H-S Histogram", 1 );
imshow( "H-S Histogram", histImg );
waitKey();
}

计算机视觉讨论群:162501053
转载请注明:http://blog.csdn.net/abcd1992719g




版权声明:本文博客原创文章,博客,未经同意,不得转载。

OpenCV2第一个马拉松8环——画一个柱状图的更多相关文章

  1. d3.js(v5.7)完整地画一个柱状图

    一.首先定义画布大小以及绘画区域的位置(总不能顶着屏幕边沿画吧) 代码: 图示: 二.横.纵向坐标轴 代码: 图示: 三.添加矩形个文本以及上色 图示:

  2. D3画完整柱状图(带坐标轴、标签)

    昨天晚上本来打算花一点时间把之前学的柱状图改一下,用CSV文件来替换自定义数据.这一替换可不得了,一晚上就搭进去了,还好今早找到了问题的所在,原因在于我的数据引用出了问题. 现在就来讲解一下如何画一个 ...

  3. 使用H5 canvas画一个坦克

      具体步骤如下:   1. 首先做出绘图区,作为坦克的战场   <canvas id="floor" width="800px" height=&quo ...

  4. PostScript的简单例子-用粗线画一个圆

    一 近期需要用到PostScript,查询资料学习PS的语法 简单的画一个圆的例子 %!PS-Adobe-3.0 /inch{72 mul} def 4.25 inch 5.5 inch 1.5 in ...

  5. 自己画一个ActivityIndicatorView-b

    苹果的UI控件中有一个UIActivityIndicatorView,俗称菊花.→_→现在我们仿照它来制作一个其它样式的指示器,如下: ActivityView.png 自定义指示器 首先画一个白色的 ...

  6. 用C语言画一个心

    用C语言图形库画一个心 --环家伟 这次我教大家用代码画一个心,这样你们就可以送给你们的女(男)朋友了.没找到对象的也可以用来表白啊. 1.首先,我去百度找了心形线的函数,如下: 2.  联系高中的数 ...

  7. vb代码之------画一个半透明矩形

    入吾QQ群183435019 (学习 交流+唠嗑). 废话不说,咱们来看代码吧 程序结果运行如下 需要如下API 1:GdipCreateFromHDC 功能:创建设备场景相对应的绘图区域(相当于给设 ...

  8. Effective前端1---chapter 2 用CSS画一个三角形

    1.CSS画三角形的画法 第一步:三角形可以用border画出来,首先一个有四个border的div长这样: <div class="triangle"></di ...

  9. OpenGL学习笔记(1) 画一个三角形

    最近找实习有一丢丢蛋疼,沉迷鬼泣5,四周目通关,又不想写代码,写篇笔记复习一下,要好好学图形学啊 用OpenGL画一个三角形 项目的简介 记录一下跟着learnOpenGL学习的过程 笔记里的代码放在 ...

随机推荐

  1. jvm在存储区域

    当区域执行的数据  JVM存储器的管理分为几个时间之后的数据区的实施:程序计数器.JavaVM栈.本地方法栈.Java堆.方法区(包括常量池的实现).   程序计数器 较小的内存空间,能够看作是当前线 ...

  2. 多于ListView同步滚动

    简介: 发展过程中可能遇到的2一个或多个其他listview为了用相应的关系保持滚动的情况下一起,本文演示了这种效应为大家. 功效: 实现原理: 在滚动当中不论什么一个ListView的时候,同一时候 ...

  3. SQL Server 2012 复制(发布订阅的研究)

    原文:SQL Server 2012 复制(发布订阅的研究) 已实现发布订阅功能,可以实现局域网内双击备份. 一.注意事项: a) 使用[事务复制]功能 b) 必须是相同的SqlServer 帐号和密 ...

  4. eclipse+Java2WSDL+WSDL2Java 2012-12-06 12:32:43| 分类: j2ee |报道|字体大小 认购 一、eclipse如何使用低axis生成wsdl 可以使用

    eclipse+Java2WSDL+WSDL2Java 一.eclipse下怎样用axis生成wsdl 能够使用axis提供的Java2WSDL功能生成所要公布类的 WSDL,过程例如以下:  1.在 ...

  5. JavaScript中null和undefined的总结

    先说null,它表示一个特殊值,常用来描述“空值”.对null执行typeof运算,结果返回字符串“object”,也就是说,可以将null认为是一个特殊的对象值,含义是“非对象”(感觉怪怪的).实际 ...

  6. Ubuntu 14.04 LAMP搭建(Apache 2.47+MySQL 5.5+PHP5.5)

    原文:Ubuntu LAMP搭建 为了数据库课程设计,只好自己搭一个数据库系统,采用LAMP方式. 一.安装 1.安装Apache sudo apt-get install apache2 Apach ...

  7. thinkphp学习笔记2—入口文件

    原文:thinkphp学习笔记2-入口文件 在thinkphp中有两个入口文件,一个是项目的入口文件,是index.php在主目录里面,还有一个是thinkphp框架的的入口文件,放在框架目录下面如: ...

  8. 独立博客网站FansUnion.cn操作2多年的经验和教训以及未来计划

    今天,我把运营了2年的独立博客站点FansUnion给"归零"了.    2012年6月.我成功搭建了自己的博客站点FansUnion.cn,这是因为自己的不懈努力和时代发展成就的 ...

  9. IOS 警告 收集

    Semantic Warnings Warning Message -WCFString-literal input conversion stopped due to an input byte t ...

  10. 求解决!!!SystemVerilog于ModelSim在编译和执行

    我们正在学习SV流程,样品执行书.. 功能:函数返回数组. Code1: /*书上提供的样例.存在错误,不可执行 function void init(ref int f[5], int start) ...