Значения интенсивности кадров изображения меняются после преобразования в видео

#python #opencv #image-processing #video-processing

#python #opencv #обработка изображений #обработка видео

Вопрос:

Я использую OpenCV для создания видеороликов с определенными шаблонами. Один из моих шаблонов размером 35×35 выглядит следующим образом

шаблон

и соответствующие числовые записи в базовой матрице выглядят следующим образом

введите описание изображения здесь

Моя идея состоит в том, чтобы наложить шаблон на белый фон размером 260×346 и создать видео, в котором шаблон перемещается горизонтально. Первый кадр будет выглядеть примерно так

введите описание изображения здесь

Я создаю видео, используя OpenCV со следующей функцией

 def move_square(pattern, background):
    '''
    The function creates a video of the pattern moving horizontally over a given background

    Parameters:
    -----------
    pattern: <np.array, 35x35>
        The pattern supposed to move over the background
    background: <np.array, 260x346>
        A white background of the given size 
    '''
    fourcc = VideoWriter_fourcc(*'MP42')
    video = VideoWriter('./videos/moving_pattern_for_sampling_exp.avi', fourcc, 30, (346, 260))
    background[112:147, 0:35] = pattern
    frame = background

    for _ in range(0, 346-30):
        video.write(cv2.cvtColor(frame,cv2.COLOR_GRAY2RGB))
        shifted_frame =  np.roll(frame, 1, axis=1)
        frame = shifted_frame
        video.write(frame)

    cv2.destroyAllWindows()
    video.release()
  

Однако, если я прочитаю кадры вышеупомянутого видео, используя следующий фрагмент

 vidcap = cv2.VideoCapture('videos/moving_pattern_for_sampling_exp.avi')
success,image = vidcap.read()
count = 0

while success:
  cv2.imwrite("test/frame%d.jpg" % count, image)     # save frame as JPEG file      
  success,image = vidcap.read()
  print('Read a new frame: ', success)
  count  = 1

im = cv2.imread('test/frame1.jpg')
img = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
np.savetxt("image.csv", np.asarray(img),fmt='%i', delimiter=",")
  

а теперь посмотрите на кадры, значения шаблона в кадре отличаются от того, какими они были изначально.

введите описание изображения здесь

Кроме того, для мест, которые должны были быть белыми со значением 255, теперь повсюду установлено значение 252. Что может быть причиной этих расхождений?

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

1. JPEG с потерями. Разрешается изменять ваши данные, чтобы уменьшить размер вашего файла. Используйте PNG, если хотите сжатие без потерь.

2. Большинство видеокодеков сделают это сами, т.е. «скорректируют» ваши данные, кстати, точно так же, как JPEG.

3. Да, я понял, что видеокодек был неправильным. Я заменил свой старый кодек одним из этих кодеков без потерь, и моя проблема была решена. Спасибо за ваши комментарии.

Ответ №1:

Когда вы сохраняете изображение в формате JPEG, вы теряете качество, следовательно, точность. Вот пример сжатия JPEG (вы можете найти полное изображение здесь):

Нет сжатия
Сжатие

Вы можете наблюдать ухудшение качества птицы и дерева (на полном изображении).

Как предложил @Mark Setchell, вы можете использовать PNG, чтобы избежать этого, но помните, что чем больше у вас цветовых вариаций на изображении, тем больше будет ваш файл.

Если это поможет, в этой статье в Википедии кратко описаны распространенные форматы файлов.

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

1. Спасибо за ваши комментарии. Хотя проблема с png / jpeg в целом может быть правдой, похоже, здесь это не помогает. Я модифицировал вышеупомянутые функции, чтобы записывать и считывать все в терминах изображений png вместо jpeg. Однако в итоге я получил такое же несоответствие. Может ли произойти какая-то потеря из-за видеокодеков?

2. Я обнаружил, что проблема также была в видеокодеке, который я использовал ранее. Кодек без потерь наряду с заменой .jpg на .png в функциях выше решает проблему. Спасибо за вашу помощь

3. Рад, что это помогает, проблему с кодеком может быть сложно найти, молодец.