Замена repmat () в MATLAB на np.tile () от NumPy - PullRequest
0 голосов
/ 06 июня 2018

Я пытаюсь перенести приведенную ниже функцию для порогового изображения с MATLAB на 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)

maskedRGBImage имеет форму (1024,768,3), а BW имеет форму (1024,768), но почему-то мне не удается преобразовать BW в правильную форму.Как заменить функцию repmat в MATLAB на np.tile или любую другую функцию Python?

1 Ответ

0 голосов
/ 07 июня 2018

Как вы уже пишете в комментариях, проблема заключается в следующей строке:

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().На самом деле вы хотите вызвать np.tile с (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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...