Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab图像处理-直方图增强对比度_Matlab_Image Processing_Histogram - Fatal编程技术网

Matlab图像处理-直方图增强对比度

Matlab图像处理-直方图增强对比度,matlab,image-processing,histogram,Matlab,Image Processing,Histogram,我必须将灰度图像导入matlab,将它由无符号8位整数组成的像素转换为双精度,绘制直方图,最后使用转换提高图像质量: v'(x,y) = a(v(x,y)) + b out(x,y) = max_type*(in(x,y) - min(in)) / (max(in) - min(in)); 其中v(x,y)是点x,y处像素的值,v'(x,y)是像素的新值 我的主要问题是两个常量的值,a和b,我们必须为转换选择这两个常量。我的理解是,均衡直方图对于良好的图像是可取的。互联网上的其他代码涉及使

我必须将灰度图像导入matlab,将它由无符号8位整数组成的像素转换为双精度,绘制直方图,最后使用转换提高图像质量:

v'(x,y) = a(v(x,y)) + b 
out(x,y) = max_type*(in(x,y) - min(in)) / (max(in) - min(in));
其中
v(x,y)
是点
x,y
处像素的值,
v'(x,y)
是像素的新值

我的主要问题是两个常量的值,
a
b
,我们必须为转换选择这两个常量。我的理解是,均衡直方图对于良好的图像是可取的。互联网上的其他代码涉及使用内置的MATLAB
histeq
函数或计算概率密度。我在任何地方都没有找到为上面给出的转换选择常量的参考

我想知道是否有人对如何选择这些常数有什么建议或想法。我认为我的代码的其余部分做了它应该做的:

 image = imread('image.png');
 image_of_doubles = double(image);

 for i=1:1024
     for j=1:806
            pixel = image_of_doubles(i,j);
            pixel = 0.95*pixel + 5;
            image_of_doubles(i,j) = pixel;
    end
end

[n_elements,centers] = hist(image_of_doubles(:),20);
bar(centers,n_elements);

xlim([0 255]);

编辑:我还玩了一些不同的常量值。改变后的
a
常数似乎是拉伸直方图的常数;但是,这只适用于介于0.8-1.2之间的值(并且拉伸不够-仅在150-290范围内均衡直方图)。如果你使用
a
的值,比如说0.5,直方图被分成两个斑点,其中很多像素的强度大约为4或5;同样,一点也不均衡。

您感兴趣的操作称为线性对比度拉伸。基本上,您希望将每个强度乘以一些增益,然后将强度移动一些数字,以便可以操纵直方图的动态范围。这与
histeq
或使用图像的概率密度函数(直方图均衡化的前身)来增强图像是不同的。直方图均衡化寻求使图像直方图平坦化,以便在图像中遇到的强度或多或少相等。如果您想对该主题进行更权威的解释,请参阅我关于直方图均衡化工作原理的回答:


在任何情况下,选择
a
b
的值都高度依赖于图像。但是,如果您希望这是自适应的,我可以建议您使用minmax规范化。基本上,您采用直方图并线性映射强度,以便将最低输入强度映射为0,将最高输入强度映射为图像关联数据类型的最高值。例如,如果图像是
uint8
,这意味着最高值映射到255

执行最小/最大规格化非常容易。这只是以下转换:

v'(x,y) = a(v(x,y)) + b 
out(x,y) = max_type*(in(x,y) - min(in)) / (max(in) - min(in));
in
out
是输入和输出图像
min(in)
max(in)
是输入图像的总体最小值和最大值
max_type
是与输入图像类型关联的最大值

对于输入图像的每个位置
(x,y)
,替换一个输入图像强度,并运行上述等式以获得输出。您可以说服自己,将
min(in)
max(in)
替换为
in(x,y)
将分别得到0和
max\u类型
,其他所有内容都是线性缩放的

现在,通过一些代数运算,你可以得到你在问题陈述中提到的形式
out(x,y)=a*in(x,y)+b
。具体地说:

out(x,y) = max_type*(in(x,y) - min(in)) / (max(in) - min(in));
out(x,y) = (max_type*in(x,y)/(max(in) - min(in)) - (max_type*min(in)) / (max(in) - min(in)) // Distributing max_type in the summation
out(x,y) = (max_type/(max(in) - min(in)))*in(x,y) - (max_type*min(in))/(max(in) - min(in)) // Re-arranging first term

out(x,y) = a*in(x,y) + b
a
只是
(max_type/(max(in)-min(in))
b
(max_type*min(in))/(max(in)-min(in))

你可以制作这些代码> < <代码> >代码> b>代码>并运行你的代码。BTW,如果我可以建议一些东西,请考虑矢量化你的代码。你可以很容易地使用这个等式,同时对整个图像数据进行操作,而不是对图像中的每个值进行循环。

简单地说,您的代码现在如下所示:

image = imread('image.png');
image_of_doubles = 0.95*double(image) + 5; %// New

[n_elements,centers] = hist(image_of_doubles(:),20);
bar(centers,n_elements);
……不是更简单吗

现在,修改您的代码,使新常数
a
b
按照我们讨论的方式计算:

image = imread('image.png');

%// New - get maximum value for image type
max_type = double(intmax(class(image)));

%// Calculate a and b
min_val = double(min(image(:)));
max_val = double(max(image(:)));
a = max_type / (max_val - min_val);
b = -(max_type*min_val) / (max_val - min_val);

%// Compute transformation
image_of_doubles = a*double(image) + b;

%// Plot the histogram - before and after
figure;
subplot(2,1,1);
[n_elements1,centers1] = hist(double(image(:)),20);
bar(centers1,n_elements1);
%// Change
xlim([0 max_type]);

subplot(2,1,2);
[n_elements2,centers2] = hist(image_of_doubles(:),20);
bar(centers2,n_elements2);
%// Change
xlim([0 max_type]);

%// New - show both images
figure; subplot(1,2,1);
imshow(image);
subplot(1,2,2);
imshow(image_of_doubles,[]);
非常重要的是将最大整数转换为
double
,因为返回的不仅是整数,而且是整数转换为该数据类型。我还随意更改了代码,以便我们可以显示转换前后的直方图,以及im年龄在你改变它之前和之后都是一样的


作为查看此工作的示例,让我们使用图像处理工具箱中的
pout.tif
图像

image = imread('image.png');
image_of_doubles = 0.95*double(image) + 5; %// New

[n_elements,centers] = hist(image_of_doubles(:),20);
bar(centers,n_elements);

您可以肯定地看到,这需要一些图像对比度增强操作,因为强度的动态范围非常有限。 这看起来像是被洗劫一空

使用这个作为图像,这是直方图在前后的样子

我们当然可以看到直方图被拉伸。现在这是图像的样子:

你肯定可以看到更多细节,即使它更暗。这告诉你,简单的线性缩放是不够的。你可能想实际使用直方图均衡化,或使用伽马定律或幂律变换



希望这足以让您开始。祝您好运!

您感兴趣的操作称为线性对比度拉伸。基本上,您希望将每个强度乘以一些增益,然后将强度移动一些数字,以便可以操纵直方图的动态范围。这是不是