OpenCV计算和显示图像直方图
来源:互联网 发布:网络机顶盒直播节目源 编辑:程序博客网 时间:2024/05/21 10:28
要在OpenCV中计算直方图,可调用函数calcHist(),
void calcHist(const Mat* images,//源图像 int nimages,//源图像的个数。设为1,则仅为一个图像的直方图 const int* channels,//使用的通道 InputArray mask, //掩码,(可设置哪些像素不参与直方图计算) OutputArray hist, //作为结果的直方图 int dims, //直方图的维数 const int* histSize,//直方图箱子的数量 const float** ranges, //像素值的范围 bool uniform=true, bool accumulate=false )
这是一个通用的直方图计算函数,可处理包含任何值类型和范围的多通道图像。为了简化使用,在这里构建两个计算直方图的类:分别处理单通道图像和彩色图像。
单通道图像
比如单通道图像可以这样调用类函数来计算直方图:
Histogram1D h;//直方图计算得算法类h.setHistSize(256);//设置直方图的箱子数量cv::Mat hist=h.getHistogram(image);//计算直方图cv::Mat histImg = h.getHistogramImage(image, 1);//将直方图画出来,返回直方图图像cv::imshow("histogram", histImg);
单通道图像计算直方图的算法类如下:
//头文件 Histogram1D.h#pragma once#include"opencv2/opencv.hpp"#include"opencv2/core/core.hpp"#include"opencv2/highgui/highgui.hpp"class Histogram1D{private: int channels[1];//使用的通道数量 int histSize[1];//直方图箱子(bin)的数量 const float* ranges[1];//像素值范围 float hranges[2];public: Histogram1D(); cv::Mat getHistogram(const cv::Mat& image);//得到直方图 void setHistSize(int n);//设置直方图箱子数量 int* getHistSize(); static cv::Mat applyLookUp(const cv::Mat& image,const cv::Mat& lookup);//应用查找表 cv::Mat getHistogramImage(const cv::Mat& image,int zoom);//得到直方图图像 ~Histogram1D();};
//实现文件 Histogram1D.cpp#include "Histogram1D.h"Histogram1D::Histogram1D(){ histSize[0] = 256;//箱子个数设为256 channels[0] = 0;//使用一个通道,默认为0 hranges[0] = 0.0; hranges[1] = 256.0; ranges[0] = hranges;//值范围}Histogram1D::~Histogram1D(){}cv::Mat Histogram1D::getHistogram(const cv::Mat& image){ cv::Mat hist; cv::calcHist(&image, 1,//单幅图像的直方图 channels, cv::Mat(), hist, 1,//一维直方图 histSize, ranges); return hist;}cv::Mat Histogram1D::getHistogramImage(const cv::Mat& image, int zoom = 1){ cv::Mat hist = getHistogram(image); //这里调用静态方法 return getImageOfHistogram(hist,zoom);}cv::Mat getImageOfHistogram(const cv::Mat& hist, int zoom//设置缩放系数 ){ double minVal = 0; double maxVal = 0; cv::minMaxLoc(hist,&minVal,&maxVal,0,0); int histSize = hist.rows; //用于显示直方图的方形图像 cv::Mat histImg(histSize*zoom,histSize*zoom,CV_8U,cv::Scalar(255)); //设置最高点为90%的箱子个数 int hmax = static_cast<int>(histSize*0.9); //画线 for (int h = 0; h < histSize;h++) { float binVal= hist.at<float>(h); if (binVal > 0) { int intensity = binVal*hmax / maxVal; cv::line(histImg, cv::Point(h*zoom, histSize*zoom), cv::Point(h*zoom, (histSize-intensity)*zoom), cv::Scalar(0), zoom); } } return histImg;}//应用查找表相关的函数cv::Mat Histogram1D::applyLookUp(const cv::Mat& image, const cv::Mat& lookup){ cv::Mat result; cv::LUT(image,lookup,result); return result;}//get方法,获取成员变量histSizeint* Histogram1D::getHistSize(){ return histSize;}//set方法,设置成员变量histSizevoid Histogram1D::setHistSize(int n){ histSize[0] = n;}
运行效果如下:
输入图像
直方图
彩色图像
再比如,彩色图像可以这样调用类函数来计算直方图:
ColorHistogram hc;//直方图计算得算法类hc.setSize(16);//设置每个通道直方图箱子数量cv::Mat hist=hc.getHistogram(image);//计算直方图//或者//cv::Mat hist=hc.getHueHistogram(image);//计算H通道直方图//cv::Mat histImg=hc.getHistImage(hist,16);//放大16倍,使图像能以256*256大小显示//imshow("histImg",histImg);
彩色图像计算直方图的算法类如下:
//头文件 ColorHistogram.h#pragma once#include"opencv2/opencv.hpp"#include"opencv2/core/core.hpp"#include"opencv2/highgui/highgui.hpp"class ColorHistogram{private: int channels[3];//使用的通道数量 int histSize[3];//直方图箱子(bin)的数量 const float* ranges[3];//存放值范围(3个通道) float hranges[2];public: ColorHistogram(); cv::Mat getHistogram(const cv::Mat& image); cv::Mat getHueHistogram(const cv::Mat& image,int minSaturation);//设置饱和度阈值的原因是低饱和度图像RGB分量几乎相同, //很难确定准确颜色,故排除 void setSize(int n);//设置直方图箱子数量 ~ColorHistogram();};
//实现文件 ColorHistogram.cpp#include "ColorHistogram.h"ColorHistogram::ColorHistogram(){ histSize[0] = 256;//箱子个数设为256 histSize[1] = 256;//箱子个数设为256 histSize[2] = 256;//箱子个数设为256 channels[0] = 0;//使用通道0 channels[1] = 1;//使用通道1 channels[2] = 2;//使用通道2 hranges[0] = 0.0; hranges[1] = 256.0; ranges[0] = hranges;//值范围 ranges[1] = hranges;//值范围 ranges[2] = hranges;//值范围}cv::Mat ColorHistogram::getHistogram(const cv::Mat& image){ cv::Mat hist; cv::calcHist(&image, 1,//单个图像的直方图 channels, cv::Mat(), hist, 3,//3维直方图 histSize, ranges); return hist;}void ColorHistogram::setSize(int n){ histSize[0] = n; histSize[1] = n; histSize[2] = n;}cv::Mat ColorHistogram::getHueHistogram(const cv::Mat& image, int minSaturation){ cv::Mat hist; cv::Mat hsv; cv::cvtColor(image,hsv,CV_BGR2HSV); //掩码,计算直方图时掩盖低饱和度像素贡献 cv::Mat mask; if (minSaturation > 0) { std::vector<cv::Mat> v; cv::split(hsv,v); //饱和度通道 cv::threshold(v[1],mask,minSaturation,255,cv::THRESH_BINARY ); } hranges[0] = 0.0; hranges[1] = 180; channels[0] = 0; cv::calcHist(&hsv, 1,//单个图像的直方图 channels, mask, hist, 1,//3维直方图 histSize, ranges); return hist;}ColorHistogram::~ColorHistogram(){}
运行效果如下:
输入图像
这里插几句嘴。。
cv::Mat hist=hc.getHistogram(image);//计算直方图
上述方法返回的是三维的cv::Mat实例。如果选用含有256个箱子的直方图,这个矩阵的像素个数为256^3。形象的讲,它是一个正方体。所以无法显示。
类中计算直方图还有一种方法:
cv::Mat hist=hc.getHueHistogram(image);//计算H通道直方图
首先将输入图像转化为HSV格式,H代表色调,代表颜色信息。这样得到的是一维直方图,结果如下(这里将直方图箱子数量设为16):
0 0
- OpenCV计算和显示图像直方图
- Opencv---计算图像直方图方差和均值
- calcHist()计算图像直方图opencv
- OpenCV之图像直方图计算
- opencv实现灰度图像的直方图点计算以及灰度直方图显示
- opencv学习之(五)-直方图计算和绘制图像直方图
- opencv学习之(五)-直方图计算和绘制图像直方图
- OpenCV 计算图像一维直方图
- OpenCV【4】---calcHist 计算图像的直方图
- OpenCV 学习(计算图像的直方图)
- opencv图像直方图的计算及绘制
- Opencv学习之 计算图像直方图
- OPENCV图像直方图显示(代码)
- OpenCV-007:图像直方图的显示
- opencv学习(二)计算图像的直方图和表示为柱状图
- OPenCV直方图均衡 和 图像缩放
- OpenCV图像直方图的理解和验证
- OpenCV图像增强:直方图拉伸和直方图均衡化
- javascript中的基本包装类型
- 位运算符面试题--Java基础014
- JavaScript如何处理解析JSON数据详解
- SVM学习总结(一)如何学习SVM
- 【扫雷】C语言编写的小程序扫雷
- OpenCV计算和显示图像直方图
- java 数据库连接(用properties文件)
- c++字符串操作
- struts2常用校验器及其配置
- 分水问题
- map<string, vector<string> >
- struts2实现国际化
- 小程序组件集合-(陆续更新中,欢迎探讨~)
- 选夫婿1