You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用imhist函数实现图像直方图提取的MATLAB技术咨询

手动实现图像直方图提取(替代imhist)

嘿,作为MATLAB新手能想到手动实现直方图提取,这点超棒!先帮你指出原代码里的两处小问题:

  • picture(1,1,1)只是单个像素的红色通道值,用imhist只会显示这个单一值的直方图,和你标注的“white”不符;
  • picture(:,:,:)直接传入imhist时,MATLAB会自动把RGB图像转为灰度图再计算,但和你标注的“black”预期不符,建议如果要做灰度直方图,先通过rgb2gray(picture)转换。

接下来,我们不用imhist,用两种方式实现直方图提取:

方法1:用histcounts高效统计(MATLAB基础内置函数,非imhist)

histcounts是MATLAB用于统计数据分布的基础工具,我们可以用它统计每个灰度级的像素数量,再手动绘制直方图,效率很高:

clc
close all
clear all
picture = imread('space.jpg');
% 确保图像是8位无符号整数(常见图像格式)
if ~isa(picture, 'uint8')
    picture = uint8(picture);
end

% 显示原图
subplot(2,3,1); imshow(picture); title('Original Image');

% 红色通道直方图
red_channel = picture(:,:,1);
% 统计0-255每个灰度级的像素数,区间设为0到256(包含所有灰度值)
[red_counts, red_bins] = histcounts(red_channel, 0:256);
subplot(2,3,2); bar(red_bins(1:end-1), red_counts); title('Red Channel Histogram');
xlim([0 255]); % 限定x轴为灰度级范围

% 绿色通道直方图
green_channel = picture(:,:,2);
[green_counts, green_bins] = histcounts(green_channel, 0:256);
subplot(2,3,3); bar(green_bins(1:end-1), green_counts); title('Green Channel Histogram');
xlim([0 255]);

% 蓝色通道直方图
blue_channel = picture(:,:,3);
[blue_counts, blue_bins] = histcounts(blue_channel, 0:256);
subplot(2,3,4); bar(blue_bins(1:end-1), blue_counts); title('Blue Channel Histogram');
xlim([0 255]);

% 灰度直方图(替换你原代码的错误部分)
gray_pic = rgb2gray(picture);
[gray_counts, gray_bins] = histcounts(gray_pic, 0:256);
subplot(2,3,5); bar(gray_bins(1:end-1), gray_counts); title('Grayscale Histogram');
xlim([0 255]);

% 单个像素值的直方图(仅作演示,实际意义不大)
single_pixel = picture(1,1,1);
single_counts = histcounts(single_pixel, 0:256);
subplot(2,3,6); bar(0:255, single_counts); title('Single Pixel Value Histogram');
xlim([0 255]);

方法2:纯手动循环计数(适合理解底层原理)

如果你想完全脱离内置统计函数,手动遍历每个像素统计灰度级出现次数,这个方案能帮你理清直方图的核心逻辑:

clc
close all
clear all
picture = imread('space.jpg');
if ~isa(picture, 'uint8')
    picture = uint8(picture);
end

subplot(2,3,1); imshow(picture); title('Original Image');

% 初始化直方图数组,0-255共256个灰度级,初始计数为0
histogram_red = zeros(1, 256);
histogram_green = zeros(1, 256);
histogram_blue = zeros(1, 256);

% 获取图像尺寸
[rows, cols, ~] = size(picture);

% 遍历每个像素,统计各通道灰度级
for i = 1:rows
    for j = 1:cols
        % 灰度值是0-255,MATLAB数组索引从1开始,所以+1对应数组位置
        r_val = picture(i,j,1);
        histogram_red(r_val + 1) = histogram_red(r_val + 1) + 1;
        
        g_val = picture(i,j,2);
        histogram_green(g_val + 1) = histogram_green(g_val + 1) + 1;
        
        b_val = picture(i,j,3);
        histogram_blue(b_val + 1) = histogram_blue(b_val + 1) + 1;
    end
end

% 绘制红色通道直方图
subplot(2,3,2); bar(0:255, histogram_red); title('Red Channel Histogram (Manual)');
xlim([0 255]);

% 绿色通道直方图
subplot(2,3,3); bar(0:255, histogram_green); title('Green Channel Histogram (Manual)');
xlim([0 255]);

% 蓝色通道直方图
subplot(2,3,4); bar(0:255, histogram_blue); title('Blue Channel Histogram (Manual)');
xlim([0 255]);

% 手动统计灰度直方图
gray_pic = rgb2gray(picture);
histogram_gray = zeros(1,256);
for i = 1:rows
    for j = 1:cols
        gray_val = gray_pic(i,j);
        histogram_gray(gray_val + 1) = histogram_gray(gray_val + 1) + 1;
    end
end
subplot(2,3,5); bar(0:255, histogram_gray); title('Grayscale Histogram (Manual)');
xlim([0 255]);

% 单个像素的手动统计直方图
single_val = picture(1,1,1);
histogram_single = zeros(1,256);
histogram_single(single_val + 1) = 1;
subplot(2,3,6); bar(0:255, histogram_single); title('Single Pixel Histogram (Manual)');
xlim([0 255]);

小提示:

  • 手动循环的方式虽然直观,但处理大图像时效率远低于histcounts,日常使用更推荐第一种方法;
  • 8位图像的灰度范围是0-255,所以我们的直方图数组长度设为256,刚好对应每个灰度级的计数位置;
  • 原代码里的white和black标题可能是误解,换成“灰度直方图”或“单个像素直方图”会更准确。

内容的提问来源于stack exchange,提问作者AmirSadeghi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:12:46