我正在尝试移植以下函数,以便将图像从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
或任何其他Python函数替换MATLAB的np.tile
函数?
答案 0 :(得分:0)
正如您在评论中写的那样,问题出在以下几行:
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