OpenCV入门(七)

参考书目:《OpenCV计算机视觉编程攻略》(第3版)

计算灰度图像的直方图并进行阈值化操作:

引入查找表:

//用直方图统计像素
/*
1.计算图像直方图
2.利用查找表修改图像外观
3.直方图均衡化
4.反向投影直方图检测特定图像内容
5.用均值平移法查找目标
6.比较直方图搜索相似图像
7.用积分图像统计像素
*/
#include<opencv2/opencv.hpp>
#include<iostream>

//创建灰度图像的直方图
class Histogram2D {
private:
	int histSize[1]; //直方图中箱子的数量
	float hranges[2];//值范围
	const float* ranges[1];//值范围的指针
	int chanels[1];  //要检查的通道数
public:
	//准备一维直方图的默认参数
	Histogram2D() {
		histSize[0] = 256;
		hranges[0] = 0.0;
		hranges[1] = 256.0;
		ranges[0] = hranges;
		chanels[0] = 0;
	}
	cv::Mat getHistogram(const cv::Mat& image) {
		cv::Mat hist;
		//用calchist函数计算一维直方图
		cv::calcHist(&image, 
			1,//1幅图像的直方图
			chanels,//使用的通道
			cv::Mat(),//不使用掩码
			hist,//作为结果的直方图
			1,//这是一维的直方图
			histSize,
			ranges);
		return hist;
	}

	//计算一维直方图,并返回它的图像
	cv::Mat getHistogramImage(const cv::Mat& image, int zoom = 1) {
		//先计算直方图
		cv::Mat hist = getHistogram(image);
		//创建图像
		return getImageOfHistogram(hist, zoom);
	}
	//
	static cv::Mat getImageOfHistogram(const cv::Mat& hist, int zoom) {
		//取得箱子值的最大值和最小值
		double maxVal = 0;
		double minVal = 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 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);
				cv::line(histImg, cv::Point(h * zoom, histSize * zoom),
					cv::Point(h * zoom, (histSize - intensity) * zoom),
					cv::Scalar(0), zoom);
			}
		}
		return histImg;
	}

	static cv::Mat applyLookUp(const cv::Mat& image,
		const cv::Mat& lookup)
	{
		cv::Mat result;
		cv::LUT(image, lookup, result);
		return result;
	}
};



int main()
{
	cv::Mat image = cv::imread("group.jpg", 0);//以黑白方式打开
	//直方图对象
	Histogram2D h;
	//以图像形式显示直方图
	cv::namedWindow("Histogram");
	cv::imshow("Histogram", h.getHistogramImage(image));
	//阈值化处理
	cv::Mat thresholded;
	cv::threshold(image, thresholded, 70, 255, cv::THRESH_BINARY);
	cv::namedWindow("Thresholded");
	cv::imshow("Thresholded", thresholded);
	//创建一个图像反转的查找表
	cv::Mat lut(1, 256, CV_8U);
	for (int i = 0; i < 256; i++)
	{
		lut.at<uchar>(i) = 255 - i;
	}
	cv::Mat result = h.applyLookUp(image, lut);
	cv::namedWindow("lut");
	cv::imshow("lut", result);
	cv::waitKey(0);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值