Laplacian图像滤波和在MATLAB中对图像进行锐化

7
我正在尝试“翻译”Gonzalez和Woods(第2版)关于Laplacian滤波器的内容。
我已经读取了图像并创建了滤波器。然而,当我尝试显示结果时(通过减法,因为中心元素为负),我没有得到教科书中的图像。
我认为主要原因是“缩放”。但是,我不确定如何做到这一点。从我所理解的一些在线资源来看,缩放只是使值在0-255之间。从我的代码中,我看到值已经在该范围内。
我真的很感激任何提示。
下面是我使用的原始图像: enter image description here 以下是我的代码和锐化后的图像。
谢谢!
clc;
close all;
a = rgb2gray(imread('e:\moon.png'));
lap = [1 1 1; 1 -8 1; 1 1 1];
resp = uint8(filter2(lap, a, 'same'));
sharpened = imsubtract(a, resp);
figure; 
subplot(1,3,1);imshow(a); title('Original image');
subplot(1,3,2);imshow(resp); title('Laplacian filtered image');
subplot(1,3,3);imshow(sharpened); title('Sharpened image');

enter image description here


1
下次提问时,请确保使用“matlab”标记您的问题。这样可以增加您的问题曝光率。 - rayryeng
抱歉,rayryeng。实际上我以为我已经做了,但在看到你的消息后,我可能忘记了。再次感谢! - Alfian
完全没有问题。希望我的回答能对你有所帮助(如下)。 - rayryeng
1
非常感谢您编辑我的帖子@rayryeng。以后我会尽量遵循这个标准! - Alfian
1个回答

7
我有几个提示供您参考:
  1. 虽然这只是一点小事,但是 filter2 执行的是相关运算。实际上,在像素邻域和卷积核之间进行加权求和之前,您需要执行卷积操作,并将卷积核旋转180度。然而,由于卷积核是对称的,在这种情况下,卷积和相关运算会执行相同的操作
  2. 我建议您使用imfilter来实现过滤,因为您已经在使用图像处理工具箱中的方法。它比filter2conv2更快,并利用了Intel Integrated Performance Primitives
  3. 我强烈建议您首先以double精度执行所有操作,然后在完成后转换回uint8。使用im2double将图像(很可能是uint8)转换为double精度。在执行锐化时,这会保持精度,并且过早地将其转换为uint8,然后执行减法将导致意外的副作用。 uint8会限制负数或超过255的结果,这也可能是您未获得正确结果的原因之一。因此,将图像转换为double,过滤图像,通过Laplacian算子将图像与过滤结果相减以进行锐化,然后使用im2uint8将其转换回uint8

您还提供了一个链接,该链接是您试图模仿的流程:http://www.idlcoyote.com/ip_tips/sharpen.html

您的代码与链接之间的区别如下:

  1. 核心有一个正中心。因此,1s为负数,而中心为+8,您需要将过滤后的结果添加到原始图像中。
  2. 在链接中,它们对过滤响应进行了归一化,使最小值为0,最大值为1。
  3. 一旦您将过滤响应添加到原始图像上,您还需要将此结果归一化,使最小值为0,最大值为1。
  4. 您可以执行线性对比增强,使强度60成为新的最小值,强度200成为新的最大值。您可以使用imadjust来完成此操作。该函数接受一幅图像以及两个数组-第一个数组是输入最小和最大强度,第二个数组是最小和最大应映射到的位置。因此,我想将输入强度60映射到输出强度0,将输入强度200映射到输出强度255。但请确保指定的强度在0和1之间,因此您需要按文档中所述将每个量除以255。

因此:

clc;
close all;
a = im2double(imread('moon.png')); %// Read in your image
lap = [-1 -1 -1; -1 8 -1; -1 -1 -1]; %// Change - Centre is now positive
resp = imfilter(a, lap, 'conv'); %// Change

%// Change - Normalize the response image
minR = min(resp(:));
maxR = max(resp(:));
resp = (resp - minR) / (maxR - minR);

%// Change - Adding to original image now
sharpened = a + resp;

%// Change - Normalize the sharpened result
minA = min(sharpened(:));
maxA = max(sharpened(:));
sharpened = (sharpened - minA) / (maxA - minA);

%// Change - Perform linear contrast enhancement
sharpened = imadjust(sharpened, [60/255 200/255], [0 1]);

figure; 
subplot(1,3,1);imshow(a); title('Original image');
subplot(1,3,2);imshow(resp); title('Laplacian filtered image');
subplot(1,3,3);imshow(sharpened); title('Sharpened image');

我现在得到了这个数字...它似乎与链接中看到的数字相符:

enter image description here


非常感谢@rayryeng!!! 还要感谢您提供的有关不要过早转换为uint8的提示,这非常有用。很抱歉我没有包含图片,是我的错...我会尝试在我的图片上看看效果如何。非常感激! - Alfian
@Alfian 没问题 :) 许多新手在磨刀方面往往会忽略某些实现细节上的微妙之处...这也是Gonzalez和Woods所忽略的。我提供的建议来自多年的经验。祝你好运! - rayryeng
嗨@rayryeng...我试过了这段代码,但结果似乎不是那么令人满意。这还是因为缩放的原因吗?(试图阅读Gonzalez和Woods的最后一节3.4.1的结尾...但似乎不能弄清楚他的意思...)为您提供结果的URL以及原始图像以供参考。我将在以下评论中尝试粘贴代码:http://fsktm.upm.edu.my/~alfian/moon.png - 图像 http://fsktm.upm.edu.my/~alfian/results.png - Alfian
clc; close all;% 读入图像,转换为双精度,并定义拉普拉斯算子 a = im2double(rgb2gray(imread('e:\moon.png'))); lap = [1 1 1; 1 -8 1; 1 1 1];% 进行滤波操作 resp = imfilter(a, lap); % 没有指定 'conv' 是因为不需要% 从原始图像中减去滤波后的图像 sharpened = a - resp; % 应该与 imsubtract(a, resp) 相同? sharpened = im2uint8(sharpened);figure; subplot(1,3,1);imshow(a); title('原始图像'); subplot(1,3,2);imshow(sharpened); title('锐化后的图像'); subplot(1,3,3);imshow(resp); title('拉普拉斯算子'); - Alfian
主要是指这里的工作 - http://www.idlcoyote.com/ip_tips/sharpen.html(尽管作者使用了IDL) - Alfian
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接