指数滤波平滑直方图

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
//#include <pcl/io/pcd_io.h>
//#include <pcl/point_types.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<vector>
#include <opencv2/opencv.hpp>



int histSize = 255;     // 划分HIST的初始个数,越高越精

int  HIST(float hist[255], cv::Mat histimg)
{
	char string[10];

	if (histSize == 0)
	{
		printf("直方图条数不能为零!\n");
	}
	else
	{
		int  maxVal = 0;
		for (int j = 0; j <= 255; j++)
		{
			if (maxVal<hist[j])
			{
				maxVal = hist[j];
			}
		}
		

		//cv::Point maxLoc;
		//cv::minMaxLoc(hist, NULL, &maxVal, NULL, &maxLoc);//寻找最大值及其位置

		double bin_w = (double)histimg.cols / histSize;  // histSize: 条的个数,则 bin_w 为条的宽度
		double bin_u = (double)histimg.rows / maxVal;  // maxVal: 最高条的像素个数,则 bin_u 为单个像素的高度

		// 画直方图
		for (int i = 0; i < histSize - 1; i++)
		{
			cv::Point p0 = cv::Point(i*bin_w, histimg.rows);

			float binValue = hist[i];           //   注意hist中是float类型
			cv::Point p1 = cv::Point((i + 1)*bin_w, histimg.rows - binValue * bin_u);

			cv::rectangle(histimg, p0, p1, cv::Scalar(0, 255, 0), 2, 8, 0);
		}

		//曲线形式的直方图
		for (int i = 0; i < histSize; i++)
		{
			cv::line(histimg,
				cv::Point(bin_w*i + bin_w / 2, histimg.rows - hist[i] * bin_u),
				cv::Point(bin_w*(i + 1) + bin_w / 2, histimg.rows - hist[i + 1] * bin_u),
				cv::Scalar(255, 0, 0), 2, 8, 0);//bin_w/2是为了保证折现位于直方图每条的中间位置
		}

		//画纵坐标刻度(像素个数)
		int kedu = 0;
		for (int i = 1; kedu < maxVal; i++)
		{
			kedu = i * maxVal / 10;
			sprintf(string, "%d", kedu);//把一个整数转换为字符串
			//在图像中显示文本字符串
			cv::putText(histimg, string, cv::Point(0, histimg.rows - kedu * bin_u), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 255), 1);

			cv::line(histimg, cv::Point(0, histimg.rows - kedu * bin_u), cv::Point(histimg.cols - 1, histimg.rows - kedu * bin_u), cv::Scalar(0, 0, 255));
		}
		//画横坐标刻度(像素灰度值)
		kedu = 0;
		for (int i = 1; kedu < 256; i++)
		{
			kedu = i * 20;
			sprintf(string, "%d", kedu);//把一个整数转换为字符串
			//在图像中显示文本字符串
			putText(histimg, string, cv::Point(kedu*(histimg.cols / 256), histimg.rows), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 255), 2);
		}


	}
}

	
	
							
	
							
					
	




	using namespace cv;
	using namespace std;

	
	int main(int argc, char** argv)
	{
		cv::Mat src;//需要计算直方图的灰度图
		
	
		src = cv::imread("D:\\BS\\2D\\30000Exposure-晚上-有光源\\Image2D_2021_07_13_18_14_24.bmp", 0);
		原始图像的显示
		//cv::namedWindow("src", 1);
		//cv::imshow("src", src);
		//cv::namedWindow("Histogram", 1);

		cv::MatND hist;//计算得到的直方图结果
		//求图像的直方图
		int dims = 1;
		float hranges[2] = { 0, 255 };
		const float *ranges[1] = { hranges };   // 这里需要为const类型
		int channels = 0;
		//计算图像的直方图
		calcHist(&src, 1, &channels, cv::Mat(), hist, dims, &histSize, ranges);    // cv 中是cvCalcHist
		float hist1[255];
		for (int j = 0; j <= hist.rows; j++)
		{

			hist1[j]=hist.at<float>(j);
		}

		//原始图像的直方图的显示
		int maxvalue = 256;
		//设置直方图显示最大值在间隔的等分值
		//cv::createTrackbar("histSize", "src", &histSize, maxvalue, HIST);
		/*cv::Mat histimg_ori;
		histimg_ori.create(512, 256 * 4, CV_8UC3);
		histimg_ori.setTo(cv::Scalar(0, 0, 0));
		HIST(hist1, histimg_ori);
		cv::imshow("Histogram_ori", histimg_ori);
		cv::waitKey(6000000);*/
		
		指数滤波
		float average = (hist.at<float>(0) + hist.at<float>(1) + hist.at<float>(2)) / 3;
		
		float hist_new[255];;
		
		//cv::MatND hist_new;
		hist_new[0]= average;
		float EI = 0.6;
		float hist_new1;
		for (int j = 1; j <= hist.rows; j++)
		{
			hist_new[j] = EI * hist.at<float>(j) + hist.at<float>(j-1) * (1 - EI);
		}
		//验证值有没有变化
		/*for (int j = 1; j <= hist.rows; j++)
		{
			float aa = hist_new[j] - hist1[j];
			cout << aa << endl;
		}*/

		//cv::Mat histimg_ori;
		//histimg_ori.create(512, 256 * 4, CV_8UC3);
		//histimg_ori.setTo(cv::Scalar(0, 0, 0));
		//HIST(hist_new, histimg_ori);
		//cv::imshow("Histogram_ori", histimg_ori);
		//cv::waitKey(6000000);


		
		

		//最大值滤波
		float hist_max[255];;
		hist_max[0] = hist_new[0];
		hist_max[1] = hist_new[1];
		float max = 0;
		for (int j =23; j <= 255; j++)
		{

			for (int k = -3; k <2; k++)
			{
				if (max < hist_new[k+j])
				{
					max = hist_new[k + j];
				}
			}
			hist_max[j] = max;
			max = 0;
		}
		
		

	/*	float aa;
		for (int j = 0; j <= 255; j++)
		{
			aa = hist_new[j] - hist_max[j];
			cout << aa << endl;
		}*/
		


		cv::Mat histimg_max;
		histimg_max.create(512, 256 * 4, CV_8UC3);
		histimg_max.setTo(cv::Scalar(0, 0, 0));
		HIST(hist_max, histimg_max);
		cv::imshow("Histogram_max", histimg_max);
		cv::waitKey(6000000);



		

		
	



		







		return 0;
	}


	


	


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值