以下是我正在使用的图片类型:
您可以使用以下代码查看粉红色的线条:
A=imread('b20.bmp');
AR=A(:,:,1);
[rows, columns] = size(AR);
y1 = 200;
y2 = 315;
row1 = AR(y1, :); % Extract this line of gray levels from the image.
figure, image(AR,'CDataMapping','scaled'); colormap('gray');
title('Input Image in Grayscale')
hold on;
plot([0, columns], [y2, y2], 'm');
我希望从突出显示的行(315)向上扫描到图像的第一行以尝试检测暗区域,一旦检测到该区域,我想要在黑暗的中点绘制另一条线区域,类似于第一个(整个图像)。
我希望这样做的原因是一旦检测到2个区域的中点我想从2条线获得统计信息,例如标准偏差和平均值,试图处理2个区段给出周围的行或段是整体平均值。
答案 0 :(得分:0)
Jonas几乎告诉你如何解决它。但是,因为我喜欢玩图像,所以我决定写一个答案。我要做的是提取出从第1行到第315行的子图像,然后我将独立地找到每个行的平均值。这将给你315元素向量...然后从这个结果,无论位置给我们一个巨大的尖峰,这可能是细分开始的地方。这是一个人为的例子。我尝试用一些最小的代码重新创建你的。我将创建一个黑白图像,其中上半部分是黑色,下半部分是白色。一旦我这样做,我将添加一些随机高斯噪声,振幅为10,平均值为0,标准偏差为1.此后,我将对图像进行标准化,使其在[0,1]
之间。动态范围:
%// Set random seed generator
rng(123);
%// Create black and white image. First 250 rows is black, next 250 rows is gray
im = [zeros(250, 256); 128*ones(250,256)];
%// Add Gaussian random noise of amplitude 10, mean 0, std.dev = 1
im_noise = im + 10*randn(size(im));
%// Normalize image so it's between [0,1]
AR = (im_noise - min(im_noise(:))) / (max(im_noise(:)) - min(im_noise(:)));
我已将嘈杂的图像存储在AR
中,以便您可以复制并粘贴我接下来要尝试的内容。为了完整起见,这就是图像的样子:
现在这里是神奇的开始。让我们找到第1行和第315行之间每行的平均值:
avgs = mean(AR(1:315,:), 2);
2
参数表示沿列操作,这意味着我们将找到每行的平均值。这意味着我们将得到一个315元素向量,其中每个元素是一行的平均值 ....所以第一个元素是第1行的平均值,第二个元素是第2行的平均值等等。如果我们在正常图上绘制这些平均值,其中行数是横轴,平均强度是纵轴,这就是我们得到的结果:
plot(1:315, avgs);
正如你所看到的,在250处有一个明显的尖峰,在我设计的图像中,在第250行是我出现灰色方块的地方。我们可以通过diff
结合max
确定 出现,我们计算数组中元素之间的成对距离。 diff
适用于第一个输出是第二个元素减去第一个元素,然后第二个元素是第三个元素减去第二个元素,依此类推。在这种情况下,因为我们正在从低到高转换,这意味着无论位置给我们带来最大的差异意味着我们从右边(或边缘的最高值)向左(或最低值)取一个数字因此,我们找到成对距离并确定我们有一个最高可能的成对距离的点。所以,做一些像:
[~,ind] = max(diff(avgs));
这里max
的好处是,如果在共享相同最大值的数据中看到多个值,我们只返回第一个发生价值。这很好,因为一旦我们检测到情节中的峰值,我们会立即找到这个结果。如果您正确执行此操作,则ind
应为250.
我要注意的一点是,上面的语法假设您正在从黑色过渡到白色。如果您有相反行为,您可能要查看使用min
,或者如果您希望这与您遇到的渐变类型无关,请使用{{1与max
结合使用。这样,当我们找到最大的差异时,如果它从黑色变为白色,则它将是一个大的正数,如果从白色变为黑色,它将是一个大的负数。如果我们用abs
删除所有负值,这意味着无论符号是什么,我们都会将其视为一个大的正值,因此无论如何我们都应该能够检测到跳跃。因此,你应该做的是:
abs
现在,您所要做的就是显示此图像,然后绘制此位置所在的行:
[~,ind] = max(abs(diff(avgs)));
我已经将线条的粗细做了2个像素,这样你就可以清楚地看到这条线了,我已经把它做成了红色。这就是我们得到的:
因此,如果您想将其复制并粘贴到MATLAB中以供运行,请输入以下代码:
figure;
imshow(AR);
hold on;
plot([1 size(AR,2)], [ind ind], 'r', 'LineWidth', 2);