python - 将翻转图像改变图像尺寸
问题描述
我有一张从 kaggle 举办的比赛中挑选出来的图像和它的面具。图像的形状是(512,512,3)
,蒙版是(512,512,1)
。在图像上应用 a 后function(flipping)
,形状保持不变。但是,在我尝试访问掩码时应用操作之前,例如(print mask[:,:,0])
,我得到一个矩阵,
[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]
但应用操作后,并尝试访问掩码(print mask[:,:,0]),
我得到以下错误
Traceback (most recent call last):
File "Augmentation.py", line 94, in <module>
plot_img_and_mask_transformed(img,mask,img_flip,mask_flip)
File "Augmentation.py", line 36, in plot_img_and_mask_transformed
print(mask_tr[:,:,0])
IndexError: too many indices for array
我应用的功能是
def random_flip(img,mask,u=0.5):
if np.random.random() < u :
img = cv.flip(img,0)
mask = cv.flip(mask,0)
return img, mask
img, mask = get_image_and_mask(img_id)
img_tr,mask_tr = random_flip(img,mask)
plot(img,mask,img_tr,mask_tr)
翻转前图像和蒙版的形状
((512, 512, 3), (512, 512, 1))
翻转后图像和蒙版的形状
((512, 512, 3), (512, 512))
有人可以帮我弄清楚幕后发生的事情吗?
代码
def get_image_and_mask(img_id):
img = image.load_img(join(data_dir,'train','%s.jpg' % img_id),target_size=(input_size,input_size))
img = image.img_to_array(img)
mask = image.load_img(join(data_dir,'train_masks','%s_mask.gif' % img_id), grayscale=True,target_size=(input_size,input_size))
mask = image.img_to_array(mask)
img,mask = img / 255., mask/ 255.
return img, mask
def plot_img_and_mask(img,mask):
fig, axs = plt.subplots(ncols=2, figsize=(10,5),sharex=True,sharey=True)
axs[0].imshow(img)
axs[1].imshow(mask[:,:,0])
for ax in axs:
ax.set_xlim(0,input_size)
ax.axis('off')
fig.tight_layout()
plt.show()
def plot_img_and_mask_transformed(img, mask, img_tr, mask_tr):
fig, axs=plt.subplots(ncols=4,figsize=(16,4),sharex=True,sharey=True)
axs[0].imshow(img)
axs[1].imshow(mask[:,:,0])
print(mask[:,:,0])
print(mask_tr[:,:,0])
axs[2].imshow(img_tr)
axs[3].imshow(mask_tr)
for ax in axs:
ax.set_xlim(0,input_size)
ax.axis('off')
fig.tight_layout()
plt.show()
def random_flip(img,mask,u=0.5):
# Why do we have to check less than u
if np.random.random() < u :
img = cv.flip(img,0)
mask = cv.flip(mask,0)
return img, mask
def rotate(x,theta,row_axis=0,col_axis=1,channel_axis=2,fill_mode='nearest',cval=0):
rotation_matrix = np.array([
[np.cos(theta),-np.sin(theta),0],
[np.sin(theta),np.cos(theta),0],
[0,0,1]
])
h, w = x.shape[row_axis], x.shape[col_axis]
transform_matrix = image.transform_matrix_offset_center(rotation_matrix,h,w)
x = image.apply_transform(x,transform_matrix,channel_axis,fill_mode,cval)
return x
def random_rotate(img, mask, rotate_limit=(-20,20), u=0.5):
if np.random.random() < u:
theta = np.pi/ 180 * np.random.uniform(rotate_limit[0], rotate_limit[1])
img = rotate(img,theta)
mask = rotate(mask,theta)
return img, mask
if __name__== '__main__':
input_size = 512
data_dir = '../data/carvana-image-masking-challenge'
np.random.seed(1987)
df_train = pd.read_csv(join(data_dir,'train_masks.csv'),usecols=['img'])
df_train['img_id']=df_train['img'].map(lambda s:s.split('.')[0])
df_train.head(3)
img_ids=df_train['img_id'].values
np.random.shuffle(img_ids)
img_id=img_ids[0]
img,mask=get_image_and_mask(img_id)
print((img.shape,mask.shape))
plot_img_and_mask(img,mask)
img_flip,mask_flip = random_flip(img,mask,u=1)
print((img_flip.shape,mask_flip.shape))
plot_img_and_mask_transformed(img,mask,img_flip,mask_flip)
输出
Using TensorFlow backend.
C:\Users\JamesJohnson\AppData\Local\Programs\Python\Python35\lib\site- packages\keras_preprocessing\image.py:492: UserWarning: grayscale is deprecated. Please use color_mode = "grayscale"
warnings.warn('grayscale is deprecated. Please use '
> ((512, 512, 3), (512, 512, 1))
> ((512, 512, 3), (512, 512))
[[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
...
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]
[0. 0. 0. ... 0. 0. 0.]]
Traceback (most recent call last):
File "Augmentation.py", line 94, in <module>
plot_img_and_mask_transformed(img,mask,img_flip,mask_flip)
File "Augmentation.py", line 36, in plot_img_and_mask_transformed
print(mask_tr[:,:,0])
IndexError: too many indices for array
解决方案
当您翻转掩码时,OpenCV 似乎会转储单例维度。翻转后,您需要重新引入它。
mask_flip = mask_flip[..., None]
一种更方便的方法是修改您的方法,以便在翻转后以单例维度返回掩码,以防万一丢失。这样,您不必每次翻转时都执行此操作,而是由该方法处理。
def random_flip(img,mask,u=0.5):
# Why do we have to check less than u
if np.random.random() < u:
img = cv.flip(img,0)
mask = cv.flip(mask,0)
if len(mask.shape) == 2:
mask = mask[..., None]
return img, mask
顺便说一句,您有一条评论询问为什么您必须检查u
方法中的小于。请记住,该np.random.random
方法统一生成一个介于 0 和 1 之间的值。假设您选择了u = 0.3
. 这意味着您有 30% 的机会选择介于 0 和 0.3 之间的值,并且有 70% 的机会选择介于 0.3 和 1 之间的值。松散地说,这意味着如果u = 0.3
,则有 30% 的机会if
条件运行,因此您翻转图像和蒙版。因此,u
控制了图像和蒙版翻转发生的概率。
推荐阅读
- react-testing-library - react-testing-library - 如果文本包含在其他子 html 标记中,如何测试文本是否存在?
- python - 当我在我的 Mac 上运行任何 pygame 脚本时,它会显示相同的黑屏
- javascript - NodeJS - 堆内存不足
- laravel - Laravel 更改资源路由 uri
- reactjs - 如果布局道具值是“响应式”,Next.js 新图像组件如何检测设备大小?
- c++ - 字符串值有多安全?
- python - 矢量化滑动/滚动 numpy nanmean
- amazon-web-services - 在 S3 中,我们可以在对象级别而不是存储桶级别打开版本控制和加密吗?
- html - Float:left 与 flexbox
- python - python返回一个格式奇怪的字符串