Перевернет изображение, изменит размер изображения

У меня есть изображение и его маска, выбранные на конкурсе, организованном в kaggle. Форма изображения (512,512,3), а маска (512,512,1). После применения 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

Пожалуйста, опубликуйте код, где вы используете функцию, например. img, mask = random_flip(img, mask)

Thomas Weller 28.05.2019 12:33

@ThomasWeller, я разместил код. Будет ли этого достаточно?

James K J 28.05.2019 12:35

Один раз напечатаешь mask, в следующий раз mask_tr...

Thomas Weller 28.05.2019 12:36

mask_tr в основном является результатом переворачивания изображения.

James K J 28.05.2019 12:36

Вот что я просил: заявление типа ???, mask_tr = random_flip(img, mask)

Thomas Weller 28.05.2019 12:38

Я подозреваю, что форма маски действительно (512,512)...

Mark Setchell 28.05.2019 12:40

@s326280 Пожалуйста, распечатайте форму вашей маски: print(mask.shape). Я полностью уверен, что @MarkSetchell прав. Скорее всего, вы не увидите третьего измерения в форме, поэтому вы получаете эту ошибку. Чтобы решить эту проблему, вам нужно обязательно добавить одноэлементное измерение в третье измерение, если у вас есть 2D-маска: mask = mask[...,None].

rayryeng 28.05.2019 12:41

@MarkSetchell, форма публикуется в разделе вывода. Пожалуйста, взгляните на это. Строка начинается с '>'

James K J 28.05.2019 13:02
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
244
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, что 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 контролирует вероятность того, что произойдет переворот изображения и маски.

@ s326280 вообще не беспокойтесь. Я изменил вашу функцию случайного переворота, чтобы маска возвращалась с неповрежденным одноэлементным измерением. Рад, что помог!

rayryeng 28.05.2019 13:14

Другие вопросы по теме