#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;
}
指数滤波平滑直方图
最新推荐文章于 2025-03-12 18:13:54 发布