直方图均衡化程序实现



  原理参见网址:

   http://zh.wikipedia.org/wiki/%E7%9B%B4%E6%96%B9%E5%9B%BE%E5%9D%87%E8%A1%A1%E5%8C%96

  首先需要先配置好OpenCV的开发环境,直方图均衡化程序如下。

程序如下:

#include "stdafx.h"
#include <iostream>    
#include <core/core.hpp>    
#include <highgui/highgui.hpp> 
#include <opencv2/opencv.hpp>

using namespace cv;    
int _tmain(int argc, _TCHAR* argv[])
{
	
	//cv::Mat src = cv::imread(argv[1], 0);
	cv::Mat src = cv::imread("pic.bmp", 0);		//=0 Return a grayscale image. >0 Return a 3-channel color image
	int height = src.rows;
	int width = src.cols;

	int v_min = 1000;
	int v_max = -1;

	/*The method returns a Matlab-style zero array initializer and used to quickly form a constant array as a function parameter, 
	part of a matrix expression, or as a matrix initializer*/
	cv::Mat p = cv::Mat::zeros(256, 1, CV_32F);	//Mat::zeros(int rows, int cols, int type)   CV_32F: 32位浮点型

	for(int i = 0; i < height; i++)
	{
		for(int j = 0; j < width; j++)
		{
			int value = src.at<uchar>(i, j);	//遍历取各个像素的灰度值
			if(value < v_min)
				v_min = value;
			if(value > v_max)
				v_max = value;
			p.at<float>(value, 0) += 1;		//统计各个灰度级出现的次数
		}
	}
	std::cout << v_min << ' ' << v_max << std::endl;
	
	p /= (height*width);				//归一化: 计算矩阵p各个元素与总像素的比值

	
	cv::Mat c = cv::Mat::zeros(256, 1, CV_32F);	//0-255 代表256个灰度值
	for(int i = 0; i < 256; i++)
	{
		float p_sum = 0;
		for(int j = 0; j <= i; j++)
			p_sum += p.at<float>(j, 0); //直方图均衡化的作用是累计
		c.at<float>(i, 0) = p_sum;
	}

	
	cv::Mat y = cv::Mat::zeros(256, 1, CV_32F);	
	for(int i = 0; i < 256; i++)
	{
		y.at<float>(i, 0) = c.at<float>(i, 0) * (v_max - v_min) + v_min;	//将0-1的范围扩展到v_min与v_max范围之间
	}


	cv::Mat dst = src.clone();		//对原图像矩阵做拷贝
	for(int i = 0; i < height; i++)
	{
		for(int j = 0; j < width; j++)
		{
			int value = src.at<uchar>(i, j);
			
			dst.at<uchar>(i, j) = (int)(y.at<float>(value, 0) + 0.5);		//对值取4舍5入
		}
	}
	
	cv::imwrite("dst.bmp", dst);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值