灰度直方图是对图像中灰度级分布的统计,横坐标为灰度值,纵坐标是像素个数(也可以采用当前像素值个数占总像素个数的百分比)。这里直接统计个数。
1. matalb代码如下:
%画灰度直方图
%1, 读取图像
clc;
clear;
image = imread('D:\Code\Image\classic.jpg');
image = rgb2gray(image);
figure,imshow(image);
[row,col] = size(image);
grayNum = zeros(1,256); %列下标值[1,256]减一表示灰度值[0,255],保存某个灰度值[0,255]的像素个数
%2, 记录灰度值为image(i,j)像素个数
for i=1:row
for j=1:col
grayNum(image(i,j)+1) = grayNum(image(i,j)+1)+1; %灰度值加一就是列值
end
end
%3, 画灰度直方图,将列下标[1,256]即灰度值,映射到[0,255]
figure,
bar(0:255,grayNum,'grouped');%第一个参数为横轴(即灰度值),第二个参数为纵轴(个数),第三个为直方图类型
效果:
2. C++ 代码实现:
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("D:/Code/Image/classic.jpg", 0); //以灰度图形式读入
imshow("原图", img);
int row = img.rows;
int col = img.cols;
int grayNum[256] = { 0 }; // 数组下标值等于灰度值
//遍历整幅图像,统计个数
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
grayNum[img.at<uchar>(i, j)] = grayNum[img.at<uchar>(i, j)] + 1;
}
}
// 画直方图
double maxVal = 0;
int i = 0;
while (1)
{
if (i > 255)
break;
if (grayNum[i] > maxVal)
maxVal = grayNum[i];
i++;
}
int bin_num = 256; // [0,255]共256个bin
Mat histImg(bin_num, bin_num, CV_8U, Scalar(255)); //生成白色画布(255)
int hpt = static_cast<int>(0.9*bin_num);
//每个bin就是一条垂直线
for (int i = 0; i<bin_num; i++){
printf("%d ", i);
int binVal = grayNum[i];
int intensity = static_cast<int>(binVal*hpt / maxVal); // 个数转化为长度,同样上面的灰度值也可以转化为长度
//两点之间绘制一条线
line(histImg, Point(i, bin_num), //直方图下面的点
Point(i, bin_num - intensity), //直方图上面的点
Scalar::all(0));
}
imshow("dd", histImg);
waitKey(0);
return 0;
}
效果图: