不使用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
相关产品推荐
相关产品推荐

