2015-03-02 199 views
2

我有一个代表jpg的numpy数组,而不是文件。因此我必须直接处理数组。我想将这些数据保存到一个文件中,这样我就可以用普通的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-able信息?

更新:
运行以下行

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

导致以下错误:

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

编辑:完整的功能:

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吗?你从scikit图像尝试过io吗? – YXD 2015-03-02 21:44:52

+0

请注意,您不能使用'is'来比较字符串,所以如果outputpic [: - 4]不是“.jpg”'不会达到您所期望的效果。使用'=='/'!=':'如果outputpic [: - 4]!=“.jpg”'。 – 2015-03-02 22:57:01

+0

另外,如果你使用'logging.exception'而不是'logging.critical',你将得到一个堆栈跟踪以及错误。 – 2015-03-02 22:57:34

回答

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)) 

编辑:我错过了 “JPG2000” 位,所以:

  • pgmagick可以加载jpg2000文件和上面的代码将工作无线这个问题。
  • jpg2000文件的幻数是0000 000C 6A50 2020 0D0A 870A
+0

我有数据作为一个numpy数组,而不是一个文件,如我的问题所述。此外,我还遇到PIL无法处理jpg2000压缩数据的问题,正如问题中所述,因此对我来说无效。 – 2015-03-02 21:37:10

+0

有关将numpy数组转换为字节字符串的示例,请参阅第二个代码块。 pgmagick - 你已经在使用 - 支持jpg2000,所以这个例子应该可以工作。如果没有,这可能意味着您的pgmagick的安装是在没有jpg2000支持的情况下构建的。 – 2015-03-02 22:02:17

+0

即使第一行不起作用,错误显示在开始帖子中。 – 2015-03-02 22:15:43