当筵意气临九霄,星离雨散不终朝。这篇文章主要讲述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函数。类似的可以定义一个计算彩色直方图的类。
文章图片
文章图片
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
提高图像对比度
有两种方法,一是应用查找表来伸展直方图(有的强度值范围没有被利用),另一种是直方图均衡化(对所有可用的像素强度值都均衡使用)。
文章图片
文章图片
//查找表函数
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);
推荐阅读
- Search a 2D Matrix
- Linux下玩转nginx系列——初识nginx及其使用入门
- 拉格朗日对偶
- 第二节:SpingBoot单元测试
- 这8个JS 新功能,你应该去尝试一下
- #yyds干货盘点# 详解JavaScript中的闭包
- OpenHarmony 源码解析之DFX子系统-标准系统接口使用说明
- Shell脚本画图形
- #yyds干货盘点#CCNA学习记录4