Image 在一个图像上画一条水平线,其行对应于最大数量的暗像素

Image 在一个图像上画一条水平线,其行对应于最大数量的暗像素,image,matlab,image-processing,line,Image,Matlab,Image Processing,Line,我希望在MATLAB中的二值图像上画一条水平线,该图像具有最大数量的黑色像素。例如,在这个词中: 。。。我必须用大多数像素来识别水平线 我知道我可以打开二进制图像变量编辑器,并绘制一行,其中有最大的零,但这似乎不起作用 我必须对这个词做一个基线如下: 。。。作为输出,假设最大像素位于我画线的位置。纯粹按照您的定义,您需要计算出黑色像素数量最大的行。只需对每行的所有列求和,并找到最大值。完成后,找到计数最大的行,并将该行设置为红色 我想到了这样的事情。我将直接从StackOverflow读取您

我希望在MATLAB中的二值图像上画一条水平线,该图像具有最大数量的黑色像素。例如,在这个词中:

。。。我必须用大多数像素来识别水平线

我知道我可以打开二进制图像变量编辑器,并绘制一行,其中有最大的零,但这似乎不起作用

我必须对这个词做一个基线如下:


。。。作为输出,假设最大像素位于我画线的位置。

纯粹按照您的定义,您需要计算出黑色像素数量最大的行。只需对每行的所有列求和,并找到最大值。完成后,找到计数最大的行,并将该行设置为红色

我想到了这样的事情。我将直接从StackOverflow读取您的图像,并使用图像处理工具箱帮助我进行以下分析:

%// Read image from SO
im = imread('http://s15.postimg.org/cwg2sxnwr/mathworksss.png');

%// Keep a copy of a binary version
im_bw = im2bw(im);

%// Sum over all of the columns and look for dark pixels
row_sums = sum(~im_bw, 2);

%// Find row with max sum
[~,row_max] = max(row_sums);

%// Draw a red line through the original image as it's in RGB
im(row_max,:,1) = 255;
im(row_max,:,2:3) = 0;

%// Show the image
imshow(im);
第一个图像直接从SO读取图像,并将其放入MATLAB工作区。下一行将图像设置为二进制阈值,以便于分析。我们还保留了原始图像的副本,以便我们可以用红色标记基线。之后的下一行分别对每行的每一列进行使用和求和,并将黑色像素相加。这是通过反转二值图像来实现的,这样暗像素变亮以便于求和。然后我们使用计算出最大和的行,这是通过查看
max
的第二个输出来完成的。一旦找到这个位置,我们就使用这一行并将这一行中的所有像素设置为红色,或者
RGB=(255,0,0)

我得到这个图像:

现在,上面的代码从左到右画了一条线。如果你想限制这一点,只在有文本的地方画一条红线,也许可以找到最左边和最右边的黑色像素,给它们增加一点喘息的空间,然后画一条线穿过。。。。我想到了这样的事情:

%// Read image from SO
im = imread('http://s15.postimg.org/cwg2sxnwr/mathworksss.png');

%// Keep a copy of a binary version
im_bw = im2bw(im);

%// Sum over all of the columns and look for dark pixels
row_sums = sum(~im_bw, 2);

%// Find row with max sum
[~,row_max] = max(row_sums);

%// Find left most and right most black columns
[~,left_most] = find(~im_bw,1,'first');
[~,right_most] = find(~im_bw,1,'last');

%// Buffer for drawing the line before the first and after the last column
buf = 20;

%// Draw the line
im(row_max,left_most-buf:right_most+buf,1) = 255;
im(row_max,left_most-buf:right_most+buf,2:3) = 0;

%// Show the image
imshow(im);
%// Read image from SO
im = imread('http://s15.postimg.org/cwg2sxnwr/mathworksss.png');

%// Keep a copy of a binary version - also invert for ease
im_bw = ~im2bw(im);

%// Slightly erode the text
im_bw = imerode(im_bw, strel('square', 3));

%// Sum over all of the columns and look for dark pixels
row_sums = sum(im_bw, 2);

%// Sort the column sums in descending order and figure out the two highest sums
[~,ind_sort] = sort(row_sums,'descend');

%// First highest sum is the bottom - mark as red
red_row1 = ind_sort(1);

%// Second highest sum is the middle - mark as red too
red_row2 = ind_sort(2);

%// Find left most and right most black columns
[~,left_most] = find(im_bw,1,'first');
[~,right_most] = find(im_bw,1,'last');

%// Buffer for drawing the line before the first and after the last column
buf = 20;

%// Draw the two red lines
im(red_row1,left_most-buf:right_most+buf,1) = 255;
im(red_row1,left_most-buf:right_most+buf,2:3) = 0;

im(red_row2,left_most-buf:right_most+buf,1) = 255;
im(red_row2,left_most-buf:right_most+buf,2:3) = 0;

%// Show the image
imshow(im);
如您所见,大多数代码保持不变(在图像中读取、阈值化、列求和和和
max
),但在接近结束时,我使用查找关于列的黑色像素的第一个和最后一个实例。然后,我将这些列与前面找到的最大行相同,然后减去最左边的黑色列像素位置,再将最右边的黑色列像素位置加上缓冲量(我在这里选择了20),然后将该区域内的像素行设置为红色

我们得到:


现在,您希望找到具有第二高总和的行,并通过该行绘制另一条线。这样做还不错。然而,这将需要一些后处理,因为每个字符的外边缘不是单个像素厚。。。所以第二高的总和可能仍然会给你一行,在第一个最大值附近。因此,我建议稍微缩小文本,然后再次应用行和逻辑。你可以用一个小的结构元素。。。比如说,一个3x3的正方形。这可以通过用于侵蚀和指定方形结构元素来完成

您可以将行和逻辑应用于此新图像,但随后使用这些结果并在原始图像上绘制。您不想在这个新图像上操作,因为它看起来像是文本的某些区域只有一个像素厚,这些区域在腐蚀后将被消除

我想到了这样的事情:

%// Read image from SO
im = imread('http://s15.postimg.org/cwg2sxnwr/mathworksss.png');

%// Keep a copy of a binary version
im_bw = im2bw(im);

%// Sum over all of the columns and look for dark pixels
row_sums = sum(~im_bw, 2);

%// Find row with max sum
[~,row_max] = max(row_sums);

%// Find left most and right most black columns
[~,left_most] = find(~im_bw,1,'first');
[~,right_most] = find(~im_bw,1,'last');

%// Buffer for drawing the line before the first and after the last column
buf = 20;

%// Draw the line
im(row_max,left_most-buf:right_most+buf,1) = 255;
im(row_max,left_most-buf:right_most+buf,2:3) = 0;

%// Show the image
imshow(im);
%// Read image from SO
im = imread('http://s15.postimg.org/cwg2sxnwr/mathworksss.png');

%// Keep a copy of a binary version - also invert for ease
im_bw = ~im2bw(im);

%// Slightly erode the text
im_bw = imerode(im_bw, strel('square', 3));

%// Sum over all of the columns and look for dark pixels
row_sums = sum(im_bw, 2);

%// Sort the column sums in descending order and figure out the two highest sums
[~,ind_sort] = sort(row_sums,'descend');

%// First highest sum is the bottom - mark as red
red_row1 = ind_sort(1);

%// Second highest sum is the middle - mark as red too
red_row2 = ind_sort(2);

%// Find left most and right most black columns
[~,left_most] = find(im_bw,1,'first');
[~,right_most] = find(im_bw,1,'last');

%// Buffer for drawing the line before the first and after the last column
buf = 20;

%// Draw the two red lines
im(red_row1,left_most-buf:right_most+buf,1) = 255;
im(red_row1,left_most-buf:right_most+buf,2:3) = 0;

im(red_row2,left_most-buf:right_most+buf,1) = 255;
im(red_row2,left_most-buf:right_most+buf,2:3) = 0;

%// Show the image
imshow(im);
正如你所看到的,大多数逻辑是相同的。我唯一真正改变的是,我腐蚀了图像,按降序对行和进行排序,并提取了前两个最高的位置。然后我重复了逻辑,在这一行中画了一条线,但是我们现在有两行,而不是一行


我们得到:


非常感谢Rayryreng,这非常有帮助。谢谢你简单而优雅的回答。没问题。如果你不再需要帮助,请考虑接受我的回答。这可以通过点击我文章顶部左边的复选标记图标来实现,就在向上和向下投票箭头的下方。祝你好运这样做了,你能告诉我如何获得暗像素的第二个最大值并绘制一条(唯一的)线吗?同样,Ray,你有一个非常令人印象深刻的轮廓,我想为你的帮助添加一个提示。:)虽然不需要提示,但还是很感激:)我很快就会更新。给我一个小时或更长的时间so@tarabhargava-看一看。希望这就是你想要的!也谢谢你的提示。。。如果您决定这样做:)