2015-03-02 3 views
2

У меня есть массив numpy, представляющий jpg, а не как файл. Поэтому я должен непосредственно обрабатывать массив. Я хочу сохранить эти данные в файл, чтобы я мог смотреть его с помощью обычного jpg-просмотра. Обычно я могу сделать это сПреобразование массив numpy в изображение

pl = pylab.imshow(ds.pixel_array, cmap=pylab.cm.bone) 

но видеоинформация кодируется в jpg2000, поэтому этот подход не удалось. Я попытался поэтому pgmagick:

tmp = pgmagick.Image(ds.pixel_array) 
logging.info("Info I") 
pl = pgmagick.Blob() 
tmp.write(pl, 'GRAY') 

, но, к сожалению, это не удается, тоже с ошибкой, что NumPy-массив не может быть преобразован в pgmagick-изображения. Есть ли другой способ конвертировать jpg2000-кодированную информацию в информацию, пригодную для PIL?

Update:
Запуск следующую строку

jpg_bytes = ds.pixel_array.astype('uint8').tostring() 

приводит к следующей ошибке:

Data type not understood by NumPy: format='uint12', PixelRepresentation=0, BitsAllocated=12 

Edit: Полная функция:

def convert(self, inputpic, outputpic = "", force = False): 
     if not inputpic or not os.path.isfile(inputpic): 
      logging.critical("No valid input filename entered, or input file not found. Input filename was " + inputpic) 
      return INT_ERROR 
     else: 
      input_clean = self.cleanEnding(inputpic) 
      if not outputpic: 
       outputpic = input_clean + ".jpg" 
      print "Output pic is " + outputpic 
      if os.path.isfile(outputpic + ".jpg") and force is False: 
       logging.critical("Output file is already there, don't want to overwrite it! Output filename was " + outputpic) 
      else: 
       if outputpic[:-4] is not ".jpg": 
        outputpic = outputpic + ".jpg" 
       try: 
        ds = dicom.read_file(inputpic, force=True) 
       except InvalidDicomError: 
        logging.critical("File " + inputpic + " is not a dicom file!") 
        return INT_ERROR 
       #try: 
       # pl = pylab.imshow(ds.pixel_array, cmap=pylab.cm.bone) 
       #except: 
       try: 
        logging.info("Decoding starts now") 
        jpg_bytes = "".join(chr(x) for x in ds.pixel_array) 
        logging.info("Test I") 
        jpg_bytes = ds.pixel_array.astype('uint8').tostring() 
        logging.warning("Trying to decode it with pgmagick") 
        im = pgmagick.Image.open(io.BytesIO(jpg_bytes)) 
        logging.info("Decoding successfull") 
        #logging.info("Info I") 
        #pl = pgmagick.Blob() 
        #tmp.write(pl, 'GRAY') 
       except Exception as e: 
        logging.critical("Critical error happened during imshow() with file " + inputpic + " with the following error: " + str(e)) 
        return INT_ERROR 
       if not os.path.isfile("tmp.png"): 
        pylab.savefig("tmp.png") 
       else: 
        logging.critical("tmp.png is already in this folder, maybe a failed cleanup? Stopping!") 
        return INT_ERROR 
       im = Image.open("tmp.png") 
       bg = Image.new("RGB", im.size, (255,255,255)) 
       bg.paste(im, (0,0), im) 
       bg.save(outputpic[:-4], quality=95) 
       os.remove("tmp.png") 
     return INT_SUCCESS 

с inputpic как DICOM файл. Ошибка в файле регистрации появляется после первого logging.info (logging.info("Decoding starts now")), поэтому я предполагаю, что ошибка выбрана из второй строки, после того, как третья строка больше не находится в файле журнала.

+0

Я не уверен, что понимаю. Можете ли вы просто написать его как двоичный файл без привлечения PIL? Вы пробовали io из изображения scikit? – YXD

+0

Обратите внимание, что вы не можете использовать 'is' для сравнения строк, поэтому' if outputpic [: - 4] не является «.jpg» 'не будет делать то, что вы ожидаете. Используйте '=='/'! =': 'If outputpic [: - 4]! =" .jpg "'. –

+0

Кроме того, если вы используете 'logging.exception' вместо' logging.critical', вы получите трассировку стека вместе с ошибкой. –

ответ

2

Предполагая, что pixel_array представляет собой массив байтов, представляющих изображение в формате JPEG (первые четыре байта - магическое число - будет FF D8 FF E0, если это так).

Вы можете преобразовать Numpy массив в строку байтов с помощью:

jpg_bytes = ds.pixel_array.astype('uint8').tostring() 

И вы можете загрузить строку байт с помощью:

import io 
from pgmagick import Image 

im = Image.open(io.BytesIO(jpg_bytes)) 

Edit: Я пропустил "jpg2000" биты , так:

  • pgmagick может загрузить jpg2000 файлы, а код выше будет работать wi проблема.
  • Магическое число файлов jpg2000: 0000 000C 6A50 2020 0D0A 870A.
+0

У меня есть данные как массив numpy, а не как файл, как указано в моем вопросе. Кроме того, у меня есть проблема, что PIL не может обрабатывать сжатые jpg2000 данные, как это также указано в вопросе, поэтому делает это бесполезным для меня. –

+0

См. Второй блок кода для примера преобразования массива numpy в строку байта. pgmagick - который вы уже используете - поддерживает jpg2000, поэтому пример должен работать. Если это не так, скорее всего, ваша установка pgmagick была построена без поддержки jpg2000. –

+0

Даже первая строка не работает, ошибка отображается в открывшемся сообщении. –