使用dcm4che对压缩的dcm文件进行解压

上一篇文章说到了DCM文件的无损压缩 DICOM DCM4CHE影像压缩

本想着压缩了就大功告成 在使用的时候可以大大减少网络上传输的时间 提高网站性能

但是新的问题又出现了

问题如下 代码中获取文件像素的时候取到的是 null

    public static Attributes loadDicomObject(File f) throws IOException {
        if (f == null){
            return null;
        }else{
            DicomInputStream dis = new DicomInputStream(f);
            //attr.setSpecificCharacterSet("GBK");
            return dis.readDataset(-1, -1);
        }
    }
Attributes attrs = loadDicomObject(file);
byte[] pixelData=attrs.getBytes(Tag.PixelData);//pixelData 为null

但是在取没有压缩的DCM源文件通过这段代码是可以取到的

到底压缩和没压缩有什么区别呢?

先用阅片工具看一下PixelData 的tag吧

这是源文件的PixelData tag值
使用dcm4che对压缩的dcm文件进行解压_第1张图片

这是压缩后的PixelData tag值
使用dcm4che对压缩的dcm文件进行解压_第2张图片
很明显的 VR 从OW 变成了OB Value 变空了 难怪取不上值

经过不断找资料研究 发现DCM压缩后 像素值会通过 Fragments 方式存

然后对代码进行修改

Object pixelData = attr.getValue(Tag.PixelData);
if (pixelData instanceof byte[]) {
   dicomPixels=(byte[])pixelData;
} else if (pixelData instanceof BulkData) {
   System.out.println("343434343");
} else if (pixelData instanceof Fragments) {
   Object [] aa= ((Fragments) pixelData).toArray();
   dicomPixels=(byte[])aa[1];
}

果然取上了压缩后的像素值

又想着终于解决了 可以愉快的玩耍了 结果新的问题又出来了

再用压缩后的像素值进行调节灰度时

居然这样了!!

使用dcm4che对压缩的dcm文件进行解压_第3张图片
居然马赛克了!

明显压缩后的源文件 像素也应该是压缩处理了

然后继续研究。。但是确实资料太少了 工期又有限

只好在用的时候先把压缩后的DCM文件 先进行解压 然后再获取 像素值使用了

1.添加对应的dcm4che的jar包
在pom.xml里:

       <dependency>
            <groupId>org.dcm4che</groupId>
            <artifactId>dcm4che-imageio</artifactId>
            <version>5.21.0</version>
        </dependency>
        <dependency>
            <groupId>org.dcm4che</groupId>
            <artifactId>dcm4che-imageio-opencv</artifactId>
            <version>5.21.0</version>
            <scope>runtime</scope>
        </dependency>
  1. 开始解压
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.UID;
import org.dcm4che3.imageio.codec.Transcoder;


public class Dcm4cheTranscode {
    public static void main(String[] args) {
        File src = new File("F:\\Desktop\\2238\\DX\\src.DCM"); //带有压缩协议的dicom原始文件
        File dest = new File("F:\\Desktop\\2238\\DX\\des.DCM"); //解压成未压缩的dicom目标文件
        
        try {
            transcodeWithTranscoder(src, dest);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	public static void transcodeWithTranscoder(File src, final File dest) throws IOException {
		try (Transcoder transcoder = new Transcoder(src)) {
			transcoder.setDestinationTransferSyntax(UID.ExplicitVRLittleEndian);
			transcoder.setIncludeFileMetaInformation(true);
			transcoder.transcode(new Transcoder.Handler(){
				@Override
				public OutputStream newOutputStream(Transcoder transcoder, Attributes dataset) throws IOException {
					return new FileOutputStream(dest);
				}
			});
		} catch (Exception e) {
			Files.deleteIfExists(dest.toPath());
			throw e;
		}
	}
}

目前是研究到这个份上 ,有更好的解决办法希望大神指点,我也会继续研究,不断学习的。。。有收获继续更新

你可能感兴趣的:(DCM4CHE)