Отображать 2D-массив из OpenCV в Matplotlib.pyplot.imshow ()

у меня есть установка на Python, в которой я использую библиотеку OpenCV для чтения кадров видео в виде 2D-массивов - эти видео в оттенках серого, поэтому я использую 8-битные целые числа без знака для значения пикселей.

На следующем этапе я пытаюсь использовать pyplot.imshow () из matplotlib для отображения кадра видео. К сожалению, я получаю то, что вообще не имеет никакого смысла.

Вот код для чтения видео:

import numpy as np
import cv

def read_video(filename):
  video = cv.CaptureFromFile('%s' % filename)
  num_frames = int(cv.GetCaptureProperty(video, cv.CV_CAP_PROP_FRAME_COUNT))

  frames = []
  for i in range(0, num_frames):
    frame = cv.QueryFrame(video)
    if frame is None:
      quit('Failed to extract frame %s of %s!' % (i, num_frames))
    toadd = cv2numpy(frame, 'uint8')
    frames.append(np.array(toadd))
  return np.array(frames)

cv2numpy - служебная функция, которая преобразует массив OpenCV в массив numpy (просто вызов fromstring , а затем reshape ). Вот код, который я использую для построения первого кадра видео:

import matplotlib.pyplot as plot
import matplotlib.cm as cm

frames = read_video('video.avi')
plot.imshow(frames[0], cmap = cm.gray)
plot.show()

В другом коде я использовал OpenCV SaveImage для одного кадра, чтобы предоставить ссылку на то, что я ожидал от imshow . Вот изображение, которое я получил из предыдущего , и вот изображение, которое я получил из кода выше .

Как видите, они сильно отличаются. Единственное, что я могу почерпнуть из фактического изображения, - это полосы: похоже, что размеры неверны, что в ширине больше пикселей, чем в высоте (это изображение должно быть 128 x 256). Но я попытался транспонировать массив перед его построением, изменив параметры экстента и аспекта и формы в соответствии с документацией imshow , и, за исключением некоторого причудливого растяжения пикселей, я не нашел исправления.

Есть какие-нибудь мысли?

РЕДАКТИРОВАТЬ 1: Я полагаю, что было бы разумно добавить код cv2numpy , на случай, если это изменение каким-то образом сбивает с толку (поскольку мое "правдивое" изображение выше делает не использовать этот код и, следовательно, cv2numpy участвует только в сомнительном конвейере).

def cv2numpy(cvarr, the_type):
  a = np.fromstring(
      cvarr.tostring(),
      dtype = the_type,
      count = cvarr.width * cvarr.height)
  a.shape = (cvarr.height, cvarr.width)
  return a

8
задан Magsol 23 January 2012 в 20:29
поделиться