罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经退休,不会被更新。

填补图像NaN值与当地平均水平

最近我们有一个客户问如何在图像填充NaN值与当地社区的意思。我的朋友,同事,和偶尔的博客,布雷特Shoelson今天,加入我给你们几个可行的技术。

内容

创建数据

让我们创建一个图像,人为地创造一些漏洞与nan。这是一个类型的形象uint8,不能代表南所以我们要转换为浮点值。

img = imread (“rice.png”);谁img
类属性名称大小字节256 x256 65536 uint8 img
thisIsWhatHappens = uint8(南)
thisIsWhatHappens = uint8 0

将图像从uint8单。

singleImg = im2single (img);tlo = tiledlayout (2, 2,“TileSpacing”,“紧凑”,“填充”,“没有”);nexttile (tlo);imshow (singleImg)

添加一些NaN值。单一米粒小于270像素,因此我们选择介绍nan地区比一个典型的粮食。首先我们阈值图像分割粒大米。我们丢弃blob小于270像素。这给了我们一个大的面具或连续的米粒。我们用nan替换这些领域的原始图像。你可以看到,在第三图像。

nanMask = imbinarize (singleImg,“自适应”);nanMask = bwareaopen (nanMask, 270);nexttile (tlo) imshow (nanMask) singleImgNaN = singleImg;singleImgNaN (nanMask) =南;nexttile (tlo) imshow (singleImgNaN)

现在让我们考虑几种方法来填充这些南地区。

使用regionfill取代nan -解决方案1

regionfill提供了一个“开箱即用”,记录区域填充的方法。它工作得很好,很快。它填补了区域内使用插值图像,在这种情况下,替换nan的光滑表示当地背景值。如果你对算法感兴趣,请访问文档页面。这是你的首选算法对大多数region-filling需求。

imgrf = regionfill (img, nanMask);nexttile (tlo) imshow (imgrf)

这是伟大的,但不一定是客户要求。

nan换成当地平均水平-解决方案2

让我们试试别的。让我们首先定义我们所说的“邻近像素”。

如果我们有一个单一的像素,我们可以定义其邻国”四连接”,意思是像素北,东,南,西是邻居,或者我们可以定义邻居”8-connected,“在这种情况下,我们包括东北、SE,西南,西北除了。我们可以代表这些偏移量相对于图像中像素的位置。

一个警告:我们需要小心不要超越的边缘图像,因此我们将垫图像存在1个像素的边界为零。(< //www.tatmou.com/products/image.html图下载188bet金宝搏像处理工具箱中的函数>为你照顾这些事情,必要时)。

单像素黑框的四周添加一个图片:

paddedImg = padarray (singleImgNaN, [1], 0,“两个”);

创建四连接和8-connected补偿。

[m, n] =大小(singleImg);neighbors4 = (1 1 m - m);neighbors8 = [neighbors4、m1 - m + 1 m - 1 m + 1];

我们不一定要改变输出图像的大小。为了适应这一点,我们可以把原始图像中的位置分开的图像。

让我们先找到nan。

originalNaNPos =找到(isnan (singleImgNaN));paddedImageNaNs =找到(isnan (paddedImg));

我们要覆盖输出图像中的各个像素复制我们可以改变。

imglocav = singleImgNaN;

我们可以创建和使用一些匿名函数来计算方法使用两个不同社区的定义,忽略nan。

f4 = @(印第安纳州)意味着(paddedImg(印第安纳州+ neighbors4),“omitnan”);f8 = @(印第安纳州)意味着(paddedImg(印第安纳州+ neighbors8),“omitnan”);

让我们为四连接显示这样子的邻居。我们发现nan填充图像的位置,并计算这些邻居意味着。然后我们把这个计算值和替换原始图像的相应位置。

2 = 1:元素个数(paddedImageNaNs) imglocav (originalNaNPos (ii)) = f4 (paddedImageNaNs (ii));结束imshow (imglocav)

我们看到这种方法的第一个问题:任何南像素包围完全由南邻居——将取代南!

whyNaN =意味着(nan (4,1),“omitnan”)
whyNaN =南

因此,尽管我们缩小NaN-holes,我们还没有完全删除它们。(注意当我们放大和使用impixelinfo我们可以看到像素的值我们讨论)。

所以要做什么吗?

让我们重复!现在让我们考虑如果我们进行迭代,直到不再有nan。

让我们先重置我们的形象。

imglocav = singleImgNaN;

现在迭代

nnz (isnan (imglocav)) > 0 originalNaNPos =找到(isnan (imglocav));2 = 1:元素个数(originalNaNPos) imglocav (originalNaNPos (ii)) = f4 (paddedImageNaNs (ii));结束结束imshow (imglocav)

我们认为这是客户在要求什么,但现在我们看到一个潜在的第二个问题:完全包围的南像素的4 - eight-connectedness NaN,已经替换为0。

电脑做我们问什么,但不一定是我们想要的东西!

使用地区的标签来填补——解决方案3

我们要利用的nanMask我们之前计算。我们发现了,和标签不同的连接区域。接下来我们将遍历每个区域并填满每一个的意思是周长值。不需要迭代,但我们最终会与平地区统一的强度。

edgeMask =边缘(nanMask);bwl = bwlabel (edgeMask);bwl2 = bwlabel (nanMask);imX = singleImgNaN;2 = 1:马克斯(bwl (:)) thisEdgeMean =意味着(imX (bwl = = 2),“omitnan”);imX (bwl2 = = 2) = thisEdgeMean;结束imshow (imX)

其他人呢?

关于这个问题的其他方法你认为什么?我们知道有许多不同的方法。让我们知道在这里




发表与MATLAB®R2020b

|
  • 打印
  • 发送电子邮件