【问题标题】:Replacing MATLAB's repmat() with NumPy's np.tile()用 NumPy 的 np.tile() 替换 MATLAB 的 repmat()
【发布时间】:2018-06-06 04:28:13
【问题描述】:

我正在尝试移植以下函数,用于将图像从 MATLAB 阈值化到 Python。但是我无法转换以下 MATLAB 代码:

maskedRGBImage(repmat(~BW,[1 1 3])) = 0

到 Python。此代码将图像maskedRGBImage 中的所有背景像素设置为零,其中BWFalse

这是完整的 MATLAB 代码:

function [BW,maskedRGBImage] = createMask(RGB)    

I = rgb2hsv(RGB);

% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.985;
channel1Max = 0.460;

% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.264;
channel2Max = 1.000;

% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.000;
channel3Max = 1.000;

% Create mask based on chosen histogram thresholds
sliderBW = ( (I(:,:,1) >= channel1Min) | (I(:,:,1) <= channel1Max) ) & ...
    (I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
    (I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;

% Initialize output masked image based on input image.
maskedRGBImage = RGB;

% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;

end

到目前为止,这就是我将代码转换为 Python 和 NumPy 的方式:

def createMask( image ):
    maskedRGBImage = image
    image = cv2.cvtColor( image, cv2.COLOR_RGB2HSV )

    channel1Min = 0.985;
    channel1Max = 0.460;

    channel2Min = 0.264;
    channel2Max = 1.000;

    channel3Min = 0.000;
    channel3Max = 1.000;

    sliderBW = ((image[:,:,0] >= channel1Min) | (image[:,:,0] <= channel1Max) ) & (image[:,:,1] >= channel2Min ) & (image[:,:,1] <= channel2Max) & (image[:,:,2] >= channel3Min ) & (image[:,:,2] <= channel3Max)
    BW = sliderBW
    maskedRGBImage[(np.array([np.tile(~BW, (1,1)) for i in range(3)]))] = 0

我尝试使用如图所示的np.tile函数,但这不起作用并在最后一行返回以下错误:

ValueError: 操作数无法与形状一起广播 (1024,768,3) (3,1024,768)

maskedRGBImage 的形状为 (1024,768,3)BW 的形状为 (1024,768),但不知何故我无法将 BW 转换为正确的形状。如何将 MATLAB 的 repmat 函数替换为 np.tile 或任何其他 Python 函数?

【问题讨论】:

  • 欢迎来到 Stack Overflow!以下是该网站的工作方式:您可以自己编写代码,遇到困难,就您遇到的确切问题提出具体问题,其他人会帮助您。几乎不可能有人为您编写代码。
  • @NPE 我不明白你为什么这么说,我正在转换一段代码,然后卡在一行中。然后,我试图在这里得到任何提示!
  • 请发布您目前拥有的代码,以便读者更好地了解您如何在 Python 代码等中表示事物,并提供更准确的帮助。
  • @NPE 谢谢,我已经添加了!
  • 图像尺寸似乎有一些错误:一种情况是width x height x channels,另一种情况是channels x width x height。这发生在哪一行? maskedRGBImage.shapeimage.shape 返回什么?

标签: python matlab numpy


【解决方案1】:

正如您已经在 cmets 中写的那样,问题出在以下行:

maskedRGBImage[(np.array([np.tile(~BW, (1,1)) for i in range(3)]))] = 0

首先,请注意 np.tile(~BW, (1, 1)) 根本不做任何事情:np.tile 相当于 MATLAB 的 repmat(),它按照您指定的次数重复矩阵,即只重复一次。所以你返回~BW。您可以通过调用来验证这一点

np.all(np.tile(~BW, (1, 1)) == ~BW)

返回True,表示这确实等于~BW

其次,您手动尝试使用列表理解重新创建 repmat() 功能:

np.array([np.tile(~BW, (1,1)) for i in range(3)])

但是,请注意,这会返回大小为 (3, 1024, 768) 的数组,而您的图像的形状为 (1024, 768, 3)。这实际上是错误消息所说的内容。

一个可能的解决方案是删除列表理解并使用np.tile 作为repmat() 替换。您实际上想以(1, 1, 3) 作为参数调用np.tile,在第三维中将输入数组平铺三次。

虽然在 MATLAB 中这是开箱即用的,但 NumPy 要求您将输入数组 BW 在您的情况下设为三维,即将其从维度 (1024, 768) 更改为 (1024, 768, 1)。这是使用np.newaxis 完成的:

np.tile(~BW[:, :, np.newaxis], (1, 1, 3))

通过索引maskedRGBImage 变量应该可以正常工作:

maskedRGBImage[np.tile(~BW[:, :, np.newaxis], (1, 1, 3))] = 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-15
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多