Skip to content

Instantly share code, notes, and snippets.

@tomafc330
Created May 12, 2012 18:54
Show Gist options
  • Save tomafc330/2668191 to your computer and use it in GitHub Desktop.
Save tomafc330/2668191 to your computer and use it in GitHub Desktop.
Amira DICOM converter
package converter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.archimed.dicom.DicomException;
import domain.Metadata;
import domain.Mode;
/**
* File that takes an Amira file (.am) and turn it into a DICOM image
*
* @author tchan
*
*/
public class AmiraToDicomConverter {
private final String inputFile;
private final String outputFile;
private final String referenceFile;
public static void main(String[] args) throws IOException, DicomException {
//String inputFile = "/home/tchan/Documents/ubc-reading-center/OCT_FILE_Samples/Amira_Export/024680_20120214_162423_3DOCT00_L_01.am";
String inputFile = "/home/tchan/Dropbox/RawFiles/256x256x128.am";
String referenceFile = "/home/tchan/Dropbox/RawFiles/DICOM/single.dcm";
SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MMM-dd-HH-mm-ss");
String dateNow = formatter.format(new Date().getTime());
String outputFile = "amira" + dateNow + ".dcm";
new AmiraToDicomConverter(inputFile, outputFile, referenceFile).convert();
}
public AmiraToDicomConverter(String inputFile, String outputFile, String referenceFile) {
this.inputFile = inputFile;
this.outputFile = outputFile;
this.referenceFile = referenceFile;
}
private void convert() throws IOException, DicomException {
File file = new File(inputFile);
Metadata header = getHeaderInformation(file);
long startPostToReadRaw = getRawDataStartOffset(file, header);
System.out.println(startPostToReadRaw);
byte[] rawData = getRawBytes(file, startPostToReadRaw, file.length());
System.out.println(rawData);
new DicomConverter(referenceFile, outputFile).convert(header, rawData);
}
/**
* Gets the start position of the raw data to read from.
*
* @param header
*/
private long getRawDataStartOffset(File file, Metadata header) {
return file.length() - getHeaderSize(header) - 1;
}
private long getHeaderSize(Metadata header) {
return Integer.parseInt(header.getWidth())
* Integer.parseInt(header.getHeight())
* Integer.parseInt(header.getFrames()) * 2;
}
private Metadata getHeaderInformation(File file) throws IOException {
byte[] rawHeader = getRawBytes(file, 0, 2048);
String str = getDimensionAndType(getContentString(rawHeader)); // ie.
// 512x885x128
// ushort,
// uniform
// coordinates
String[] parts = str.split(" ");
return new Metadata(parts[0], parts[1].replace(",", ""));
}
/**
* Will extract the raw data into a metadata class
*/
private String getDimensionAndType(String contentString) {
Pattern pattern = Pattern.compile("(?s)\\\"(.*?)\\\"");
Matcher matcher = pattern.matcher(contentString);
if (matcher.find()) {
return matcher.group(1).trim();
} else {
throw new RuntimeException("Cannot parse Amira Header file.");
}
}
/**
* Gets the Content string that looks something like this:
*
* Content "512x885x128 ushort, uniform coordinates", BoundingBox 0 511 0
* 884 0 127, CoordType "uniform"
*
*/
private String getContentString(byte[] rawHeader) {
Pattern pattern = Pattern.compile("(?s)Parameters \\{(.*?)\\}");
Matcher matcher = pattern.matcher(new String(rawHeader));
if (matcher.find()) {
return matcher.group(1).trim();
} else {
throw new RuntimeException("Cannot parse Amira Header file.");
}
}
private byte[] getRawBytes(File file, long start, long end) throws IOException {
InputStream is = new FileInputStream(file);
byte[] bytes = new byte[(int) (end - start)];
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "
+ file.getName());
}
is.close();
return bytes;
}
}
package converter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import com.archimed.dicom.DDict;
import com.archimed.dicom.DicomException;
import com.archimed.dicom.DicomObject;
import com.archimed.dicom.DicomReader;
import com.archimed.dicom.DicomWriter;
import com.archimed.dicom.IllegalValueException;
import domain.Metadata;
public class DicomConverter {
private String referenceFileName;
private String outputFileLoc;
public static void main(String[] args) throws IOException, DicomException,
IllegalValueException {
String inputFileLoc = "/home/tchan/Dropbox/RawFiles/DICOM/7line.dcm";
String outputFileLoc = "example7.dcm";
new DicomConverter(inputFileLoc, outputFileLoc).convert(new Metadata(
"512x885x128", "ushort"), retrieveRawData());
}
/**
*
* @param referenceFileName The reference file name where we grab the header information from
* @param outputFileName
*/
public DicomConverter(String referenceFileName, String outputFileName) {
this.referenceFileName = referenceFileName;
outputFileLoc = outputFileName;
}
public void convert(Metadata metadata, byte[] rawData) throws IOException,
DicomException {
DicomObject sampleInObj = read(referenceFileName);
DicomObject outObj = new DicomObject();
sampleInObj.dumpVRs(System.err, true);
// dump out example object
// sampleInObj.dumpVRs(System.out, true);
outObj.setFileMetaInformation(sampleInObj.getFileMetaInformation());
// outObj.set(DDict.dFileMetaInformationVersion, new byte[] {0, 1});
// outObj.set(DDict.dSOPClassUID, "1.2.840.10008.5.1.4.1.1.77.1.5.4");
// outObj.set(DDict.dSOPInstanceUID,
// "1.3.6.1.4.1.33437.11.4.5604041.12963093945.145.4.1");
// outObj.set(DDict.dTransferSyntaxUID, "1.2.840.10008.1.2.1");
// outObj.set_ge(0x0002, 0x0010, "1.2.840.10008.1.2.1");
// outObj.set(DDict.dMediaStorageSOPClassUID,
// "1.2.840.10008.5.1.4.1.1.77.1.5.4");
// outObj.set(DDict.dMediaStorageSOPInstanceUID,
// "1.3.6.1.4.1.33437.11.4.5604041.12963173613.145.4.0.1");
// outObj.set(DDict.dImplementationClassUID,
// "1.2.276.0.7230010.3.0.3.5.4");
// outObj.set(DDict.dImplementationVersionName, "OFFIS_DCMTK_354 ");
/**
* Image related data attrs.
*/
outObj.set(DDict.dPixelData, rawData);
outObj.set(DDict.dImageType, "ORIGINAL\\PRIMARY");
outObj.set(DDict.dSpecificCharacterSet, "ISO_IR 100");
outObj.set(DDict.dColumns, metadata.getWidth());
outObj.set(DDict.dRows, metadata.getHeight());
// outObj.set(DDict.dBitsAllocated, "8");
// outObj.set(DDict.dBitsStored, "8");
// outObj.set(DDict.dHighBit, "7");
outObj.set(DDict.dBitsAllocated, "16");
outObj.set(DDict.dBitsStored, "16");
outObj.set(DDict.dHighBit, "15");
outObj.set(DDict.dPixelRepresentation, "0");
// outObj.set(DDict.dSharedFunctionalGroupsSequence,
// createSharedGroupSequence());
outObj.set(DDict.dSamplesPerPixel, "1");
outObj.set(DDict.dPhotometricInterpretation, "MONOCHROME2 ");
outObj.set(DDict.dNumberOfFrames, metadata.getFrames());
// outObj.set(DDict.dImageLaterality, "R ");
/**
* General equipment module attrs
*/
outObj.set(DDict.dManufacturer, "TopCon");
outObj.set(DDict.dInstitutionName, "");
outObj.set(DDict.dInstitutionAddress, "");
outObj.set(DDict.dStationName, "");
outObj.set(DDict.dInstitutionalDepartmentName, "");
outObj.set(DDict.dManufacturerModelName, "OCT");
outObj.set(DDict.dDeviceSerialNumber, "");
outObj.set(DDict.dSoftwareVersion,
"FW-CAM 1.5.0.0\\FW-PWS 1.4.2.0\\FW-TSP 1.5.1.0\\SW-AQM 5.0.1.1 ");
/**
* General series module attrs
*/
outObj.set(DDict.dModality, "OPT ");
outObj.set(DDict.dSeriesInstanceUID,
"1.3.6.1.4.1.33437.11.3.5604041.12963093945.145.3.1");
outObj.set(DDict.dSeriesNumber, "2429001 ");
outObj.set(DDict.dImageLaterality, "L ");
outObj.set(DDict.dSeriesDate, "L ");
/**
* General study module attrs
*/
outObj.set(DDict.dStudyID, "1767592277");
outObj.set(DDict.dStudyDate, "20090212");
outObj.set(DDict.dStudyTime, "152300");
outObj.set(DDict.dPatientName, "test");
outObj.set(DDict.dPatientID, "HRA, Vol, OCT, PROG ");
outObj.set(DDict.dStudyInstanceUID,
"1.3.6.1.4.1.33437.11.2.5604041.12963093944.145.2");
outObj.set(DDict.dReferringPhysiciansName, "");
outObj.set(DDict.dContentDate, "20090212");
outObj.dumpVRs(System.out, true);
OutputStream outStream = new FileOutputStream(outputFileLoc);
new DicomWriter().write(outObj, outStream, true);
}
private static byte[] retrieveRawData() throws FileNotFoundException,
IOException {
File rawFile = new File("/home/tchan/Dropbox/RawFiles/3DOCT.raw");
FileInputStream fin = new FileInputStream(rawFile);
byte[] rawData = new byte[(int) rawFile.length()];
fin.read(rawData);
return rawData;
}
private static Object createSharedGroupSequence() throws DicomException {
// create a first sequence item
DicomObject sharedGroupSequence = new DicomObject();
sharedGroupSequence.set(DDict.dReferencedImageSequence,
createReferencedImageSequence());
sharedGroupSequence.set(DDict.dFrameAnatomySequence,
createFrameAnatomySequence());
sharedGroupSequence.set(DDict.dPlaneOrientationSequence,
createPlaneOrientationSequence());
sharedGroupSequence.set(DDict.dPixelMeasuresSequence,
createPixelMeasuresSequence());
return sharedGroupSequence;
}
private static Object createFrameAnatomySequence() throws DicomException {
DicomObject item = new DicomObject();
item.set(DDict.dAnatomicRegionSequence, createAnatomicRegionSequence());
item.set(DDict.dFrameLaterality, "L ");
return item;
}
private static Object createAnatomicRegionSequence() throws DicomException {
DicomObject item = new DicomObject();
item.set(DDict.dCodeValue, "T-AA610 ");
item.set(DDict.dCodingSchemeDesignator, "SRT ");
item.set(DDict.dCodeMeaning, "Retina");
return item;
}
private static Object createPlaneOrientationSequence()
throws DicomException {
DicomObject item = new DicomObject();
// item.set(DDict.dImageOrientationPatient,
// "1.000000\\0.000000\\0.000000\\0.000000\\1.000000\\0.000000 ");
return item;
}
private static Object createPixelMeasuresSequence() throws DicomException {
DicomObject item = new DicomObject();
item.set(DDict.dSliceThickness, "0.252057");
item.set(DDict.dPixelSpacing, "0.003867\\0.005911 ");
return item;
}
private static DicomObject createReferencedImageSequence()
throws DicomException {
DicomObject item = new DicomObject();
item.set(DDict.dReferencedSOPClassUID,
"1.2.840.10008.5.1.4.1.1.77.1.5.1");
item.set(DDict.dReferencedSOPInstanceUID,
"1.3.6.1.4.1.33437.11.4.5604041.12963093945.145.4.0.0");
return item;
}
public DicomObject read(String location) throws IOException, DicomException {
FileInputStream fin = new FileInputStream(location);
DicomReader dcmReader = new DicomReader();
DicomObject dcm = dcmReader.read(fin, true);
return dcm;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment