【问题标题】:Separating the components of an image and saving them as new image分离图像的组件并将它们保存为新图像
【发布时间】:2018-05-09 20:35:29
【问题描述】:

我有一张黑白图像,如下所示:

我想分离这张图片的白色部分,然后将它们保存为单独的图片。此图像有四个白色部分。我想将它们分开并保存四个新图像;每个都包含图像的白色部分。

为此,我编写了以下代码:

BW=imread('img11_Inp.jpg');
imshow(BW);
BW=imbinarize(BW);

[L, num] = bwlabel(BW);
for k = 1 : num
    thisBlob = ismember(L, k);
    h = int2str(k);
    filname = strcat(h,'_Out.jpg');
    imwrite(thisBlob,filname);
    figure
    imshow(thisBlob, []);
end

问题

此代码将白色部分分开并保存,但新图像中保存的白色部分的大小与原始图像中的相同。请参阅下面的输出图像:

输出图片

所需的输出图像

我希望输出图像包含增大的原始图像白色部分的大小。以下图片是我想要的:

问题

如何修改上面的代码,才能得到想要的输出图片?

【问题讨论】:

  • 您想在图像中保留多少黑色?
  • 与所需输出图像中显示的一样多
  • 以精确的数字/像素定义它。如果白色在原始图像的边缘怎么办?你还想在它的侧面涂上黑色吗?
  • 没有固定数量的黑色像素要显示在白色部分周围。输出图像中的黑色像素应尽可能多,以便在图像的白色部分周围可以看到一些黑色。不,如果白色部分位于原始图像的边缘,我不想在侧面显示黑色。

标签: image matlab image-processing crop


【解决方案1】:

步骤:

  1. 找到白色部分的边界。

  2. 要包括黑色部分,从左上角减去一个常数。如果小于或等于0,则表示我们已经到达或超过了实际图像的左角,所以设置为1 . 如果它大于零,那么一切都很好。

  3. 对右下角进行类似的调整。

  4. 裁剪到所需的大小。

代码:

%Finding the boundary of the white
[~, c1] = find(thisBlob, 1);             [~, r1] = find(thisBlob.', 1);
[~, c2] = find(thisBlob, 1, 'last');     [~, r2] = find(thisBlob.', 1, 'last');

%Making adjustments to include the black portion
k = 10;            %constant defining max number of black pixels
mxlim = size(X);   %to be used to confirm that we don't exceed the boundary of the image
r1 = r1-10;  r1(r1<=0)=1;                    c1 = c1-10;  c1(c1<=0)=1;
r2 = r2+10;  r2(r2>mxlims(1)) = mxlim(1);    c2 = c2+10;  c2(c2>mxlim(2)) = mxlims(2);

%Extracting the desired portion
thisBlob = thisBlob(r1:r2, c1:c2);

所提供图像的输出:

您可以通过更改代码中的常量k来更改黑色像素的数量。


白色部分在边缘时的测试用例:

要验证它是否也适用于白色部分是否在边缘,如下图所示:

上图的代码输出如下:

【讨论】:

  • 我是否需要将此代码添加到我当前的代码中,或者这是我可以用来代替我编写的代码的完整代码?
  • @Nick 上面的代码假设您已经分离了白色部分并解释了进一步的处理。您需要在filname = strcat(h,'_Out.jpg'); 行之后添加此代码
【解决方案2】:

实际上,您要执行的是在对象周围有一点跨度的裁剪。这可以使用imcrop 轻松实现,您必须调用它来提供您想要保留的矩形。

为了识别矩形:

  1. 查找包含白色像素的最小和最大行 (y-axis);
  2. 查找包含白色像素的最小和最大列 (x-axis);
  3. 使用maximum - minimum 计算矩形的宽度和高度。
  4. 由于您想使用一点margin 进行裁剪(在我的示例中,我将其值设置为10,但您可以完全控制它),您必须将margin 减去最小值并将其添加到最大值值,但注意不要超出图像的边界(这就是 min-max 小游戏发挥作用的地方)。

这是完整的工作代码:

img = imread('img11_Inp.jpg');
imshow(img);

img_bin = imbinarize(img);
[lab,num] = bwlabel(img_bin);

span = 10;

for k = 1:num
    file = [num2str(k) '_Out.jpg'];

    blob = ismember(lab,k);
    blob_size = size(blob);

    col_idx = find(any(blob == true,1));
    x1 = max([1 (min(col_idx) - span)]);
    x2 = min([blob_size(2) (max(col_idx) + span)]);
    width = x2 - x1;

    row_idx = find(any(blob == true,2));
    y1 = max([1 (min(row_idx) - span)]);
    y2 = min([blob_size(1) (max(row_idx) + span)]);
    height = y2 - y1;

    blob_crop = imcrop(blob,[x1 y1 width height]);
    imwrite(blob_crop,file);

    figure();
    imshow(blob_crop,[]);
end

另外,不要使用int2str(k) 来获取索引的字符串表示形式。您的索引实际上是double,因此您强制进行双重(不是双关语)演员:double -&gt; int,然后是int -&gt; char array。只需使用num2str

结果:

【讨论】:

    猜你喜欢
    • 2019-07-12
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 2021-04-24
    • 1970-01-01
    • 2019-03-11
    • 2023-03-05
    相关资源
    最近更新 更多