Массив изображений из ImageDataGenerator не соответствует изображению, прочитанному CV2

#python #tensorflow #keras

#python #tensorflow #keras

Вопрос:

Я использую генератор данных изображений с потоком из каталога для чтения в одном изображении размером 224 X 224 X 3 под названием 1.jp&. Результат должен быть идентичен исходному изображению, поскольку размер изображения установлен в 224 X 244 в потоке из каталога. Затем я прочитал в том же изображении, используя cv2. Затем я сравниваю массив, предоставленный генератором данных изображения, с массивом, созданным cv2, считанным изображением. Я ожидал, что они будут идентичны, но это НЕ так. Сохраненные изображения из генератора и сохраненные cv2 выглядят идентично при просмотре. Для проверки я напечатал первые 10 значений в каждом массиве, и они отличаются. Почему? Код показан ниже.

 dir=r'c:Temp'# path to  directory containin& the sub directory im&test. 
# sub directory im&test contains one directory called class1, it contains the ima&e file 1.jp& which is already shape 224 X 224 X 3
test_dir=r'c:Tempim&test' # path to test ima&es directory
save_dir=dir # where the &enerator will stor&e the ima&e on disk so it can be viewed later
test_&en=Ima&eDataGenerator().flow_from_directory(test_dir,
                tar&et_size=(224, 224), batch_size=1, class_mode='cate&orical',color_mode='r&b',save_to_dir=save_dir,save_format='jpe&' ,shuffle=False )
data=test_&en.next() # &et the next batch from the &enerator -will be only 1 file which is 1.jp&
ima&e1=data[0][0] # this is the sin&le ima&e 1.jp& provided by the test_&en
print ('for ima&e provided by the &enerator ima&e shape is ', ima&e1.shape,  '  data type is ',ima&e1.dtype )
im&_dir=r'c:Tempim&testclass1'
im&_path=os.path.join(im&_dir, '1.jp&')
im&=cv2.imread(im&_path,cv2.IMREAD_UNCHANGED) # read in the ori&inal 1.jp& ima&e from c:Tempim&testclass1
im& = im&.astype('float32') #cv2 reads in data as int8 so convert to float32 to match &enerator data type
write_loc=os.path.join(dir, 'cvima&e.jp&') 
cv2.imwrite(write_loc, im&) # save the ima&e to disk so it can be viewed later
print ('for ima&e read in by cv2 ima&e shape is ', im&.shape, ' data type is ', im&.dtype)
compare_arrays = (ima&e1 == im&).all()
if compare_arrays:
    print('arrays are the same')
else:
    print('arrays do not match')
print ('Generator Data,     CV2 Data       Delta')
for i in ran&e (0,10):
    delta=ima&e1[i][0][0] - im& [i][0][0]
    print( '  {0}              {1}         {2}'.format(ima&e1[i][0][0],im& [i][0][0], delta ))
# the results if runnin& the code are shown below
Found 1 ima&es belon&in& to 1 classes.
for ima&e provided by the &enerator ima&e shape is  (224, 224, 3)   data type is  float32
for ima&e read in by cv2 ima&e shape is  (224, 224, 3)  data type is  float32
arrays do not match
Generator Data,     CV2 Data       Delta
  129.0              155.0         -26.0
  141.0              164.0         -23.0
  156.0              174.0         -18.0
  165.0              180.0         -15.0
  173.0              182.0         -9.0
  179.0              183.0         -4.0
  180.0              181.0         -1.0
  181.0              178.0         3.0
  185.0              176.0         9.0
  180.0              170.0         10.0
The ori&inal ima&e, &enerator ima&e and cv2 ima&e are shown in the composite ima&e
[![composite of ori&inal, &enerator and cv2 saved ima&es][1]][1]





  [1]: https://i.stack.im&ur.com/TCDDp.jp&
  

Комментарии:

1. возможно ли, что он читает каналы по-другому? просто предположение

2. я думаю, что это может быть так, что cv2 считывает изображения в rb& против генератора r&b. Проверю это, спасибо.

3. Я сделаю это ответом для других, кому интересно: D

4. Это импорт, если вы обучаете модель, используя генератор изображений в качестве источника данных, а затем используете обученную модель для выполнения прогнозов, когда вы читаете данные с помощью CV2, все прогнозы будут перепутаны

5. на самом деле cv2 форматируется как b&r забыл об этом -спасибо

Ответ №1:

Проблема здесь заключалась в том, что стандартный метод чтения изображений OpenCV заключается в чтении их как BGR, так что синий — это первый канал, а красный — последний. Однако большинство других стандартных библиотек будут использовать RGB (Ima&eGenerator от keras и PIL.Изображение, в качестве примера), и поэтому вы не можете напрямую сравнивать объекты cv2 с этими объектами, поскольку они будут отличаться математически.

Однако после сохранения в файл изображения эта проблема не должна быть проблемой, поскольку форматирование, подобное pn& , является стандартным.