Opencv Cookbook阅读笔记(用直方图统计像素)

当筵意气临九霄,星离雨散不终朝。这篇文章主要讲述Opencv Cookbook阅读笔记:用直方图统计像素相关的知识,希望能为你提供帮助。


灰度直方图的定义
灰度直方图是灰度级的函数,描述图像中该灰度级的像素个数(或该灰度级像素出现的频率):其横坐标是灰度级,纵坐标表示图像中该灰度级出现的个数(频率)。

Opencv Cookbook阅读笔记(用直方图统计像素)

文章图片
Opencv Cookbook阅读笔记(用直方图统计像素)

文章图片

#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
#include < opencv2/imgproc/imgproc.hpp>
#include < iostream>

using namespace cv;
using namespace std;

class Histogram1D

//定义一个处理单通道的类
private:
int histSize[1]; //bin的数量
float hranges[2]; //值范置
const float* ranges[1]; //值范围的指针.指向常量的指针(所指对像不一定是个常量),不能通过指针修改其值
int channels[1]; //通道数量


Mat getHistogram(const Mat & image)

//统计直方图
Mat hist;
calcHist(& image, 1,//一个图像的直方图
channels,//使用的通道
Mat(),//不使用掩码
hist,//作为结果的直方图
1,//一维直方图
histSize,
ranges
);

return hist;


public:
Histogram1D()

histSize[0] = 256;
hranges[0] = 0; //从0到256
hranges[1] = 256;

ranges[0] = hranges;

channels[0] = 0;


Mat getImageOfHistogram(const Mat & image, int zoom=1)

//zoom通道数
//画出直方图

Mat hist = getHistogram(image);

return getImageOfHistogram1(hist, zoom);


//定义为静态,不对成员变量进行操作
static Mat getImageOfHistogram1(const Mat & hist, int zoom)

//取得箱子的最大值和最小值
double maxVal = 0, minVal = 0;
minMaxLoc(hist, & minVal, & maxVal,0,0);

int histSize = hist.rows;
//用于显示的直方图
Mat histImg(histSize*zoom, histSize*zoom, CV_8U, Scalar(255));
//设置最高点为90%的箱子个数
int hpt = static_cast< int> (0.9*histSize);

//为每个箱子画垂线
for (int h = 0; h < histSize; h++)

float binVal = hist.at< float> (h);
if (binVal> 0)

int intensity = static_cast< int> (binVal*hpt / maxVal); //相对高度
line(histImg, Point(h*zoom, histSize*zoom),
Point(h*zoom, (histSize - intensity)*zoom),
Scalar(0), zoom);



return histImg;

;

int main()


Mat image = imread("1.jpg");
//判断是否为空
Histogram1D h;
//Mat histo = h.getHistogram(image);
Mat histo = h.getImageOfHistogram(image);
//namedWindow("Histogram");
//imshow("Histogram",histo);
//输出二值图像
Mat thresholded;
threshold(image, thresholded, 200,//阈值
255,//对超过域值的像素赋值
THRESH_BINARY); //阈值化类型

imshow("threshold", thresholded);
waitKey(0);

return 0;

View Code


上面的程序是计算并画出单通下图像的直方图,主要就是calcHist函数。类似的可以定义一个计算彩色直方图的类。
Opencv Cookbook阅读笔记(用直方图统计像素)

文章图片
Opencv Cookbook阅读笔记(用直方图统计像素)

文章图片

class ColorHistgoram

private:
int histSize[3];
float hranges[2];
const float*ranges[3];
int channels[3];
public:
ColorHistgoram()

histSize[0] = histSize[1] = histSize[2] = 256;
hranges[0] = 0;
hranges[1] = 256;

ranges[0] = hranges;
ranges[1] = hranges;
ranges[2] = hranges;

channels[0] = 0;
channels[1] = 1;
channels[2] = 2;


Mat getHistogram(const Mat & image)

Mat hist;

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

return hist;

;

View Code


提高图像对比度
有两种方法,一是应用查找表来伸展直方图(有的强度值范围没有被利用),另一种是直方图均衡化(对所有可用的像素强度值都均衡使用)。


Opencv Cookbook阅读笔记(用直方图统计像素)

文章图片
Opencv Cookbook阅读笔记(用直方图统计像素)

文章图片

//查找表函数
static Mat applyLookUp(const Mat & image, const Mat & lookup)

Mat result;
LUT(image, lookup, result);

return result;


//通过查找表提高图像的对比度
Mat stretch(const Mat & image, int minValue = https://www.songbingjia.com/android/0)

Mat hist = getHistogram(image);

//找到直方图的左右限值
float imin;
for (imin=0; imin < histSize[0]; imin++)

//忽略数量较少的箱子
float x = hist.at< float> (imin);
if (x> minValue)
break;

int imax = histSize[0] - 1;
for (; imax > = 0; imax--)

if (hist.at< float> (imax)> minValue)
break;


//创建查找表
int dim(256);
Mat lookup(1,//一维
& dim, CV_8U);
for (int i = 0; i < 256; i++)

//
if (i < imin)lookup.at< uchar> (i) = 0;
else if (i> imax)lookup.at< uchar> (i) = 255;
else
lookup.at< uchar> (i) = cvRound(255.0*(i - imin) / (imax - imin));


Mat result;
result = applyLookUp(image, lookup);

return result;

View Code


【Opencv Cookbook阅读笔记(用直方图统计像素)】 通过如下的函数可实现直方图均衡化。
//灰度图
equalizeHist(image, result);












    推荐阅读