Engee 文档
Notebook

直方图计算

图像直方图是图像中像素强度分布的图形表示。它显示图像中有多少像素具有一定的强度(颜色或亮度)值。

为什么要计算直方图?

通过直方图,您可以分析光照、调整对比度、图像亮度、突出物体、平衡色彩并提高视觉质量。

通过直方图可以评估图像的亮度或暗度:

如果像素在左边 "挤在一起"(低强度),则说明图像太暗。

如果像素挤在右边(高强度),则图像过亮。

连接处理图像所需的软件包

In [ ]:
import Pkg
Pkg.add("Images")
Pkg.add("StatsBase")
Pkg.add("Plots")
In [ ]:
using Images, StatsBase, Plots

上传图像

In [ ]:
path_to_img_1 = "$(@__DIR__)/Cozy_Autumn_Beverage_Moment.jpeg";
In [ ]:
Image_1 = load(path_to_img_1)
Out[0]:
No description has been provided for this image

数据处理

channelview 将图像转换成一个数组,其中每个颜色通道(红、绿、蓝)都是一个单独的层。

In [ ]:
rgb_planes = channelview(Image_1);

接下来,将颜色通道分割成不同的变量

In [ ]:
blue_channel = rgb_planes[3, :, :]
green_channel = rgb_planes[2, :, :]
red_channel = rgb_planes[1, :, :];

可视化单个通道

In [ ]:
red_image = colorview(RGB, red_channel, zeros(size(red_channel)), zeros(size(red_channel)))
Out[0]:
No description has been provided for this image

计算直方图

In [ ]:
red_channel
Out[0]:
2400×1345 Array{N0f8,2} with eltype N0f8:
 0.184  0.192  0.204  0.212  0.224  …  0.102  0.098  0.082  0.071  0.063
 0.188  0.192  0.204  0.212  0.22      0.082  0.075  0.067  0.067  0.067
 0.196  0.2    0.212  0.22   0.22      0.075  0.063  0.067  0.067  0.059
 0.196  0.2    0.208  0.216  0.216     0.067  0.055  0.059  0.059  0.051
 0.192  0.2    0.208  0.212  0.22      0.059  0.055  0.047  0.043  0.051
 0.188  0.196  0.204  0.212  0.216  …  0.055  0.055  0.047  0.043  0.059
 0.188  0.196  0.204  0.212  0.216     0.055  0.051  0.055  0.055  0.059
 0.188  0.192  0.204  0.212  0.212     0.043  0.039  0.047  0.059  0.055
 0.18   0.188  0.196  0.208  0.212     0.051  0.051  0.055  0.055  0.043
 0.184  0.184  0.196  0.204  0.212     0.051  0.055  0.059  0.059  0.043
 0.184  0.188  0.196  0.196  0.204  …  0.059  0.059  0.059  0.059  0.051
 0.188  0.184  0.192  0.196  0.204     0.055  0.055  0.055  0.059  0.055
 0.184  0.188  0.196  0.2    0.208     0.051  0.051  0.051  0.051  0.051
 ⋮                                  ⋱  ⋮                           
 0.098  0.039  0.035  0.098  0.149     0.502  0.486  0.49   0.486  0.486
 0.027  0.043  0.075  0.071  0.09      0.514  0.502  0.498  0.494  0.498
 0.11   0.122  0.169  0.141  0.118  …  0.525  0.518  0.518  0.522  0.506
 0.169  0.098  0.125  0.133  0.122     0.537  0.533  0.537  0.541  0.518
 0.063  0.125  0.114  0.051  0.035     0.549  0.545  0.549  0.537  0.522
 0.157  0.165  0.133  0.059  0.024     0.553  0.553  0.549  0.545  0.549
 0.212  0.125  0.102  0.094  0.09      0.561  0.557  0.553  0.553  0.573
 0.094  0.078  0.133  0.106  0.09   …  0.573  0.561  0.565  0.561  0.576
 0.027  0.067  0.122  0.047  0.075     0.58   0.569  0.576  0.573  0.573
 0.051  0.043  0.098  0.094  0.114     0.584  0.584  0.584  0.588  0.573
 0.039  0.047  0.157  0.196  0.098     0.588  0.592  0.592  0.588  0.569
 0.09   0.082  0.122  0.129  0.059     0.588  0.596  0.596  0.588  0.569

在上面的单元格中,我们可以看到图像中每个像素的红色通道强度数组

首先,我们将强度分成不同的范围。例如,对于归一化数据 [0,1],也就是我们这里的数据。 我们可以使用 256 个相等的区间。然后,我们计算每个范围内有多少像素。

将单元格数设为 256

In [ ]:
histSize = 256;

设置数值范围(0 至 1)

In [ ]:
hist_range = 0:1/(histSize-1):1;

让我们开始计算直方图。StatsBase.Histogram 可以计算直方图

In [ ]:
b_hist = fit(Histogram, blue_channel[:], hist_range)
r_hist = fit(Histogram, red_channel[:], hist_range)
g_hist = fit(Histogram, green_channel[:], hist_range);

可视化

我们将计算出的直方图可视化,以清楚地评估强度的分布情况

In [ ]:
plot(r_hist.edges[1][1:end-1], r_hist.weights, color=:red, label="Red Channel")
plot!(b_hist.edges[1][1:end-1], b_hist.weights, color=:blue, label="blue Channel")
plot!(g_hist.edges[1][1:end-1], g_hist.weights, color=:green, label="green Channel")
Out[0]:

从上图可以看出,按强度等级划分的大部分像素都在图的左侧,这表明图像变暗了

结论

在本例中,通过计算像素强度直方图来估计图像的亮度