这里统计了最全的matlab画直方图的方法,各个色彩空间(RGB/HSV/Lab)的都包含,相信这对大家都有帮助。。。
彩色图像直方图统计
统计图像直方图,进行灰度级线性分段增强灰度分段线性变换实现代码绘制彩色图像直方图绘制彩色直方图方法一绘制彩色直方图方法二将图像映射到HSV视觉接近的颜色空间中,计算统计在该空间的直方图绘制Lab颜色空间分量图和分量直方图makecform和applycform函数实现代码资源传送门「❤️ 感谢大家」统计图像直方图,进行灰度级线性分段增强
灰度分段线性变换
在某些情况下,为了将图像灰度级整个范围(A,B)或其中某一段扩展或压缩到另一灰度范围(Z1,ZK)质内,称灰度的线性变换。
(1)当图像曝光不充分,使(A,B)区间小于(Z1,ZK)区间,即:A>Z1、B<ZK可选用这样的变换:
通过这种变换,使得图像灰度范围从(A,B)扩展到(Z1,ZK),实际上使曝光不充分的图像中黑的更黑、白的更白,从而提高了图像灰度的对比度。
(2)若图像的绝大部分灰度集中在(A,B)之间,则用这样的变换:
这种变换实际上失去了一部分图像的信息。
实现代码
实验测试图像:lena图
I = imread('lena1.jpg') ; % 读取rgb图像I = rgb2gray(I);figure, imshow(I); figure, imhist(I); % 显示图像的灰度值直方图%进行灰度级线性分段增强:f0 = 0; g0 = 0;fl = 20; g1 = 100;f2 = 100; g2 = 180 ;f3= 255; g3 = 255 ;r1 = (g1 - g0) / (fl - f0);bl = g0 - r1 * f0;r2 = (g2 - g1) / (f2 - fl);b2 = g1 - r2 * fl;r3 = (g3 - g2) / (f3 - f2);b3 = g2 - r3 * f2 ;[m , n ] = size(I);x2 = double(I); %变换矩阵中的每一个元素for i = 1 : mfor j = 1 : nf = x2( i , j);g(i , j ) = 0 ;if( f >= 0) & (f <= fl)g(i, j) = r1 * f + bl;elseif(f >= fl) & (f <= f2)g(i, j) = r2 * f + b2;elseif( f >= f2) & (f <= f3)g(i, j) = r3 * f + b3;endendendJ = mat2gray(g);figure, imshow(J);figure, imhist(J);%进行对比度调整K = imadjust(J); figure, imshow(K);figure, imhist(K);
结果:
灰度图像
直方图
增强图像
对比度调整图像
绘制彩色图像直方图
通常情况下绘制直方图我们都是使用imhist()
函数,但是当使用该函数绘制彩色图像的直方图时会报如下错误:
正常情况下,需要先将彩色图像转换为会灰度图像,在绘制直方图。代码如下:
I = imread('lena1.jpg') ; % 读取rgb图像I = rgb2gray(I);% 灰度化figure, imhist(I); % 显示图像的灰度值直方图
绘制彩色直方图方法一
方法:
提取RGB各分量,使用imhist提取各分量图像的直方图plot绘制各分量图像的直方图hold on 将直方图绘制在同一坐标系中
实现代码:
img=imread('lena1.jpg');R=img(:,:,1);G=img(:,:,2);B=img(:,:,3);histogramR=imhist(R);histogramG=imhist(G);histogramB=imhist(B);x=0:1:255;figure;plot(x,histogramR, 'r');hold onplot(x,histogramG, 'g');hold onplot(x,histogramB, 'b');
结果:
如果需要在直方图中填充颜色,可以使用fill()
函数,代码如下:
% R线填充颜色fill([x,fliplr(x)],[zeros(size(histogramR')),fliplr(histogramR')],'r');% G线填充颜色fill([x,fliplr(x)],[zeros(size(histogramG')),fliplr(histogramG')],'g');% B线填充颜色fill([x,fliplr(x)],[zeros(size(histogramB')),fliplr(histogramB')],'b');
绘制彩色直方图方法二
方法:
将每个颜色通道变为一列,将数据以柱状图形式画出,默认绘图的时候采用的颜色顺序为b,g,r,c,m,y,k
,跟图片的rgb
顺序正好相反,所以把图片列的顺序倒过来,让图片颜色通道跟绘制时的颜色一致
代码:
I=imread('lena1.jpg');siz=size(I);I1=reshape(I,siz(1)*siz(2),siz(3)); % 每个颜色通道变为一列I1=double(I1);[N,X]=hist(I1, [0:1:255]); % 如果需要小矩形宽一点,划分区域少点,可以把步长改大,比如0:5:255bar(X,N(:,[3 2 1])); % 柱形图,用N(:,[3 2 1])是因为默认绘图的时候采用的颜色顺序为b,g,r,c,m,y,k,跟图片的rgb顺序正好相反,所以把图片列的顺序倒过来,让图片颜色通道跟绘制时的颜色一致xlim([0 255])hold onplot(X,N(:,[3 2 1])); % 上边界轮廓hold off
结果:
将图像映射到HSV视觉接近的颜色空间中,计算统计在该空间的直方图
实现代码:
clearclcclose allrgb = imread('lena1.jpg');if size(rgb,3)~=3 error('3 components is needed for histogram'); end % globals H_BITS = 4; S_BITS = 2; V_BITS = 2; %rgb2hsv可用rgb2hsi代替hsv = uint8(255*rgb2hsv(rgb)); imgsize = size(hsv); % 去掉不相关的界限i0=round(0.05*imgsize(1)); i1=round(0.95*imgsize(1)); j0=round(0.05*imgsize(2)); j1=round(0.95*imgsize(2)); hsv = hsv(i0:i1, j0:j1, :); % 画直方图for i = 1 : 2^H_BITS for j = 1 : 2^S_BITS for k = 1 : 2^V_BITS colorhist(i,j,k) = sum(sum( ... bitshift(hsv(:,:,1),-(8-H_BITS))==i-1 &... bitshift(hsv(:,:,2),-(8-S_BITS))==j-1 &... bitshift(hsv(:,:,3),-(8-V_BITS))==k-1 )); end end end colorhist = reshape(colorhist, 1, 2^(H_BITS+S_BITS+V_BITS));% 归一化 colorhist = colorhist/sum(colorhist);figure,plot(colorhist)
结果:
绘制Lab颜色空间分量图和分量直方图
makecform和applycform函数
makecform创建一个颜色转换结构,函数makecform用于创建cform结构,而函数applycform使用cform结构转换颜色。
例如:以Lab彩色空间为基础创建在感觉上的一致彩色空间
这里设计在40和80之间的间隔相等的估值为1024的斜坡
L = linspace(40,80,1024); %构建线性斜坡radius = 70;theta = linspace(0,pi,1024);a = radius*cos(theta);b = radius*sin(theta);%设置平面中的彩色极角L=repmat(L,100,1);a=repmat(a,100,1);b=repmat(b,100,1);lab_scale = cat(3,L,a,b); %制作一幅彩色标尺图像cform = makecform('lab2srgb');rgb_scale = applycform(lab_scale,cform);imshow(rgb_scale) %显示彩色标尺
结果:
实现代码
img = imread('lena1.jpg');translate = makecform('srgb2lab');lab = applycform(img, translate);L = lab(:,:,1);a = lab(:,:,2);b = lab(:,:,3);figure(1);subplot(2,2,1);imshow(a);title('a分量图像');subplot(2,2,2);imshow(b);title('b分量图像');subplot(2,2,3);imhist(a);title('a分量直方图');subplot(2,2,4);imhist(b);title('b分量直方图');
结果: