代码之家  ›  专栏  ›  技术社区  ›  Tarcisiofl

用NumPy的np替换MATLAB的repmat()。瓷砖()

  •  -2
  • Tarcisiofl  · 技术社区  · 8 年前

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

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

    到Python。此代码设置图像中的所有背景像素 maskedRGBImage 哪里 BW 是 False 归零。

    以下是完整的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)

    这个 蒙面图像 有形状 (1024,768,3) 和 体重 有形状 (1024,768) 但不知怎的我没能皈依 体重 正确的形状。如何替换MATLAB repmat 作用于 NP瓦片 或者其他Python函数?

    1 回复  |  直到 8 年前
        1
  •  0
  •   hbaderts    8 年前

    正如您已经在评论中所写,问题在于以下几行:

    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瓦片 作为一个 repmat() 替换你真的想打电话吗 NP瓦片 具有 (1, 1, 3) 作为参数,将输入数组在三维中平铺三次。

    而在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