去除有机分子图中不需要的字符
Removing unwanted characters in an organic molecule diagram
我有这张图片:
我想删除图像中不构成有机分子结构的所有部分。所以在这个特定的图像中,我想删除 Process A
和 line below it
。我尝试使用 bwlabel
来获取连接的组件,但结构本身并没有形成一个单独的组件。因此,无法通过该方法移除。知道我该如何解决这个问题吗?
假设图像标题在 space 中与 "actual image" 足够远:
通过模糊图像构建斑点,找到连接的组件,采用 upper/bigger 一个(或其他一些取决于您的数据的启发式)。所以,在使用连通分量算法之前,进行预处理:
- Gauss/Median 过滤器(如果需要)和边缘检测。
- 二值化
- 形态学操作(腐蚀、膨胀)
- 使用启发式方法提取 Blob (size/shape/position)。
而 4. 是连接组件的替代品(这不是强制性的)。您可以在关键字 blob extraction
或 text extraction
下搜索其他方法。这是您将要执行的操作的粗略概述 "in the general case"。哪些步骤带来最佳解决方案取决于您的数据,因此您需要进行一些试验。
根据您的喜好,有两种方法可以解决这个问题。
方法#1 - 使用bwareaopen
执行此操作的一种廉价方法是反转图像,使对象像素为白色而不是黑色,然后对图像执行形态学闭合并移除那些低于一定数量的区域。关闭会将断开连接的区域连接在一起,并利用连接 "structure" 会生成一个面积较大的区域,您可以按每个区域的面积设置阈值并消除低于一定数量的区域。
然后,您只需对反转图像和闭合结果执行逻辑运算 AND
,然后重新反转该中间结果,即可恢复原始图像。这样做的效果是我们只保留属于原始图像的像素,因为关闭操作人为地创建了对象像素。具体来说,结构附近区域的连接将创建新的对象像素,因此执行 AND
将确保那些与原始像素不相同的像素被删除。由于这是在原始结果的相反方向上执行的,因此重新反转会使您回到对象像素的原始域是黑色而不是白色。
像这样:
%// Read in image from Whosebug
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
%// Remove regions whose areas fall below 10000 pixels
out = bwareaopen(out, 10000);
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
我们得到这张图片:
备注
- 函数
imclose
will perform the morphological closing for you with a structuring element defined by strel
。我使用了一个 50 x 50 的正方形来确保我们有足够大的 window 来将相邻的对象像素连接在一起。
- 函数
bwareaopen
接受二值图像并删除像素面积低于一定数量的区域。关闭后,您将有两个连接的区域 - 带有结构的图像顶部和带有文本的底部。通过实验,10000像素去除了底部区域。
方法#2 - 使用regionprops
与方法 #1 相关,执行此操作并与阈值无关的另一种方法是遵循您最初的想法。执行闭合操作,然后评估每个连接区域的面积和 select 面积最大的区域。我推荐的是在这种情况下使用 regionprops
,这是一个专门用于分析不同图像区域特征的函数。输出将是一个包含 N
个元素的结构,其中 N
是在图像中找到的唯一和连接对象的总数,每个结构都包含您想要在图像中测量的属性字段。在您的情况下,指定 'Area'
和 'PixelIdxList'
属性,其中包含每个区域的面积和列主像素位置。
你会找到最大的整体面积并使用相应的像素位置并设置一个你合乎逻辑的输出地图 AND
。
像这样:
%// Read in image from Whosebug
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
s = regionprops(out, 'Area', 'PixelIdxList'); %// Apply regionprops
%// Find the region with the max area
[~,id] = max([s.Area]);
%// Create an output mask with the largest area
%// Make logical
out = false(size(im));
%// Set pixels from largest area
out(s(id).PixelIdxList) = true;
%// Rest of the logic from before
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
您应该得到与第一种方法完全相同的结果。
我有这张图片:
我想删除图像中不构成有机分子结构的所有部分。所以在这个特定的图像中,我想删除 Process A
和 line below it
。我尝试使用 bwlabel
来获取连接的组件,但结构本身并没有形成一个单独的组件。因此,无法通过该方法移除。知道我该如何解决这个问题吗?
假设图像标题在 space 中与 "actual image" 足够远:
通过模糊图像构建斑点,找到连接的组件,采用 upper/bigger 一个(或其他一些取决于您的数据的启发式)。所以,在使用连通分量算法之前,进行预处理:
- Gauss/Median 过滤器(如果需要)和边缘检测。
- 二值化
- 形态学操作(腐蚀、膨胀)
- 使用启发式方法提取 Blob (size/shape/position)。
而 4. 是连接组件的替代品(这不是强制性的)。您可以在关键字 blob extraction
或 text extraction
下搜索其他方法。这是您将要执行的操作的粗略概述 "in the general case"。哪些步骤带来最佳解决方案取决于您的数据,因此您需要进行一些试验。
根据您的喜好,有两种方法可以解决这个问题。
方法#1 - 使用bwareaopen
执行此操作的一种廉价方法是反转图像,使对象像素为白色而不是黑色,然后对图像执行形态学闭合并移除那些低于一定数量的区域。关闭会将断开连接的区域连接在一起,并利用连接 "structure" 会生成一个面积较大的区域,您可以按每个区域的面积设置阈值并消除低于一定数量的区域。
然后,您只需对反转图像和闭合结果执行逻辑运算 AND
,然后重新反转该中间结果,即可恢复原始图像。这样做的效果是我们只保留属于原始图像的像素,因为关闭操作人为地创建了对象像素。具体来说,结构附近区域的连接将创建新的对象像素,因此执行 AND
将确保那些与原始像素不相同的像素被删除。由于这是在原始结果的相反方向上执行的,因此重新反转会使您回到对象像素的原始域是黑色而不是白色。
像这样:
%// Read in image from Whosebug
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
%// Remove regions whose areas fall below 10000 pixels
out = bwareaopen(out, 10000);
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
我们得到这张图片:
备注
- 函数
imclose
will perform the morphological closing for you with a structuring element defined bystrel
。我使用了一个 50 x 50 的正方形来确保我们有足够大的 window 来将相邻的对象像素连接在一起。 - 函数
bwareaopen
接受二值图像并删除像素面积低于一定数量的区域。关闭后,您将有两个连接的区域 - 带有结构的图像顶部和带有文本的底部。通过实验,10000像素去除了底部区域。
方法#2 - 使用regionprops
与方法 #1 相关,执行此操作并与阈值无关的另一种方法是遵循您最初的想法。执行闭合操作,然后评估每个连接区域的面积和 select 面积最大的区域。我推荐的是在这种情况下使用 regionprops
,这是一个专门用于分析不同图像区域特征的函数。输出将是一个包含 N
个元素的结构,其中 N
是在图像中找到的唯一和连接对象的总数,每个结构都包含您想要在图像中测量的属性字段。在您的情况下,指定 'Area'
和 'PixelIdxList'
属性,其中包含每个区域的面积和列主像素位置。
你会找到最大的整体面积并使用相应的像素位置并设置一个你合乎逻辑的输出地图 AND
。
像这样:
%// Read in image from Whosebug
im = imread('http://i.stack.imgur.com/A7iT7.png');
%// Invert image
im = ~im;
%// Define 50 x 50 structuring element and close the image
se = strel('square', 50);
out = imclose(im, se);
s = regionprops(out, 'Area', 'PixelIdxList'); %// Apply regionprops
%// Find the region with the max area
[~,id] = max([s.Area]);
%// Create an output mask with the largest area
%// Make logical
out = false(size(im));
%// Set pixels from largest area
out(s(id).PixelIdxList) = true;
%// Rest of the logic from before
%// Remove out extraneous closing areas by ANDing with inverted image
%// then reinvert to bring back to original label scheme
out = ~(im & out);
%// Show the image
imshow(out);
您应该得到与第一种方法完全相同的结果。