OpenCV2第一个马拉松8环——画一个柱状图

在包里

  • 灰度直方图
  • 彩色直方图

葵花宝典

直方图的理论还是非常丰富的,应用也非常多,诸如:

直方图均衡化

直方图匹配(meanshift,camshift)

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

拿灰度图像来说。直方图就是不同的灰度相应的个数,横轴(x)就是[0,256), 纵轴(y)就是相应的个数

例如以下图,各自是灰度直方图和彩色直方图



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

初识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" >

因为我对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

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

时间: 2024-12-05 19:23:44

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

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

一.首先定义画布大小以及绘画区域的位置(总不能顶着屏幕边沿画吧) 代码: 图示: 二.横.纵向坐标轴 代码: 图示: 三.添加矩形个文本以及上色 图示: 原文地址:https://www.cnblogs.com/eco-just/p/10018038.html

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

昨天晚上本来打算花一点时间把之前学的柱状图改一下,用CSV文件来替换自定义数据.这一替换可不得了,一晚上就搭进去了,还好今早找到了问题的所在,原因在于我的数据引用出了问题. 现在就来讲解一下如何画一个柱状图吧: 柱状图的画法和折线图其实很类似,只要掌握了比例尺的用法和坐标轴的画法,我们只要在此基础上添加“rect”元素添加矩形就可以了,但这其中也有一些要点,我会在其中标出,希望对你有用. 对于d3不同版本带来的代码不适用的解决办法:1).下载对应的v3或者v4版本加到代码引用里可以解决. 2).

自己画一个ActivityIndicatorView-b

苹果的UI控件中有一个UIActivityIndicatorView,俗称菊花.→_→现在我们仿照它来制作一个其它样式的指示器,如下: ActivityView.png 自定义指示器 首先画一个白色的扇形.创建一个MyLayer类继承自CALayer,重写它的绘图方法- (void)drawInContext:(CGContextRef)ctx: - (void)drawInContext:(CGContextRef)ctx {        CGContextSetRGBFillColor(c

智慧城市,在中国的北海边再画一个圈——大连“中国首届智慧城市协同创新峰会”请你带好笔

这可能是中国第二次大规模地改变城市印象.从1979年,"在中国的南海边画了一个圈",用三十多年的时间,中国完成了从传统城市到现代城市的跨越,繁荣.机会.财富.梦想演变成激动人心的中国奇迹和城市骄傲.但随之而来,城市化进程也引发诸多的问题,社会保险.医疗.就业.安防.交通--所有的这些问题都为生活于此的每个城居者带来困扰. 现代化的中国城市需要改变,城市的管理需要提升,所有人都在发问,城市未来的发展空间在哪,围绕城市建设,商机在哪?如果城市已经拥有了摩天大楼.地铁公交.城际轻轨.繁华商铺

10分钟,利用canvas画一个小的loading界面(顺便讨论下绘制效率问题)

首先利用定义下canvas得样式 <canvas width="1024" height="720" id="canvas" style="border: 1px solid #808080;display: block;margin: 100px auto;>你的游览器不支持canvas</canvas> 这里主要要说的就是宽高,不要在style里面定义,不然会被拉伸.(对于这点,建议大家看下W3c文档,不是很

10分钟,利用canvas画一个小的loading界面

首先利用定义下canvas得样式 <canvas width="1024" height="720" id="canvas" style="border: 1px solid #808080;display: block;margin: 100px auto;>你的游览器不支持canvas</canvas> 这里主要要说的就是宽高,不要在style里面定义,不然会被拉伸.(对于这点,建议大家看下W3c文档,不是很

CSS3画一个滚动的骰子

今天利用CSS3来画一个自动滚动的骰子. 思路:骰子的六个面分别用六个ul标签,每个面的点数就是li标签,点数的排列采用伸缩布局,然后采用定位和transform属性将六个面翻转折叠成立方体. 1.HTML结构:用一个类名为box的大盒子将六个面(ul)包起来,方便给整个骰子定位和添加动画:每个ul里的li代表每个面的点数,其中第四.五.六面每一列的点数分别用一个div包起来 1 <div class="box"> 2 <ul class="one"

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

1.CSS画三角形的画法 第一步:三角形可以用border画出来,首先一个有四个border的div长这样: <div class="triangle"></div> <style> .triangle{ margin: 100px; border-top: 40px solid #000; border-bottom: 40px solid #333; border-left: 40px solid #666; border-right: 40px

如何画一个精致的思维导图

画思维导图和画一个精致的思维导图还是有很大的区别的,不仅对软件要求比较高,还要将内容更加的丰富,所以就需要下功夫啦,下面交给大家画精致思维导图的操作方法,想要使用的朋友可以参考使用. 工具/原料: 迅捷画图官网,能上网的电脑并带有浏览器 操作方法介绍: 1.进入迅捷画图官网中,在上述列表中有三项操作,选择模板点击进去可以看到有很多制作精美的模板,并且不同的分类归纳的很清楚,需要套用模板的可以点击模板进行编辑使用. 2.这里要绘制的是思维导图,点击新建文件之后会有四个选项可以选择,点击思维导图即可