如何根据矩阵值检测图像的一部分?

How to detect a portion of an image based upon the matrix values?

我在 Matlab(版本 R 2016b)中有一个简单的 pcolor 图,我已经上传了它,如下图所示。我只需要获取从最左角的中间延伸到最右角的 蓝色斜线 ,而无需对矩阵值进行硬编码。

例如:可以看到所需的斜率线的值大约在20[=33之间=] 到 45 从 pcolor 图。 (仅通过查看图表粗略猜测)

我在包含绘制值的 matrix named Slant 上应用以下代码。

load('Slant.mat');
Slant(Slant<20|Slant>50)=0;
pcolor(Slant); colormap(jet); shading interp; colorbar;

如您所见,我硬编码了我不想要的值。有什么方法可以检测某些矩阵值,同时使其余矩阵值等于零吗?

我使用了另一个小算法,从矩阵中取最大值的一半并将其设置为零。但这不适用于其他图像。

[maxvalue, row] = max(Slant);
max_m=max(maxvalue);
Slant(Slant>max_m/2)=0;
pcolor(Slant); colormap(jet); shading interp; colorbar;

思路:使用霍夫变换:

首先最好创建一个只有我们感兴趣的行和列的新矩阵。

为了应用 matlab 的内置 hough 我们必须创建一个二值图像:由于直线的值总是比其余的低,我们可以例如确定图片中亮度的最低四分位数(使用 quantile,并将这些设置为白色,其他所有设置为黑色。

然后为了找到直线,我们可以直接在那个黑白图像上使用hough

这是另一个建议:

  1. 删除所有背景。
  2. 假设此 "line" 导致数据呈双峰分布(删除零后),找到较低的模式。
  3. 假设线的值总是低于背景,应用逻辑掩码将所有高于最小值 + 2nd_mode 的值设置为零,如下图所示(红色圆圈):

这是它的工作原理:

A = Slant(any(Slant,2),:); % save in A only the nonzero data

现在我们 A 看起来像这样:

[y,x] = findpeaks(histcounts(A)); % find all the mode in the histogram of A
sorted_x = sortrows([x.' y.'],-2); % sort them by their hight in decendet order
mA = A<min(A(:))+sorted_x(2,1); % mask all values above the second mode
result = A.*mA; % apply the mask on A

我们得到 result:


生成的行中有一些空洞,因此您可能希望从结果中插入整行。这可以通过对索引进行简单的数学运算来完成:

[y1,x1] = find(mA,1); % find the first nonzero row 
[y2,x2] = find(mA,1,'last'); % find the last nonzero row
m = (y1-y2)/(x1-x2); % the line slope
n = y1-m*x1; % the intercept
f_line = @(x) m.*x+n; % the line function

所以我们得到一个像这样的线函数f_line(下面的红色部分):

现在我们想让这条线更粗,就像数据中的线一样,所以我们采用粗细的模式(通过计算每一列中的值,你可能想取 max 代替) , 并且 'expand' 这条线向两边减半:

thick = mode(sum(mA)); % mode thickness of the line
tmp = (1:thick)-ceil(thick/2); % helper vector for expanding
rows = bsxfun(@plus,tmp.',floor(f_line(1:size(A,2)))); % all the rows for each coloumn
rows(rows<1) = 1; % make sure to not get out of range
rows(rows>size(A,1)) = size(A,1); % make sure to not get out of range
inds = sub2ind(size(A),rows,repmat(1:size(A,2),thick,1)); % convert to linear indecies
mA(inds) = 1; % add the interpolation to the mask
result = A.*mA; % apply the mask on A

现在 result 看起来像这样: