Olá Pessoal,
Sou iniciante em Java, e estou querendo escrevendo um aplicativo que leia algumas imagens DICOM de um diretório qualquer.
Só pra esclarecer, DICOM é um formato padronizados de imagens médicas, além da propria imagem em si, o arquivo contem informacoes como nome de paciente, numero do estudo a qual ele pertence, numero da serie a qual pertence, ou seja, todas as informacoes do exame.
Antes de explicar o resto, um estudo se refere a um exame, que pode ter várias séries de imagens, cada série com várias imagens.
A ideia do aplicativo eh o seguinte, uma tabela lista todas as imagens de um diretório, agrupando-as segundo o ID (único) do estudo. Ao clicar em algum estudo, em uma outra tabela abaixo, seriam mostradas todas as séries pertecentes ao estudo.
O que eu já fiz esta postado embaixo, terminei a primeira parte, ou seja, agrupar um grupo de imagens de acordo com seu estudo.
ackage DicomDecoder;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import edu.ucla.loni.jdicom.DataElement;
import edu.ucla.loni.jdicom.DataSet;
import edu.ucla.loni.jdicom.decoder.DataSetDecoder;
import edu.ucla.loni.jdicom.decoder.MeasuredInputStream;
public class Dicom extends JFrame implements ActionListener {
JPanel panel;
JTextField diretorio;
JTable PatientTable,StudyTable;
JButton BAbrir;
String dir;
File file;
File[] fileArray;
String[] colunas = {"ID","Paciente","Modalidade","Study"};
String[] StudyTableColunas = {"Study UID","Modalidade","Data do Estudo","No. de Imagens"};
Vector<String> IDs = new Vector<String>();
Vector<String> StudyIDs = new Vector<String>();
Vector<DicomRecord> Records = new Vector<DicomRecord>();
MyTableModel model2 = new MyTableModel();
DefaultTableModel model = new DefaultTableModel(null,colunas){
public boolean isCellEdiPatientTable(int row, int column)
{
return false;
}};
DefaultTableModel StudyTableModel = new DefaultTableModel(null,StudyTableColunas){
public boolean isCellEdiPatientTable(int row, int column)
{
return false;
}};
Dicom() {
super("Dicom Decoder");
setSize(400,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
diretorio = new JTextField("E:\\Imagens\\Varias",30);
BAbrir = new JButton("Abrir");
BAbrir.addActionListener(this);
panel = new JPanel();
panel.add(diretorio);
//panel.add(pacientes);
panel.add(BAbrir);
PatientTable = new JTable();
PatientTable.setModel(model);
JScrollPane scroller = new javax.swing.JScrollPane(PatientTable);
PatientTable.setPreferredScrollableViewportSize(new Dimension(350, 300));
StudyTable = new JTable();
StudyTable.setModel(StudyTableModel);
JScrollPane scrollerStudy = new javax.swing.JScrollPane(StudyTable);
StudyTable.setPreferredScrollableViewportSize(new Dimension(350, 300));
panel.add(scroller);
panel.add(scrollerStudy);
add(panel);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Dicom dd = new Dicom();
dd.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == BAbrir) {
limparTable();
dir = diretorio.getText();
file = new File(dir);
fileArray = file.listFiles();
for (int i=0;i < fileArray.length; i++) {
try {
createRecordsTable(fileArray[i]);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
drawPatientTable();
}
}
private void limparTable() {
model.setRowCount(0);
}
// Cria os Vetores com ID e Records a partir de um arquivo
private void createRecordsTable(File file) throws IOException {
FileInputStream inputStream;
String path = file.getPath();
try {
inputStream = new FileInputStream(file);
MeasuredInputStream mis = new MeasuredInputStream(inputStream);
DataSet data = (new DataSetDecoder(mis)).getDataSet();
String StudyID = getStringValue(data,"0020000D");
if (StudyIDs.isEmpty()) {
StudyIDs.add(StudyID);
createDicomRecord(data,path);
} else if (StudyIDs.contains(StudyID)) {
int idx = StudyIDs.indexOf(StudyID);
DicomRecord dr = Records.get(idx);
addDataDicomRecord(dr,data,path);
} else {
StudyIDs.add(StudyID);
createDicomRecord(data,path);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void addDataDicomRecord(DicomRecord dr, DataSet data, String path) {
dr.addExame(getStringValue(data,"00080060"));
dr.addPath(path);
}
public byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("Arquivo muito grande");
}
byte[] bytes = new byte[(int)length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
is.close();
return bytes;
}
public String getStringValue(DataSet data, String tag) {
DataElement de = data.getDataElement(tag);
Enumeration enu = de.getValues();
Object value = enu.nextElement();
return value.toString();
}
public DicomRecord createDicomRecord(DataSet data,String path) {
DicomRecord dr = new DicomRecord();
dr.addPath(path);
dr.setID(getStringValue(data,"00100020"));
dr.setNome(getStringValue(data, "00100010"));
dr.addExame(getStringValue(data,"00080060"));
dr.setStudy(getStringValue(data,"00200010"));
Records.add(dr);
return dr;
}
public void drawPatientTable() {
String[] data = new String[colunas.length];
for (int i=0; i < Records.size() ;i++) {
data[0] = Records.get(i).getID();
data[1] = Records.get(i).getNome();
data[2] = Records.get(i).getExame(i);
data[3] = Records.get(i).getStudy();
model.addRow(data);
}
}
public void drawStudyTable(){
String[] data = new String[StudyTableColunas.length];
}
}
A forma que encontrei de agrupar esses IDs foi criar uma classe DicomRecord, que retira algumas informações do arquivo DICOM e criar um vetor Records com cada DicomRecord criada. Sendo que ele só cria outra DicomRecord se os 2 arquivos tiverem uma ID do estudo diferente.
Segue o código do DicomRecord:
package DicomDecoder;
import java.util.Vector;
public class DicomRecord {
protected String ID, Study;
protected String nome;
protected Vector<String> vexame = new Vector<String>();
protected Vector<String> vpath = new Vector<String>();
public DicomRecord() {
ID = "";
nome = "";
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getStudy() {
return Study;
}
public void setStudy(String Study) {
this.Study = Study;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Vector getExame() {
return vexame;
}
public String getExame(int index) {
return vexame.get(index);
}
public void addExame(String exame) {
vexame.add(exame);
}
public void addPath(String path) {
vpath.add(path);
}
public Vector getPath() {
return vpath;
}
}
O problema é o seguinte, pra criar a segunda tabela, com as séries de cada estudo, fica complicado dessa forma que eu fiz. A melhor forma de lidar com esse problema é realmente criar um vetor Records com cada DicomRecord? Ou criar outras classes que facam o trabalho?
Desculpem a mensagem tao longa… mas acho q essa dúvida responde perguntas pra quem tem problemas de manipular varias informacoes que sao organizadas hierarquicamente, como nesse problema…
[]'s!!!
Gabriel Costa