以前的答案提出了一些有趣的数学方法来删除基线。但我想这个问题是您previousquestions 的延续,而“图像”是指您的数据实际上是图像。如果是这样,您可以使用图像处理技术来找到峰值并将其周围的区域变平。
1.预处理
在应用不同的过滤器之前,最好将像素值映射到一定范围内。这样我们可以更好地控制过滤器所需参数的值。
首先,我们将图像数据类型转换为双精度,用于像素值为整数的情况。
I = double(I);
然后,通过应用平均滤波器,我们减少了图像中的噪声。
SI = imfilter(I,fspecial('disk',40),'replicate');
最后,我们将所有像素的值映射到从零到一的范围内。
NI = SI-min(SI(:));
NI = NI/max(NI(:));
2。细分
准备好图像后,我们可以识别每个峰所在的部分。为此,我们首先计算图像梯度。
G = imgradient(NI,'sobel');
然后我们识别出图像中斜率较高的部分。由于“高坡度”在不同的图像中可能有不同的含义,因此我们使用graythresh函数将图像分为低坡度和高坡度两部分。
SA = im2bw(G, graythresh(G));
上一步的分割区域可能有几个问题:
- 被归类为高坡度区域一部分的小连续分量可能仅由噪声引起。因此,应移除面积小于阈值的组件。
- 由于斜率在峰的顶部达到零,因此在上一步中发现的组件中可能存在孔。
- 沿边界的峰的斜率不一定相同,发现的区域可能具有不规则的形状。一种解决方案是通过将它们替换为凸形大厅来扩展它们。
[L, nPeaks] = bwlabel(SA);
minArea = 0.03*numel(I);
P = false(size(I));
for i=1:nPeaks
P_i = bwconvhull(L==i);
area = sum(P_i(:));
if (area>minArea)
P = P|P_i;
end
end
3。删除基线
在上一步计算的P 矩阵在峰值处包含值 1,在其他区域包含值为零。到目前为止,我们可以通过在主图像中乘以这个矩阵来删除基线。但最好先软化发现区域的边缘,以免峰的边缘突然降为零。
FC = imfilter(double(P),fspecial('disk',50),'replicate');
F = I.*FC;
您还可以移动边缘图像最少的峰。
E = bwmorph(P, 'remove');
o = min(I(E));
T = max(0, F-o);
上述所有步骤都在一个函数中
function [hlink, T] = removeBaseline(I, demoSteps)
% converting image to double
I = double(I);
% smoothing image to reduce noise
SI = imfilter(I,fspecial('disk',40),'replicate');
% normalizing image in [0..1] range
NI = SI-min(SI(:));
NI = NI/max(NI(:));
% computng image gradient
G = imgradient(NI,'sobel');
% finding steep areas of the image
SA = im2bw(G, graythresh(G));
% segmenting image to find regions covered by each peak
[L, nPeaks] = bwlabel(SA);
% defining a threshold for minimum area covered by each peak
minArea = 0.03*numel(I);
% filling each of the regions, and eliminating small ones
P = false(size(I));
for i=1:nPeaks
% finding convex hull of the region
P_i = bwconvhull(L==i);
% computing area of the filled region
area = sum(P_i(:));
if (area>minArea)
% adding the region to peaks mask
P = P|P_i;
end
end
% applying the average filter on peaks mask to compute coefficients
FC = imfilter(double(P),fspecial('disk',50),'replicate');
% Removing baseline by multiplying the coefficients
F = I.*FC;
% finding edge of peaks
E = bwmorph(P, 'remove');
% finding minimum value of edges in the image
o = min(I(E));
% shifting the flattened image
T = max(0, F-o);
if demoSteps
figure
subplot 231, imshow(I, []); title('Original Image');
subplot 232, imshow(SI, []); title('Smoothed Image');
subplot 233, imshow(NI); title('Normalized in [0..1]');
subplot 234, imshow(G, []); title('Gradient of Image');
subplot 235, imshow(SA); title('Steep Areas');
subplot 236, imshow(P); title('Peaks');
figure;
subplot 221, imshow(FC); title('Flattening Coefficients');
subplot 222, imshow(F, []); title('Base Line Removed');
subplot 223, imshow(E); title('Peak Edge');
subplot 224, imshow(T, []); title('Final Result');
figure
h1 = subplot(1, 3, 1);
surf(I, 'edgecolor', 'none'); hold on;
contour3(I, 'k', 'levellist', o, 'linewidth', 2)
h2 = subplot(1, 3, 2);
surf(F, 'edgecolor', 'none'); hold on;
contour3(F, 'k', 'levellist', o, 'linewidth', 2)
h3 = subplot(1, 3, 3);
surf(T, 'edgecolor', 'none');
hlink = linkprop([h1 h2 h3],{'CameraPosition','CameraUpVector', 'xlim', 'ylim', 'zlim', 'clim'});
set(h1, 'zlim', [0 max(I(:))])
set(h1, 'ylim', [0 size(I, 1)])
set(h1, 'xlim', [0 size(I, 2)])
set(h1, 'clim', [0 max(I(:))])
end
end
使用包含多个噪声峰值的图像执行该函数:
close all; clc; clear variables;
I = abs(peaks(1200));
J1 = imnoise(ones(size(I))*0.5,'salt & pepper', 0.05);
J1 = imfilter(double(J1),fspecial('disk',20),'replicate');
[X, Y] = meshgrid(linspace(0, 1, size(I, 2)), linspace(0, 1, size(I, 1)));
J2 = X.^3+Y.^2;
I = max(I, 2*J2) + 5*J1;
lp3 = removeBaseline(I, true);
调用从文件中读取图像的函数:
I = rgb2gray(imread('imagefile.jpg'));
[~, I2] = removeBaseline(I, true);
先前问题中提供的图像的结果: