• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/DGVImageVTK.cpp

Go to the documentation of this file.
00001 
00022 #include "DGVImageVTK.h"
00023 
00024 #include <QFileDialog>
00025 
00026 #include "vtkPNGReader.h"
00027 #include "vtkPNGWriter.h"
00028 #include "vtkJPEGReader.h"
00029 #include "vtkJPEGWriter.h"
00030 #include "vtkTIFFReader.h"
00031 #include "vtkTIFFWriter.h"
00032 #include "vtkPNMReader.h"
00033 #include "vtkPNMWriter.h"
00034 #include "vtkBMPReader.h"
00035 #include "vtkBMPWriter.h"
00036 #include "vtkPostScriptWriter.h"
00037 #include "vtkGDCMImageReader.h"
00038 #include "vtkGDCMImageWriter.h"
00039 #include "vtkXMLImageDataReader.h"
00040 #include "vtkXMLImageDataWriter.h"
00041 #include "vtkStructuredPoints.h"
00042 #include "vtkStructuredPointsReader.h"
00043 #include "vtkStructuredPointsWriter.h"
00044 #include "vtkImageActor.h"
00045 #include "vtkImageCast.h"
00046 #include "vtkImageMapToWindowLevelColors.h"
00047 #include "vtkImageClip.h"
00048 #include "vtkImageAccumulate.h"
00049 #include "vtkCamera.h"
00050 #include "vtkCallbackCommand.h"
00051 #include "vtkEventForwarderCommand.h"
00052 
00053 #include "DGImage.hpp"
00054 
00055 extern "C"
00056 {
00057     #include "contrib/libtarga.h"
00058 }
00059 
00060 DGVImageVTK::DGVImageVTK(QWidget *parent) : QVTKWidget(parent)
00061 {
00062     loaded = false;
00063     arrayLoaded = false;
00064     imageDataSource = false;
00065     imageDataLoaded = false;
00066     externalData = false;
00067     viewing = false;
00068     volume = false;
00069     complexData = false;
00070     consoleAssigned = false;
00071     verboseMode = true;
00072     enableVolumes = false;
00073     permuted = false;
00074     sliceInView = 0;
00075     outputPort = NULL;
00076 
00077     timerInterval = 0.0;
00078     timerId = -1;
00079 
00080     Blitz.alignmentForImages(true);
00081 
00083     createActions();
00084     complexValuedMode(false);
00085 
00087         createConnections();
00088 }
00089 
00090 DGVImageVTK::DGVImageVTK(QVector<QMenu*> &menus, QWidget *parent) : QVTKWidget(parent)
00091 {
00092     loaded = false;
00093     arrayLoaded = false;
00094     imageDataSource = false;
00095     imageDataLoaded = false;
00096     externalData = false;
00097     viewing = false;
00098     volume = false;
00099     complexData = false;
00100     consoleAssigned = false;
00101     verboseMode = true;
00102     enableVolumes = true;
00103     sliceInView = 0;
00104     outputPort = NULL;
00105 
00106     timerInterval = 0.0;
00107     timerId = -1;
00108 
00109     Blitz.alignmentForImages(true);
00110 
00112     createActions();
00113     complexValuedMode(false);
00114 
00116     addToContextMenu(menus);
00117 
00119         createConnections();
00120 }
00121 
00122 DGVImageVTK::~DGVImageVTK()
00123 {
00124     /*if(loaded && !externalData)
00125         if(imageDataSource || imageDataLoaded)
00126             imageData->Delete();*/ 
00127     if(viewing)
00128         viewer->Delete();
00129     if(permuted)
00130         permute->Delete();
00131 }
00132 
00133 void DGVImageVTK::setName(QString filename)
00134 {
00135     name = filename;
00136     setWindowTitle(strippedNamePrefix());
00137 }
00138 
00139 bool DGVImageVTK::openImage(QString filename)
00140 {
00141         setName(filename);
00142     QWidget::setWindowTitle(strippedName());
00143 
00144     QFileInfo fi(name);
00145     QString extension = fi.suffix().toLower();
00146 
00147     printInfo("Extension of Image is " + extension);
00148         if(extension == "png")
00149                 return openPNG();
00150         else if(extension == "jpg" || extension == "jpeg")
00151                 return openJPEG();
00152         else if(extension == "tif" || extension == "tiff")
00153                 return openTIFF();
00154         else if(extension == "pnm" || extension == "pgm" || extension == "pbm" || extension == "ppm")
00155                 return openPNM();
00156         else if(extension == "bmp")
00157                 return openBMP();
00158         else if(extension == "dcm" || extension == "dicom")
00159                 return openDICOM();
00160     else if(extension == "vti")
00161         return openVTI();
00162     else if(extension == "vtk")
00163         return openVTK();
00164     else if(extension == "tga")
00165         return openTGA();
00166         else
00167         {
00168             extension = fi.completeSuffix().toLower();
00169             if( extension.contains("pnm.", Qt::CaseInsensitive) || extension.contains("ppm.", Qt::CaseInsensitive)
00170             || extension.contains("pgm.", Qt::CaseInsensitive) || extension.contains("pbm.", Qt::CaseInsensitive) )
00171             return openPNMVolume();
00172         else if( extension.contains("png.") )
00173             return openPNGVolume();
00174         else
00175             return false;
00176         }
00177 }
00178 
00179 bool DGVImageVTK::saveImage(QString filename)
00180 {
00181     if(!filename.isEmpty())
00182     {
00183         QFileInfo fi(filename);
00184         QString extension = fi.suffix().toLower(), format;
00185         bool success = false;
00186 
00187         printInfo("Extension of Image will be " + extension);
00189         if(extension == "png")
00190         {
00191             format = "PNG format.";
00192             success = savePNG(filename);
00193         }
00194         else if(extension == "jpg" || extension == "jpeg")
00195         {
00196             format = "JPEG format.";
00197             success = saveJPEG(filename);
00198         }
00199         else if(extension == "tif" || extension == "tiff")
00200         {
00201             format = "TIFF format.";
00202             success = saveTIFF(filename);
00203         }
00204         else if(extension == "pnm" || extension == "pgm" || extension == "pbm" || extension == "ppm")
00205         {
00206             format = "PNM format.";
00207             success = savePNM(filename);
00208         }
00209         else if(extension == "bmp")
00210         {
00211             format = "BMP format.";
00212             success = saveBMP(filename);
00213         }
00214         else if(extension == "ps")
00215         {
00216             format = "PS format.";
00217             success = savePS(filename);
00218         }
00219         else if(extension == "vti")
00220         {
00221             format = "VTI format.";
00222             success = saveVTI(filename);
00223         }
00224         else if(extension == "vtk")
00225         {
00226             format = "VTK (legacy) format.";
00227             success = saveVTK(filename);
00228         }
00229         else if(extension == "dcm" || extension == "dicom")
00230         {
00231             format = "DICOM format.";
00232             success = saveDICOM(filename);
00233         }
00234         else if(extension == "tga")
00235         {
00236             format = "TGA format.";
00237             success = saveTGA(filename);
00238         }
00239         else
00240         {
00241             printError("Error: Unknown format. Not Saving.");
00242             success = false;
00243         }
00244 
00245         printInfo("Saving as file: " + filename + " having extension: " + extension + " as " + format);
00246         emit recentFileAvailable(filename);
00247         return success;
00248     }
00249 
00250     return false;
00251 }
00252 
00253 bool DGVImageVTK::saveImage()
00254 {
00255     QFileDialog *fileSaver = new QFileDialog(this);
00256     QSettings settings("Shakes", "DGV");
00257 
00258     QString path = settings.value("recentPath").toString();
00259     QString filename = fileSaver->getSaveFileName(this,
00260                                    tr("Select File Name to Save"),
00261                                    path,
00262     tr("Images [8-Bit Colour] (*.png *.jpeg *.jpg *.bmp *.tiff *.tif *.tga *.dcm *.dicom);;Images [Arbitrary] (*.pgm *.vti *.vtk);;Vectorised (*.ps)"));
00263 
00264     return saveImage(filename);
00265 }
00266 
00267 bool DGVImageVTK::openStack(QString filename)
00268 {
00269     setName(filename);
00270     QWidget::setWindowTitle(strippedName());
00271 
00272     QFileInfo fi(name);
00273     QString extension = fi.suffix().toLower();
00274 
00275     printInfo("Extension of Image is " + extension);
00276         if(extension == "png")
00277                 return openPNGVolume();
00278         else if(extension == "jpg" || extension == "jpeg")
00279                 return openJPEGVolume();
00280         else if(extension == "tif" || extension == "tiff")
00281                 return openTIFFVolume();
00282         else if(extension == "pnm" || extension == "pgm" || extension == "pbm" || extension == "ppm")
00283                 return openPNMVolume();
00284         else if(extension == "bmp")
00285                 return openBMPVolume();
00286     else
00287         return false;
00288 }
00289 
00290 bool DGVImageVTK::saveStack()
00291 {
00292     QSettings settings("Shakes", "DGV");
00293     QString path = settings.value("recentPath").toString(), filename;
00294 
00295     QFileDialog *fileSaver = new QFileDialog(this);
00296 
00297     filename = fileSaver->getSaveFileName(this,
00298                                tr("Enter First File Name (with extension)"),
00299                                path,
00300                                tr("Images (*.png *.pnm *.ppm *.pgm *.pbm *.jpeg *.jpg *.bmp *.tiff *.tif)"));
00301 
00302     if (!filename.isEmpty())
00303         return saveStack(filename);
00304     else
00305         return false;
00306 }
00307 
00308 bool DGVImageVTK::saveStack(QString filename)
00309 {
00310     QFileInfo fi(filename);
00311     QString extension = fi.suffix().toLower();
00312 
00313     printInfo("Extension of Image is " + extension);
00314     if(extension == "png")
00315                 return savePNGVolume(filename);
00316     else if(extension == "jpg" || extension == "jpeg")
00317                 return saveJPEGVolume(filename);
00318         else if(extension == "tif" || extension == "tiff")
00319                 return saveTIFFVolume(filename);
00320         else if(extension == "pnm" || extension == "pgm" || extension == "pbm" || extension == "ppm")
00321                 return savePNMVolume(filename);
00322         else if(extension == "bmp")
00323                 return saveBMPVolume(filename);
00324     else
00325         return false;
00326 }
00327 
00328 bool DGVImageVTK::openPNG()
00329 {
00330         vtkPNGReader* reader = vtkPNGReader::New();
00331 
00332     if(reader->CanReadFile(name.toStdString().c_str()))
00333     {
00334         printInfo("Opening " + name + " as PNG File");
00335         reader->SetFileName(name.toStdString().c_str());
00336         reader->Update();
00337         imageData = reader->GetOutput();
00338 
00339         if(!viewing)
00340         {
00341             viewer = ImageViewer::New();
00342             viewing = true;
00343         }
00344         outputPort = reader->GetOutputPort();
00345 
00346         setupViewerFromReader(); //Loaded set in here
00347     }
00348     else
00349         loaded = false;
00350 
00351     reader->Delete();
00352         return loaded;
00353 }
00354 
00355 bool DGVImageVTK::savePNG(const QString filename)
00356 {
00357         vtkPNGWriter* writer = vtkPNGWriter::New();
00358 
00359     if(!imageDataLoaded)
00360         arrayToData();
00361 
00363     printInfo("Casting data to 8-bit Greyscale based on Window Level");
00364     writer->SetInputConnection(viewer->GetWindowLevel()->GetOutputPort());
00365     writer->SetFileName(filename.toStdString().c_str());
00366     writer->Write();
00367     writer->Delete();
00368 
00369         return true;
00370 }
00371 
00372 bool DGVImageVTK::openPNGVolume()
00373 {
00374     vtkPNGReader* reader = vtkPNGReader::New();
00375 
00376         bool ok1, ok2, ok3;
00377         int start = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00378                                           tr("Enter Volume Start:"), 0, -2147483647, 2147483647, 1, &ok1);
00379         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00380                                           tr("Enter Volume End (inclusive):"), 10, -2147483647, 2147483647, 1, &ok2);
00381     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00382                                           tr("Pattern:"), QLineEdit::Normal,
00383                                           "%s%i.png", &ok3);
00384 
00385     QString tmp, tmpName, tmp1, tmp2;
00386     QFileInfo stripper(name);
00387     tmp = stripper.suffix();
00388     tmpName = stripper.baseName();
00389     printInfo("Volume Stack Name to be used: " + tmpName);
00390     printInfo("Volume Stack to be read from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00391 
00392     if(reader->CanReadFile(name.toStdString().c_str()) && ok1 && ok2 && ok3)
00393     {
00394         int bounds[6] = {0};
00395         bounds[4] = start;
00396         bounds[5] = end;
00397 
00398         reader->SetDataExtent(bounds);
00399         tmpName.remove(QRegExp("\\d+$")); 
00400         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00401         tmpName = stripper.path() + "/" + tmpName; 
00402         reader->SetFilePrefix(tmpName.toStdString().c_str());
00403         reader->SetFilePattern(prefix.toStdString().c_str());
00404         reader->Update();
00405         loaded = true;
00406 
00407         imageData = reader->GetOutput();
00408         imageData->Update();
00409         outputPort = reader->GetOutputPort();
00410 
00412         volume = true;
00413         if(enableVolumes)
00414             generateVolume();
00415 
00416         if(!viewing)
00417         {
00418             viewer = ImageViewer::New();
00419             viewing = true;
00420         }
00421 
00422         setupViewerFromReader(); //Loaded set in here
00423     }
00424     else
00425         loaded = false;
00426 
00427     reader->Delete();
00428     return loaded;
00429 }
00430 
00431 bool DGVImageVTK::savePNGVolume(const QString filename)
00432 {
00433     vtkPNGWriter* writer = vtkPNGWriter::New();
00434 
00435     if(!loaded)
00436         return false;
00437 
00438     if(!imageDataLoaded)
00439         arrayToData();
00440 
00441     int bounds[6] = {0};
00442 
00443     imageData->GetExtent(bounds);
00444 
00445         bool ok1, ok2, ok3;
00446         int start = QInputDialog::getInteger(this, tr("Write Volume stack to ranges."),
00447                                           tr("Enter Volume Start:"), 0, 0, bounds[4], 1, &ok1);
00448         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00449                                           tr("Enter Volume End (inclusive):"), bounds[5], 0, bounds[5], 1, &ok2);
00450     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00451                                           tr("Pattern:"), QLineEdit::Normal,
00452                                           "%s%i.png", &ok3);
00453 
00454     QString tmp, tmpName, tmp1, tmp2;
00455     QFileInfo stripper(filename);
00456     tmp = stripper.suffix();
00457     tmpName = stripper.baseName();
00458     printInfo("Volume Stack Name to be used: " + tmpName);
00459     printInfo("Volume Stack to be written from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00460 
00461     if(ok1 && ok2 && ok3)
00462     {
00463         tmpName.remove(QRegExp("\\d+$")); 
00464         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00465         tmpName = stripper.path() + "/" + tmpName; 
00466         writer->SetInput(imageData);
00467         writer->SetFilePrefix(tmpName.toStdString().c_str());
00468         writer->SetFilePattern(prefix.toStdString().c_str());
00469         writer->Write();
00470         writer->Delete();
00471 
00472         return true;
00473     }
00474     else
00475         return false;
00476 }
00477 
00478 bool DGVImageVTK::openJPEG()
00479 {
00480         vtkJPEGReader* reader = vtkJPEGReader::New();
00481 
00482     if(reader->CanReadFile(name.toStdString().c_str()))
00483     {
00484         reader->SetFileName(name.toStdString().c_str());
00485         reader->Update();
00486         imageData = reader->GetOutput();
00487 
00488         if(!viewing)
00489         {
00490             viewer = ImageViewer::New();
00491             viewing = true;
00492         }
00493         outputPort = reader->GetOutputPort();
00494 
00495         setupViewerFromReader(); //Loaded set in here
00496     }
00497     else
00498         loaded = false;
00499 
00500     reader->Delete();
00501         return loaded;
00502 }
00503 
00504 bool DGVImageVTK::saveJPEG(const QString filename)
00505 {
00506         vtkJPEGWriter* writer = vtkJPEGWriter::New();
00507 
00508     if(!imageDataLoaded)
00509         arrayToData();
00510 
00512     printInfo("Casting data to 8-bit Greyscale based on Window Level");
00513     writer->SetInputConnection(viewer->GetWindowLevel()->GetOutputPort());
00514     writer->SetFileName(filename.toStdString().c_str());
00515     writer->Write();
00516     writer->Delete();
00517 
00518         return true;
00519 }
00520 
00521 bool DGVImageVTK::openJPEGVolume()
00522 {
00523     vtkJPEGReader* reader = vtkJPEGReader::New();
00524 
00525         bool ok1, ok2, ok3;
00526         int start = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00527                                           tr("Enter Volume Start:"), 0, -2147483647, 2147483647, 1, &ok1);
00528         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00529                                           tr("Enter Volume End (inclusive):"), 10, -2147483647, 2147483647, 1, &ok2);
00530     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00531                                           tr("Pattern:"), QLineEdit::Normal,
00532                                           "%s%i.jpg", &ok3);
00533 
00534     QString tmp, tmpName, tmp1, tmp2;
00535     QFileInfo stripper(name);
00536     tmp = stripper.suffix();
00537     tmpName = stripper.baseName();
00538     printInfo("Volume Stack Name to be used: " + tmpName);
00539     printInfo("Volume Stack to be read from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00540 
00541     if(reader->CanReadFile(name.toStdString().c_str()) && ok1 && ok2 && ok3)
00542     {
00543         int bounds[6] = {0};
00544         bounds[4] = start;
00545         bounds[5] = end;
00546 
00547         reader->SetDataExtent(bounds);
00548         tmpName.remove(QRegExp("\\d+$")); 
00549         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00550         tmpName = stripper.path() + "/" + tmpName; 
00551         reader->SetFilePrefix(tmpName.toStdString().c_str());
00552         reader->SetFilePattern(prefix.toStdString().c_str());
00553         reader->Update();
00554         loaded = true;
00555 
00556         imageData = reader->GetOutput();
00557         imageData->Update();
00558         outputPort = reader->GetOutputPort();
00559 
00561         volume = true;
00562         if(enableVolumes)
00563             generateVolume();
00564 
00565         if(!viewing)
00566         {
00567             viewer = ImageViewer::New();
00568             viewing = true;
00569         }
00570 
00571         setupViewerFromReader(); //Loaded set in here
00572     }
00573     else
00574         loaded = false;
00575 
00576     reader->Delete();
00577     return loaded;
00578 }
00579 
00580 bool DGVImageVTK::saveJPEGVolume(const QString filename)
00581 {
00582     vtkJPEGWriter* writer = vtkJPEGWriter::New();
00583 
00584     if(!loaded)
00585         return false;
00586 
00587     if(!imageDataLoaded)
00588         arrayToData();
00589 
00590     int bounds[6] = {0};
00591 
00592     imageData->GetExtent(bounds);
00593 
00594         bool ok1, ok2, ok3;
00595         int start = QInputDialog::getInteger(this, tr("Write Volume stack to ranges."),
00596                                           tr("Enter Volume Start:"), 0, 0, bounds[4], 1, &ok1);
00597         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00598                                           tr("Enter Volume End (inclusive):"), bounds[5], 0, bounds[5], 1, &ok2);
00599     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00600                                           tr("Pattern:"), QLineEdit::Normal,
00601                                           "%s%i.jpg", &ok3);
00602 
00603     QString tmp, tmpName, tmp1, tmp2;
00604     QFileInfo stripper(filename);
00605     tmp = stripper.suffix();
00606     tmpName = stripper.baseName();
00607     printInfo("Volume Stack Name to be used: " + tmpName);
00608     printInfo("Volume Stack to be written from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00609 
00610     if(ok1 && ok2 && ok3)
00611     {
00612         tmpName.remove(QRegExp("\\d+$")); 
00613         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00614         tmpName = stripper.path() + "/" + tmpName; 
00615         writer->SetInput(imageData);
00616         writer->SetFilePrefix(tmpName.toStdString().c_str());
00617         writer->SetFilePattern(prefix.toStdString().c_str());
00618         writer->Write();
00619         writer->Delete();
00620 
00621         return true;
00622     }
00623     else
00624         return false;
00625 }
00626 
00627 bool DGVImageVTK::openTIFF()
00628 {
00629         vtkTIFFReader* reader = vtkTIFFReader::New();
00630 
00631     if(reader->CanReadFile(name.toStdString().c_str()))
00632     {
00633         reader->SetFileName(name.toStdString().c_str());
00634         reader->Update();
00635         imageData = reader->GetOutput();
00636 
00637         if(!viewing)
00638         {
00639             viewer = ImageViewer::New();
00640             viewing = true;
00641         }
00642         outputPort = reader->GetOutputPort();
00643 
00644         setupViewerFromReader(); //Loaded set in here
00645     }
00646     else
00647         loaded = false;
00648 
00649     reader->Delete();
00650         return loaded;
00651 }
00652 
00653 bool DGVImageVTK::saveTIFF(const QString filename)
00654 {
00655         vtkTIFFWriter* writer = vtkTIFFWriter::New();
00656 
00657     if(!imageDataLoaded)
00658         arrayToData();
00659 
00661     printInfo("Casting data to 8-bit Greyscale based on Window Level");
00662     writer->SetInputConnection(viewer->GetWindowLevel()->GetOutputPort());
00663     writer->SetFileName(filename.toStdString().c_str());
00664     writer->Write();
00665     writer->Delete();
00666 
00667         return true;
00668 }
00669 
00670 bool DGVImageVTK::openTIFFVolume()
00671 {
00672     vtkTIFFReader* reader = vtkTIFFReader::New();
00673 
00674         bool ok1, ok2, ok3;
00675         int start = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00676                                           tr("Enter Volume Start:"), 0, -2147483647, 2147483647, 1, &ok1);
00677         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00678                                           tr("Enter Volume End (inclusive):"), 10, -2147483647, 2147483647, 1, &ok2);
00679     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00680                                           tr("Pattern:"), QLineEdit::Normal,
00681                                           "%s%i.tif", &ok3);
00682 
00683     QString tmp, tmpName, tmp1, tmp2;
00684     QFileInfo stripper(name);
00685     tmp = stripper.suffix();
00686     tmpName = stripper.baseName();
00687     printInfo("Volume Stack Name to be used: " + tmpName);
00688     printInfo("Volume Stack to be written from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00689 
00690     if(reader->CanReadFile(name.toStdString().c_str()) && ok1 && ok2 && ok3)
00691     {
00692         int bounds[6] = {0};
00693         bounds[4] = start;
00694         bounds[5] = end;
00695 
00696         reader->SetDataExtent(bounds);
00697         tmpName.remove(QRegExp("\\d+$")); 
00698         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00699         tmpName = stripper.path() + "/" + tmpName; 
00700         reader->SetFilePrefix(tmpName.toStdString().c_str());
00701         reader->SetFilePattern(prefix.toStdString().c_str());
00702         reader->Update();
00703         loaded = true;
00704 
00705         imageData = reader->GetOutput();
00706         imageData->Update();
00707         outputPort = reader->GetOutputPort();
00708 
00710         volume = true;
00711         if(enableVolumes)
00712             generateVolume();
00713 
00714         if(!viewing)
00715         {
00716             viewer = ImageViewer::New();
00717             viewing = true;
00718         }
00719 
00720         setupViewerFromReader(); //Loaded set in here
00721     }
00722     else
00723         loaded = false;
00724 
00725     reader->Delete();
00726     return loaded;
00727 }
00728 
00729 bool DGVImageVTK::saveTIFFVolume(const QString filename)
00730 {
00731     vtkTIFFWriter* writer = vtkTIFFWriter::New();
00732 
00733     if(!loaded)
00734         return false;
00735 
00736     if(!imageDataLoaded)
00737         arrayToData();
00738 
00739     int bounds[6] = {0};
00740 
00741     imageData->GetExtent(bounds);
00742 
00743         bool ok1, ok2, ok3;
00744         int start = QInputDialog::getInteger(this, tr("Write Volume stack to ranges."),
00745                                           tr("Enter Volume Start:"), 0, 0, bounds[4], 1, &ok1);
00746         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00747                                           tr("Enter Volume End (inclusive):"), bounds[5], 0, bounds[5], 1, &ok2);
00748     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00749                                           tr("Pattern:"), QLineEdit::Normal,
00750                                           "%s%i.tif", &ok3);
00751 
00752     QString tmp, tmpName, tmp1, tmp2;
00753     QFileInfo stripper(filename);
00754     tmp = stripper.suffix();
00755     tmpName = stripper.baseName();
00756     printInfo("Volume Stack Name to be used: " + tmpName);
00757     printInfo("Volume Stack to be read from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00758 
00759     if(ok1 && ok2 && ok3)
00760     {
00761         tmpName.remove(QRegExp("\\d+$")); 
00762         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00763         tmpName = stripper.path() + "/" + tmpName; 
00764         writer->SetInput(imageData);
00765         writer->SetFilePrefix(tmpName.toStdString().c_str());
00766         writer->SetFilePattern(prefix.toStdString().c_str());
00767         writer->Write();
00768         writer->Delete();
00769 
00770         return true;
00771     }
00772     else
00773         return false;
00774 }
00775 
00776 bool DGVImageVTK::openPNM()
00777 {
00778     DGImage<imageType> imageReader;
00779         vtkPNMReader* reader = vtkPNMReader::New();
00780 
00781         if(imageReader.isPNMBinaryFormat(name.toStdString()))
00782         {
00783         printInfo("Binary Format: Using VTK Reader");
00784 
00785         if(reader->CanReadFile(name.toStdString().c_str()))
00786         {
00787             reader->SetFileName(name.toStdString().c_str());
00788             reader->Update();
00789             imageData = reader->GetOutput();
00790 
00791             if(!viewing)
00792             {
00793                 viewer = ImageViewer::New();
00794                 viewing = true;
00795             }
00796             outputPort = reader->GetOutputPort();
00797 
00798             setupViewerFromReader(); //Loaded set in here
00799         }
00800         else
00801         {
00802             printError("Error loading Binary PNM File");
00803             loaded = false;
00804         }
00805 
00806         reader->Delete();
00807         }
00808         else
00809         {
00810             int grey = 0;
00811         printInfo("ASCII Format: Using Custom Reader");
00812         imageArray = 0;
00813         if(imageReader.readPNM(name.toStdString(),imageArray,grey))
00814         {
00815             arrayLoaded = true;
00816             loaded = true;
00817             DGVImageVTK::arrayToData();
00818             imageDataSource = false;
00819             generateImage();
00820             return true;
00821         }
00822         else
00823         {
00824             printError("Error loading ASCII PNM File");
00825             return false;
00826         }
00827         }
00828 
00829         return loaded;
00830 }
00831 
00832 bool DGVImageVTK::savePNM(const QString filename)
00833 {
00834     DGImage<imageType> imageWriter;
00835 
00836     if(!arrayLoaded)
00837         dataToArray();
00838 
00839     imageWriter.writePNM(imageArray,Blitz.getMax(),filename.toStdString());
00840 
00841         return true;
00842 }
00843 
00844 bool DGVImageVTK::openPNMVolume()
00845 {
00846     DGImage<imageType> imageReader;
00847         vtkPNMReader* reader = vtkPNMReader::New();
00848 
00849         bool ok1, ok2, ok3;
00850         int start = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00851                                           tr("Enter Volume Start:"), 0, -2147483647, 2147483647, 1, &ok1);
00852         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00853                                           tr("Enter Volume End (inclusive):"), 10, -2147483647, 2147483647, 1, &ok2);
00854     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00855                                           tr("Pattern:"), QLineEdit::Normal,
00856                                           "%s%i.pgm", &ok3);
00857 
00858         if(imageReader.isPNMBinaryFormat(name.toStdString()) && ok1 && ok2 && ok3)
00859         {
00860         printInfo("Binary Format: Using VTK Reader");
00861 
00862         QString tmp, tmpName, tmp1, tmp2;
00863         QFileInfo stripper(name);
00864 
00866         tmp = stripper.suffix();
00867         tmpName = stripper.baseName();
00868         printInfo("Volume Stack Name to be used: " + tmpName);
00869         printInfo("Volume Stack to be read from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00870 
00871         if(reader->CanReadFile(name.toStdString().c_str()))
00872         {
00873             int bounds[6] = {0};
00874             bounds[4] = start;
00875             bounds[5] = end;
00876 
00877             reader->SetDataExtent(bounds);
00878             tmpName.remove(QRegExp("\\d+$")); 
00879             printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00880             tmpName = stripper.path() + "/" + tmpName; 
00881             reader->SetFilePrefix(tmpName.toStdString().c_str());
00882             reader->SetFilePattern(prefix.toStdString().c_str());
00883             reader->Update();
00884             loaded = true;
00885 
00886             imageData = reader->GetOutput();
00887             imageData->Update();
00888             outputPort = reader->GetOutputPort();
00889 
00891             volume = true;
00892             if(enableVolumes)
00893                 generateVolume();
00894 
00895             if(!viewing)
00896             {
00897                 viewer = ImageViewer::New();
00898                 viewing = true;
00899             }
00900 
00901             setupViewerFromReader(); //Loaded set in here
00902         }
00903         else
00904             loaded = false;
00905 
00906         reader->Delete();
00907         }
00908         else
00909         {
00910             int grey = 0;
00911             Array<imageType,3> tmpArray;
00912             QFileInfo fi(name);
00913             QString ext = fi.suffix(), tmpName;
00914             bool success = true;
00915 
00916         printInfo("ASCII Format: Using Custom Reader");
00917         imageArray = 0;
00918 
00919         tmpName = name;
00920         tmpName.truncate(tmpName.size()-ext.size()-1); 
00921         ext = ".";
00922         ext += numToString(start).c_str();
00923         tmpName += ext;
00924         if(!imageReader.readPNM(tmpName.toStdString(),imageArray,grey))
00925             return false;
00926         else
00927         {
00928             tmpArray.resizeAndPreserve(imageArray.rows(),imageArray.cols(),end-start+1);
00929             tmpArray(Range::all(),Range::all(),0) = imageArray;
00930             for(int j = start+1; j <= end; j ++)
00931             {
00932                 tmpName.truncate(tmpName.size()-ext.size()); 
00933                 ext = ".";
00934                 ext += numToString(j).c_str();
00935                 tmpName += ext;
00936                 success = imageReader.readPNM(tmpName.toStdString(),imageArray,grey);
00937                 if(!success)
00938                     break;
00939                 tmpArray(Range::all(),Range::all(),j-start) = imageArray;
00940             }
00941             loaded = true;
00942             imageData = Blitz.arrayToVTKImageData(tmpArray);
00943             imageDataLoaded = true;
00944             imageDataSource = true;
00945             arrayLoaded = false;
00946             refresh();
00947 
00948             return true;
00949         }
00950         }
00951 
00952         return loaded;
00953 }
00954 
00955 bool DGVImageVTK::savePNMVolume(const QString filename)
00956 {
00957     vtkPNMWriter* writer = vtkPNMWriter::New();
00958 
00959     if(!loaded)
00960         return false;
00961 
00962     if(!imageDataLoaded)
00963         arrayToData();
00964 
00965     int bounds[6] = {0};
00966 
00967     imageData->GetExtent(bounds);
00968 
00969         bool ok1, ok2, ok3;
00970         int start = QInputDialog::getInteger(this, tr("Write Volume stack to ranges."),
00971                                           tr("Enter Volume Start:"), 0, 0, bounds[4], 1, &ok1);
00972         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
00973                                           tr("Enter Volume End (inclusive):"), bounds[5], 0, bounds[5], 1, &ok2);
00974     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
00975                                           tr("Pattern:"), QLineEdit::Normal,
00976                                           "%s%i.pgm", &ok3);
00977 
00978     QString tmp, tmpName, tmp1, tmp2;
00979     QFileInfo stripper(filename);
00980     tmp = stripper.suffix();
00981     tmpName = stripper.baseName();
00982     printInfo("Volume Stack Name to be used: " + tmpName);
00983     printInfo("Volume Stack to be written from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
00984 
00985     if(ok1 && ok2 && ok3)
00986     {
00987         tmpName.remove(QRegExp("\\d+$")); 
00988         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
00989         tmpName = stripper.path() + "/" + tmpName; 
00990         writer->SetInput(imageData);
00991         writer->SetFilePrefix(tmpName.toStdString().c_str());
00992         writer->SetFilePattern(prefix.toStdString().c_str());
00993         writer->Write();
00994         writer->Delete();
00995 
00996         return true;
00997     }
00998     else
00999         return false;
01000 }
01001 
01002 bool DGVImageVTK::openBMP()
01003 {
01004         vtkBMPReader* reader = vtkBMPReader::New();
01005 
01006     if(reader->CanReadFile(name.toStdString().c_str()))
01007     {
01008         reader->SetFileName(name.toStdString().c_str());
01009         reader->Update();
01010         imageData = reader->GetOutput();
01011 
01012         if(!viewing)
01013         {
01014             viewer = ImageViewer::New();
01015             viewing = true;
01016         }
01017         outputPort = reader->GetOutputPort();
01018 
01019         setupViewerFromReader(); //Loaded set in here
01020     }
01021     else
01022         loaded = false;
01023 
01024     reader->Delete();
01025         return loaded;
01026 }
01027 
01028 bool DGVImageVTK::saveBMP(const QString filename)
01029 {
01030         vtkBMPWriter* writer = vtkBMPWriter::New();
01031 
01032     if(!imageDataLoaded)
01033         arrayToData();
01034 
01036     printInfo("Casting data to 8-bit Greyscale based on Window Level");
01037     writer->SetInputConnection(viewer->GetWindowLevel()->GetOutputPort());
01038     writer->SetFileName(filename.toStdString().c_str());
01039     writer->Write();
01040     writer->Delete();
01041 
01042         return true;
01043 }
01044 
01045 bool DGVImageVTK::openBMPVolume()
01046 {
01047     vtkBMPReader* reader = vtkBMPReader::New();
01048 
01049         bool ok1, ok2, ok3;
01050         int start = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
01051                                           tr("Enter Volume Start:"), 0, -2147483647, 2147483647, 1, &ok1);
01052         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
01053                                           tr("Enter Volume End (inclusive):"), 10, -2147483647, 2147483647, 1, &ok2);
01054     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
01055                                           tr("Pattern:"), QLineEdit::Normal,
01056                                           "%s%i.bmp", &ok3);
01057 
01058     QString tmp, tmpName, tmp1, tmp2;
01059     QFileInfo stripper(name);
01060     tmp = stripper.suffix();
01061     tmpName = stripper.baseName();
01062     printInfo("Volume Stack Name to be used: " + tmpName);
01063     printInfo("Volume Stack to be read from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
01064 
01065     if(reader->CanReadFile(name.toStdString().c_str()) && ok1 && ok2 && ok3)
01066     {
01067         int bounds[6] = {0};
01068         bounds[4] = start;
01069         bounds[5] = end;
01070 
01071         reader->SetDataExtent(bounds);
01072         tmpName.remove(QRegExp("\\d+$")); 
01073         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
01074         tmpName = stripper.path() + "/" + tmpName; 
01075         reader->SetFilePrefix(tmpName.toStdString().c_str());
01076         reader->SetFilePattern(prefix.toStdString().c_str());
01077         reader->Update();
01078         loaded = true;
01079 
01080         imageData = reader->GetOutput();
01081         imageData->Update();
01082         outputPort = reader->GetOutputPort();
01083 
01085         volume = true;
01086         if(enableVolumes)
01087             generateVolume();
01088 
01089         if(!viewing)
01090         {
01091             viewer = ImageViewer::New();
01092             viewing = true;
01093         }
01094 
01095         setupViewerFromReader(); //Loaded set in here
01096     }
01097     else
01098         loaded = false;
01099 
01100     reader->Delete();
01101     return loaded;
01102 }
01103 
01104 bool DGVImageVTK::saveBMPVolume(const QString filename)
01105 {
01106     vtkBMPWriter* writer = vtkBMPWriter::New();
01107 
01108     if(!loaded)
01109         return false;
01110 
01111     if(!imageDataLoaded)
01112         arrayToData();
01113 
01114     int bounds[6] = {0};
01115 
01116     imageData->GetExtent(bounds);
01117 
01118         bool ok1, ok2, ok3;
01119         int start = QInputDialog::getInteger(this, tr("Write Volume stack to ranges."),
01120                                           tr("Enter Volume Start:"), 0, 0, bounds[4], 1, &ok1);
01121         int end = QInputDialog::getInteger(this, tr("Read Volume stack from ranges."),
01122                                           tr("Enter Volume End (inclusive):"), bounds[5], 0, bounds[5], 1, &ok2);
01123     QString prefix = QInputDialog::getText(this, tr("Filename Pattern (in printf format)"),
01124                                           tr("Pattern:"), QLineEdit::Normal,
01125                                           "%s%i.bmp", &ok3);
01126 
01127     QString tmp, tmpName, tmp1, tmp2;
01128     QFileInfo stripper(filename);
01129     tmp = stripper.suffix();
01130     tmpName = stripper.baseName();
01131     printInfo("Volume Stack Name to be used: " + tmpName);
01132     printInfo("Volume Stack to be written from: " + tmp1.setNum(start) + " - " + tmp2.setNum(end));
01133 
01134     if(ok1 && ok2 && ok3)
01135     {
01136         tmpName.remove(QRegExp("\\d+$")); 
01137         printInfo("Volume Stack Non-Digit Name to be used: " + tmpName);
01138         tmpName = stripper.path() + "/" + tmpName; 
01139         writer->SetInput(imageData);
01140         writer->SetFilePrefix(tmpName.toStdString().c_str());
01141         writer->SetFilePattern(prefix.toStdString().c_str());
01142         writer->Write();
01143         writer->Delete();
01144 
01145         return true;
01146     }
01147     else
01148         return false;
01149 }
01150 
01151 bool DGVImageVTK::savePS(const QString filename)
01152 {
01153         vtkPostScriptWriter* writer = vtkPostScriptWriter::New();
01154 
01155     if(!imageDataLoaded)
01156         arrayToData();
01157 
01159     printInfo("Casting data to 8-bit Greyscale based on Window Level");
01160     writer->SetInputConnection(viewer->GetWindowLevel()->GetOutputPort());
01161     writer->SetFileName(filename.toStdString().c_str());
01162     writer->Write();
01163     writer->Delete();
01164 
01165         return true;
01166 }
01167 
01168 bool DGVImageVTK::openDICOM()
01169 {
01170         vtkGDCMImageReader* reader = vtkGDCMImageReader::New();
01171 
01172     if(reader->CanReadFile(name.toStdString().c_str()))
01173     {
01174         reader->SetFileName(name.toStdString().c_str());
01175         reader->Update();
01176         imageData = reader->GetOutput();
01177 
01178         if(!viewing)
01179         {
01180             viewer = ImageViewer::New();
01181             viewing = true;
01182         }
01183         outputPort = reader->GetOutputPort();
01184 
01185         setupViewerFromReader(); //Loaded set in here
01186 
01187         reader->Delete();
01188     }
01189     else
01190     {
01191         reader->Delete();
01192         loaded = false;
01193     }
01194 
01195         return loaded;
01196 }
01197 
01198 bool DGVImageVTK::saveDICOM(const QString filename)
01199 {
01200         vtkGDCMImageWriter* writer = vtkGDCMImageWriter::New();
01201 
01202     if(!imageDataLoaded)
01203         arrayToData();
01204 
01206     printInfo("Casting data to 8-bit Greyscale based on Window Level");
01207     writer->SetInputConnection(viewer->GetWindowLevel()->GetOutputPort());
01208     writer->SetFileName(filename.toStdString().c_str());
01209     writer->Write();
01210     writer->Delete();
01211 
01212         return true;
01213 }
01214 
01215 bool DGVImageVTK::openVTI()
01216 {
01217     vtkXMLImageDataReader *reader = vtkXMLImageDataReader::New();
01218 
01219     if(reader->CanReadFile(name.toStdString().c_str()))
01220     {
01221         int bounds[6];
01222         QString tmp1, tmp2;
01223 
01224         reader->SetFileName(name.toStdString().c_str());
01225         reader->Update();
01226         imageData = reader->GetOutput();
01227         outputPort = reader->GetOutputPort();
01228         imageData->GetExtent(bounds);
01229         printInfo("Image Size: " + tmp1.setNum(bounds[1]) + "x" + tmp2.setNum(bounds[3]));
01230 
01231         if(bounds[5] > 1) 
01232         {
01233             volume = true;
01234             if(enableVolumes)
01235                 generateVolume();
01236         }
01237         else
01238             printInfo("Didn't find 3D Image Data. Not showing volume plot.");
01239 
01240         if(!viewing)
01241         {
01242             viewer = ImageViewer::New();
01243             viewing = true;
01244         }
01245 
01246         setupViewerFromReader(); //Loaded set in here
01247     }
01248     else
01249         loaded = false;
01250 
01251     reader->Delete();
01252         return loaded;
01253 }
01254 
01255 bool DGVImageVTK::saveVTI(const QString filename)
01256 {
01257         vtkXMLImageDataWriter* writer = vtkXMLImageDataWriter::New();
01258 
01259     if(!imageDataLoaded)
01260         arrayToData();
01261 
01262     writer->SetInput(imageData);
01263     writer->SetFileName(filename.toStdString().c_str());
01264     writer->SetDataModeToBinary();
01265     writer->Write();
01266     writer->Delete();
01267 
01268         return true;
01269 }
01270 
01271 bool DGVImageVTK::openVTK()
01272 {
01273     vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New();
01274 
01276     //if(reader->CanReadFile(name.toStdString().c_str()))
01277     //{
01278         int bounds[6];
01279         QString tmp1, tmp2;
01280 
01281         reader->SetFileName(name.toStdString().c_str());
01282         reader->Update();
01283         imageData = reader->GetOutput();
01284         outputPort = reader->GetOutputPort();
01285         imageData->GetExtent(bounds);
01286         printInfo("Image Size: " + tmp1.setNum(bounds[1]) + "x" + tmp2.setNum(bounds[3]));
01287 
01288         if(bounds[5] > 1) 
01289         {
01290             volume = true;
01291             if(enableVolumes)
01292                 generateVolume();
01293         }
01294         else
01295             printInfo("Didn't find 3D Image Data. Not showing volume plot.");
01296 
01297         if(!viewing)
01298         {
01299             viewer = ImageViewer::New();
01300             viewing = true;
01301         }
01302 
01303         setupViewerFromReader(); //Loaded set in here
01304     //}
01305     //else
01306         //loaded = false;
01307 
01308     reader->Delete();
01309         return loaded;
01310 }
01311 
01312 bool DGVImageVTK::saveVTK(const QString filename)
01313 {
01314         vtkStructuredPointsWriter* writer = vtkStructuredPointsWriter::New();
01315 
01316     if(!imageDataLoaded)
01317         arrayToData();
01318 
01319     writer->SetInput(imageData);
01320     writer->SetFileName(filename.toStdString().c_str());
01321     writer->Write();
01322     writer->Delete();
01323 
01324         return true;
01325 }
01326 
01327 bool DGVImageVTK::openTGA()
01328 {
01329     unsigned char* targaimage;
01330     int dims[3];
01331 
01332     targaimage = (unsigned char*) tga_load(name.toStdString().c_str(), &dims[0], &dims[1], TGA_TRUECOLOR_32);
01333 
01334     int extents[6] = {0, dims[0]-1, 0, dims[1]-1, 0, 0};
01335 
01336     if (targaimage == NULL)
01337     {
01338         printError("Failed to read Targa image!");
01339         printError(tga_error_string(tga_get_last_error()));
01340         return false;
01341     }
01342 
01343     imageData = vtkImageData::New();
01344     imageData->SetDimensions(dims);
01345     imageData->SetExtent(extents);
01346     imageData->SetScalarTypeToUnsignedChar();
01347     imageData->SetNumberOfScalarComponents(4);
01348 
01349     for(int j = 0; j < dims[0]; j ++)
01350         for(int k = 0; k < dims[1]; k ++)
01351         {
01352             imageData->SetScalarComponentFromDouble(j, k, 0, 0, targaimage[(j*dims[0] + k)*4]);
01353             imageData->SetScalarComponentFromDouble(j, k, 0, 1, targaimage[(j*dims[0] + k)*4 + 1]);
01354             imageData->SetScalarComponentFromDouble(j, k, 0, 2, targaimage[(j*dims[0] + k)*4 + 2]);
01355             imageData->SetScalarComponentFromDouble(j, k, 0, 3, targaimage[(j*dims[0] + k)*4 + 3]);
01356         }
01357 
01358     loaded = true;
01359     imageData->Update();
01360     imageDataLoaded = true;
01361     imageDataSource = true;
01362     arrayLoaded = false;
01363     refresh(); // to update colour, not best solution.
01364 
01365     free(targaimage);
01366     return loaded;
01367 }
01368 
01369 bool DGVImageVTK::saveTGA(const QString filename)
01370 {
01371         unsigned char* targaimage;
01372     int dims[3];
01373 
01374     if(!imageDataLoaded)
01375         arrayToData();
01376 
01377     imageData->GetDimensions(dims);
01378 
01379     targaimage = (unsigned char*) tga_create(dims[0], dims[1], TGA_TRUECOLOR_32);
01380 
01381     if(imageData->GetNumberOfScalarComponents() == 1)
01382     {
01383         for(int j = 0; j < dims[0]; j ++)
01384             for(int k = 0; k < dims[1]; k ++)
01385             {
01386                 targaimage[(j*dims[0] + k)*4] = imageData->GetScalarComponentAsDouble(j,k,0,0);
01387                 targaimage[(j*dims[0] + k)*4 + 1] = imageData->GetScalarComponentAsDouble(j,k,0,0);
01388                 targaimage[(j*dims[0] + k)*4 + 2] = imageData->GetScalarComponentAsDouble(j,k,0,0);
01389                 targaimage[(j*dims[0] + k)*4 + 3] = 255; //Alpha
01390             }
01391         printInfo("Single Component Image Written.");
01392     }
01393     else if(imageData->GetNumberOfScalarComponents() == 3)
01394     {
01395         for(int j = 0; j < dims[0]; j ++)
01396             for(int k = 0; k < dims[1]; k ++)
01397             {
01398                 targaimage[(j*dims[0] + k)*4] = imageData->GetScalarComponentAsDouble(j,k,0,0);
01399                 targaimage[(j*dims[0] + k)*4 + 1] = imageData->GetScalarComponentAsDouble(j,k,0,1);
01400                 targaimage[(j*dims[0] + k)*4 + 2] = imageData->GetScalarComponentAsDouble(j,k,0,2);
01401                 targaimage[(j*dims[0] + k)*4 + 3] = 255; //Alpha
01402             }
01403     }
01404     else if(imageData->GetNumberOfScalarComponents() > 3)
01405     {
01406         for(int j = 0; j < dims[0]; j ++)
01407             for(int k = 0; k < dims[1]; k ++)
01408             {
01409                 targaimage[(j*dims[0] + k)*4] = imageData->GetScalarComponentAsDouble(j,k,0,0);
01410                 targaimage[(j*dims[0] + k)*4 + 1] = imageData->GetScalarComponentAsDouble(j,k,0,1);
01411                 targaimage[(j*dims[0] + k)*4 + 2] = imageData->GetScalarComponentAsDouble(j,k,0,2);
01412                 targaimage[(j*dims[0] + k)*4 + 3] = imageData->GetScalarComponentAsDouble(j,k,0,3); //Alpha
01413             }
01414     }
01415     else
01416     {
01417         printError("Unsupported Number of Components in Targa Write.");
01418         free(targaimage);
01419         return false;
01420     }
01421 
01422     if (!tga_write_raw(filename.toStdString().c_str(), dims[0], dims[1], targaimage, TGA_TRUECOLOR_32))
01423     {
01424         printError("Failed to write Targa image!");
01425         printError(tga_error_string(tga_get_last_error()));
01426         return false;
01427     }
01428 
01429     free(targaimage);
01430         return true;
01431 }
01432 
01433 void DGVImageVTK::complexValuedMode(bool complexValues)
01434 {
01435     complexData = complexValues;
01436     absoluteMagnitudeAct->setDisabled(!complexValues);
01437     absoluteMagnitudeAct->setChecked(true);
01438     imaginaryPartAct->setDisabled(!complexValues);
01439     realPartAct->setDisabled(!complexValues);
01440     phaseAct->setDisabled(!complexValues);
01441 }
01442 
01443 void DGVImageVTK::setData(Array<imageType,2> &data)
01444 {
01445     if(data.rows() > 0 && data.cols() > 0)
01446     {
01447         imageArray.resizeAndPreserve(data.shape());
01448         imageArray = data;
01449         arrayLoaded = true;
01450         externalData = false;
01451         loaded = true;
01452         volume = false;
01453         DGVImageVTK::arrayToData();
01454         imageDataSource = false;
01455     }
01456 }
01457 
01458 void DGVImageVTK::setData(Array<imageType,3> &data)
01459 {
01460     if(data.rows() > 0 && data.cols() > 0 && data.depth() > 0)
01461     {
01462         imageData = Blitz.arrayToVTKImageData(data);
01463         arrayLoaded = false;
01464         loaded = true;
01465         imageDataLoaded = true;
01466         imageDataSource = true;
01467         externalData = false;
01468         volume = true;
01469         dataToArray();
01470     }
01471 }
01472 
01473 void DGVImageVTK::setData(Array< complex<imageType>,2 > &data)
01474 {
01475     if(data.rows() > 0 && data.cols() > 0)
01476     {
01477         complexValuedMode(true);
01478         imageComplexArray.resizeAndPreserve(data.shape());
01479         imageComplexArray = data;
01480         arrayLoaded = true;
01481         externalData = false;
01482         loaded = true;
01483         volume = false;
01484         DGVImageVTK::arrayToData();
01485         imageDataSource = false;
01486     }
01487 }
01488 
01489 void DGVImageVTK::setData(Array< complex<imageType>,3 > &data)
01490 {
01491     if(data.rows() > 0 && data.cols() > 0)
01492     {
01493         complexValuedMode(true);
01494         imageData = Blitz.arrayToVTKImageData(data);
01495         arrayLoaded = false;
01496         loaded = true;
01497         imageDataLoaded = true;
01498         imageDataSource = true;
01499         externalData = false;
01500         volume = true;
01501         dataToArray();
01502     }
01503 }
01504 
01505 void DGVImageVTK::setData(vtkImageData *newData)
01506 {
01507     imageData = newData;
01508     arrayLoaded = false;
01509     loaded = true;
01510     imageDataLoaded = true;
01511     imageDataSource = true;
01512     externalData = true;
01513     dataToArray();
01514 }
01515 
01516 void DGVImageVTK::setDataSize(int rows, int cols)
01517 {
01518     if(complexData)
01519     {
01520         imageComplexArray.resize(rows,cols);
01521         imageComplexArray = 0;
01522     }
01523     else
01524     {
01525         imageArray.resize(rows,cols);
01526         imageArray = 0;
01527     }
01528 }
01529 
01530 void DGVImageVTK::SetInput(vtkImageData *newData)
01531 {
01532     setData(newData);
01533 }
01534 
01535 void DGVImageVTK::setConsole(DGVConsole *newConsole)
01536 {
01537     if(newConsole != NULL)
01538     {
01539         console = newConsole;
01540         consoleAssigned = true;
01541     }
01542 }
01543 
01544 Array<imageType,2>& DGVImageVTK::data()
01545 {
01546     if(imageDataSource && !arrayLoaded)
01547         DGVImageVTK::dataToArray();
01548     if(viewing && volume)
01549         sliceToData();
01550     return imageArray;
01551 }
01552 
01553 Array< complex<imageType>,2 >& DGVImageVTK::dataComplex()
01554 {
01555     return imageComplexArray;
01556 }
01557 
01558 Array<imageType,2>& DGVImageVTK::dataViewing()
01559 {
01560     if(!complexData)
01561         return data();
01562 
01563     imageArray.resize(imageComplexArray.shape());
01564     if(absoluteMagnitudeAct->isChecked())
01565     {
01566         setWindowTitle(strippedNamePrefix() + "[Abs]");
01567         imageArray = abs(imageComplexArray);
01568         return imageArray;
01569     }
01570     else if(imaginaryPartAct->isChecked())
01571     {
01572         setWindowTitle(strippedNamePrefix() + "[Imag]");
01573         imageArray = imag(imageComplexArray);
01574         return imageArray;
01575     }
01576     else if(realPartAct->isChecked())
01577     {
01578         setWindowTitle(strippedNamePrefix() + "[Real]");
01579         imageArray = real(imageComplexArray);
01580         return imageArray;
01581     }
01582     else if(phaseAct->isChecked())
01583     {
01584         setWindowTitle(strippedNamePrefix() + "[Phase]");
01585         imageArray = arg(imageComplexArray);
01586         return imageArray;
01587     }
01588     else
01589         return imageArray;
01590 }
01591 
01592 DGVVolumePlotVTK* DGVImageVTK::getVolume()
01593 {
01594     if(!volume || !enableVolumes)
01595         printError("Possible Error: Image is not a volume or volume plot is not enabled.");
01596     return volViewer;
01597 }
01598 
01599 QString DGVImageVTK::strippedName()
01600 {
01601     return QFileInfo(name).fileName();
01602 }
01603 
01604 QString DGVImageVTK::strippedNamePrefix()
01605 {
01606     return "Image: " + QFileInfo(name).fileName();
01607 }
01608 
01609 void DGVImageVTK::addToContextMenu(QVector<QMenu*> &menus)
01610 {
01611     menusToAdd = menus;
01612 }
01613 
01614 void DGVImageVTK::generateVolume()
01615 {
01616     if(loaded && volume)
01617     {
01618         volViewer = new DGVVolumePlotVTK(parentWidget());
01619         volViewer->setName(name);
01620         if(outputPort != NULL)
01621             volViewer->SetInputConnection(outputPort);
01622         imageData->Update();
01623         volViewer->setData(imageData);
01624         volViewer->generatePlot();
01625         volViewer->generateAxes();
01626         volViewer->show();
01627 
01628         emit volumePlotAvailable(volViewer);
01629     }
01630     else
01631         printError("Volume data not detected. Check the image data.");
01632 }
01633 
01634 void DGVImageVTK::generateImage()
01635 {
01637     checkDataIsManual();
01638 
01639     if(loaded)
01640     {
01641         int bounds[6];
01642         if(!viewing)
01643         {
01644             viewer = ImageViewer::New();
01645             viewing = true;
01646         }
01647         printInfo("Generating Image");
01648         imageData->GetExtent(bounds);
01649 
01650         magnify = vtkImageMagnify::New();
01651         magnify->SetInput(imageData);
01652         if(bounds[1]+1 < minWindowSize && bounds[3]+1 < minWindowSize)
01653             magnify->SetMagnificationFactors(minWindowSize/(bounds[1]+1),minWindowSize/(bounds[3]+1),1);
01654         else
01655             magnify->SetMagnificationFactors(1,1,1);
01656         magnify->InterpolateOff();
01657 
01658         if(bounds[5] > 1) 
01659         {
01660             volume = true;
01661             if(enableVolumes)
01662             {
01663                 printInfo("Found 3D Image Data. Also showing volume plot.");
01664                 generateVolume();
01665             }
01666         }
01667         else
01668             printInfo("Didn't find 3D Image Data. Not showing volume plot.");
01669 
01670         outputPort = magnify->GetOutputPort();
01671         viewer->SetInputConnection(magnify->GetOutputPort());
01672         viewer->GetRenderer()->ResetCamera();
01673         viewer->SetColorLevel(Blitz.getMean());
01674         viewer->SetColorWindow(Blitz.getMean()); //Also good: (max-min)/2+min
01675         QVTKWidget::SetRenderWindow(viewer->GetRenderWindow());
01676         viewer->SetupInteractor(QVTKWidget::GetRenderWindow()->GetInteractor());
01677 
01678         setupEvents();
01679 
01680         if(bounds[1] > minWindowSize && bounds[3] > minWindowSize)
01681         {
01682             viewer->SetSize(bounds[1],bounds[3]);
01683             QVTKWidget::resize(bounds[1],bounds[3]);
01684         }
01685         else
01686         {
01687             viewer->SetSize(minWindowSize,minWindowSize);
01688             QVTKWidget::resize(minWindowSize,minWindowSize);
01689         }
01690 
01691         magnify->Delete();
01692     }
01693 }
01694 
01695 void DGVImageVTK::scan()
01696 {
01697     if(loaded && viewing)
01698     {
01699         if ( timerId >= 0 ) //Stop
01700         {
01701             killTimer(timerId);
01702             timerId = -1;
01703         }
01704         else //Start
01705         {
01706 
01707             bool ok;
01708             double interval = QInputDialog::getDouble(this, tr("Scan Interval Time"), tr("Interval (ms):"), 250, 0, 1000000, 1, &ok);
01709 
01710             if(ok)
01711             {
01712                 timerInterval = qRound(interval);
01713 
01714                 if (timerInterval >= 0 )
01715                 {
01716                     viewer->SetSlice(0);
01717                     viewer->GetRenderer()->ResetCamera();
01718                     timerId = startTimer(timerInterval);
01719                 }
01720             }
01721         }
01722     }
01723 }
01724 
01725 void DGVImageVTK::table()
01726 {
01728     checkDataIsManual();
01729 
01730     if(loaded)
01731     {
01732         dataTable = new DGVTableVTK(parentWidget());
01733         QString tmp;
01734 
01735         printInfo("Constructing Image Data Table");
01736         if( (imageDataSource && !arrayLoaded) || volume ) 
01737             DGVImageVTK::dataToArray();
01738         dataTable->setName(name);
01739         if(complexData)
01740             dataTable->setData(imageComplexArray);
01741         else
01742             dataTable->setData(imageArray);
01743         DGVImageVTK::connectTable(dataTable);
01744         dataTable->show(); 
01745 
01746         emit tableAvailable(dataTable);
01747     }
01748 }
01749 
01750 void DGVImageVTK::mergedSurfacePlot()
01751 {
01753     checkDataIsManual();
01754 
01755     if(loaded)
01756     {
01757         surfacePlot = new DGVSurfacePlotVTK(parentWidget());
01758 
01759         if(imageDataSource) 
01760             DGVImageVTK::dataToArray();
01761         else
01762             DGVImageVTK::arrayToData();
01763         surfacePlot->setName(name);
01764         if(consoleAssigned)
01765             surfacePlot->setConsole(console);
01766         surfacePlot->setData(dataViewing());
01767         surfacePlot->generatePlotMergedWith(imageData);
01768         surfacePlot->generateAxes();
01769         surfacePlot->show(); 
01770         externalData = true; 
01771 
01772         emit surfacePlotAvailable(surfacePlot);
01773     }
01774 }
01775 
01776 void DGVImageVTK::clip()
01777 {
01778     if(loaded)
01779     {
01780         int bounds[6];
01781 
01782         if(!imageDataLoaded)
01783             DGVImageVTK::arrayToData();
01784 
01785         imageData->GetExtent(bounds);
01786 
01787         bool okStartRows, okEndRows, okStartCols, okEndCols;
01788         int newStartRows = QInputDialog::getInteger(this, tr("Clip Image to subset"),
01789                                           tr("Start at Row:"), bounds[0], bounds[0], bounds[1], 1, &okStartRows);
01790         int newEndRows = QInputDialog::getInteger(this, tr("Clip Image to subset"),
01791                                           tr("End at Row:"), bounds[1], bounds[0], bounds[1], 1, &okEndRows);
01792         int newStartCols = QInputDialog::getInteger(this, tr("Clip Image to subset"),
01793                                           tr("Start at Column:"), bounds[2], bounds[2], bounds[3], 1, &okStartCols);
01794         int newEndCols = QInputDialog::getInteger(this, tr("Clip Image to subset"),
01795                                           tr("End at Column:"), bounds[3], bounds[2], bounds[3], 1, &okEndCols);
01796 
01797         int newStartDepth = 0, newEndDepth = 1;
01798 
01799         if(volume)
01800         {
01801             newStartDepth = QInputDialog::getInteger(this, tr("Clip Image to subset"),
01802                                               tr("Start at Depth:"), bounds[4], bounds[4], bounds[5], 1, &okStartCols);
01803             newEndDepth = QInputDialog::getInteger(this, tr("Clip Image to subset"),
01804                                               tr("End at Depth:"), bounds[5], bounds[4], bounds[5], 1, &okEndCols);
01805         }
01806 
01807         QString tmp1, tmp2;
01808 
01809         if(okStartRows && okEndRows && okStartCols && okEndCols && newStartCols < newEndCols && newStartRows < newEndRows)
01810         {
01811             vtkImageClip *clipper = vtkImageClip::New();
01812 
01813             printInfo("Clip image data to: " + tmp1.setNum(newEndRows-newStartRows) + "x" + tmp2.setNum(newEndCols-newStartCols));
01814             clipper->ClipDataOn();
01815             clipper->SetInput(imageData);
01816             if(volume)
01817                 clipper->SetOutputWholeExtent(newStartRows, newEndRows, newStartCols, newEndCols, newStartDepth, newEndDepth);
01818             else
01819                 clipper->SetOutputWholeExtent(newStartRows, newEndRows, newStartCols, newEndCols, bounds[4], bounds[5]);
01820             clipper->UpdateWholeExtent();
01821 
01822             imageData = clipper->GetOutput();
01823             if(volume)
01824                 imageData->SetDimensions(newEndRows-newStartRows, newEndCols-newStartCols, newEndCols-newStartCols);
01825             else
01826                 imageData->SetDimensions(newEndRows-newStartRows, newEndCols-newStartCols, bounds[5]-bounds[4]);
01827             bounds[0] = 0;
01828             bounds[1] = newEndRows-newStartRows;
01829             bounds[2] = 0;
01830             bounds[3] = newEndCols-newStartCols;
01831             if(volume)
01832             {
01833                 bounds[4] = 0;
01834                 bounds[5] = newEndDepth-newStartDepth;
01835             }
01836             imageData->SetExtent(bounds); 
01837             //imageData->Update();
01838             imageDataSource = true;
01839             dataToArray(); 
01840 
01841             magnify = vtkImageMagnify::New();
01842             magnify->SetInput(imageData);
01843             if(bounds[1]+1 < minWindowSize && bounds[3]+1 < minWindowSize)
01844                 magnify->SetMagnificationFactors(minWindowSize/(bounds[1]+1),minWindowSize/(bounds[3]+1),1);
01845             else
01846                 magnify->SetMagnificationFactors(1,1,1);
01847             magnify->InterpolateOff();
01848 
01849             if(!viewing)
01850             {
01851                 viewer = ImageViewer::New();
01852                 viewing = true;
01853             }
01854 
01855             viewer->SetInputConnection(magnify->GetOutputPort());
01856             viewer->Render();
01857 
01858             magnify->Delete();
01859         }
01860     }
01861 }
01862 
01863 void DGVImageVTK::histogram()
01864 {
01865     if(loaded)
01866     {
01867         if(!imageDataLoaded)
01868             DGVImageVTK::arrayToData();
01869         if(!arrayLoaded)
01870             DGVImageVTK::dataToArray();
01871 
01872         vtkImageAccumulate *hist = vtkImageAccumulate::New();
01873 
01874         hist->SetInput(imageData);
01875         hist->SetComponentExtent(Blitz.getMin(),Blitz.getMax(),0,0,0,0); 
01876         hist->Update();
01877         hist->Print(cerr);
01878 
01879         int span = abs(Blitz.getMax() - Blitz.getMin()) + 1;
01880 
01881         if(span < 100000) 
01882         {
01883             Array<imageType,1> xData(span), bins(span);
01884             QString tmp;
01885             firstIndex x;
01886 
01887             printInfo("Using Custom Histogramer");
01888             printInfo("Number of bins: " + tmp.setNum(span));
01889 
01890             dataViewing(); 
01891             xData = x + Blitz.getMin();
01892             bins = 0;
01893             for(int j = 0; j < imageArray.rows(); j ++)
01894                 for(int k = 0; k < imageArray.cols(); k ++)
01895                     bins( imageArray(j,k) - Blitz.getMin() ) ++;
01896 
01897             DGVPlot *plot = new DGVPlot(this);
01898 
01899             plot->setName(name);
01900             plot->setWindowTitle("Histogram: " + strippedName());
01901             plot->createCurvePlot(xData,bins,"Histogram: " + strippedName());
01902 
01903             hist->Delete();
01904             emit plotAvailable(plot);
01905         }
01906         else
01907         {
01908             DGVPlotVTK *plot = new DGVPlotVTK(this);
01909 
01910             printInfo("Using VTK Histogramer");
01911             plot->setName(name);
01912             plot->setWindowTitle("Histogram: " + strippedName());
01913             plot->setData(hist->GetOutput());
01914             plot->setRanges(hist->GetMin()[0],hist->GetMax()[0],0,0);
01915             //plot->setRanges(Blitz.getMin(),Blitz.getMax(),0,0);
01916             //plot->setRanges(0,0,0,0); ///Forces auto range computation (VTK)
01917             plot->generatePlot();
01918 
01919             hist->Delete();
01920             emit plotAvailable(plot);
01921         }
01922     }
01923 }
01924 
01925 void DGVImageVTK::refresh()
01926 {
01928     checkDataIsManual();
01929 
01930     if(loaded)
01931     {
01933         if(arrayLoaded)
01934             DGVImageVTK::arrayToData();
01935         else if(imageDataSource)
01936             DGVImageVTK::dataToArray();
01937         else
01938             return;
01939         printInfo("Refreshing Image: " + strippedName());
01940         DGVImageVTK::generateImage();
01941         imageData->Update();
01942         if(viewing)
01943             viewer->Render();
01944     }
01945 }
01946 
01947 void DGVImageVTK::renameData()
01948 {
01949     bool ok;
01950 
01951     QString newName = QInputDialog::getText(this, tr("Rename Data"), tr("New Name: "), QLineEdit::Normal, name, &ok);
01952 
01953     if(ok)
01954         setName(newName);
01955 }
01956 
01957 void DGVImageVTK::updateData(int row, int col)
01958 {
01959     //if(dataTable->isLinkedToImage() && !dataTable->isViewChanging())
01960     if(!dataTable->isViewChanging())
01961     {
01962         //cerr << "Updating (" << row << "," << col << ") of the ";
01963         if(!complexData)
01964         {
01965             //cerr << "Real Table Data" << endl;
01966             imageArray(row,col) = dataTable->item(row,col)->text().toDouble();
01967         }
01968         else
01969         {
01970             imageType tmpValue;
01971 
01972             //cerr << "Complex Table Data: ";
01973             if(dataTable->viewingImaginaryPart())
01974             {
01975                 //cerr << "Imaginary Part" << endl;
01976                 tmpValue = imageComplexArray(row,col).real();
01977                 imageComplexArray(row,col) = complex<imageType>(tmpValue,dataTable->item(row,col)->text().toDouble());
01978             }
01979             else if(dataTable->viewingRealPart())
01980             {
01981                 //cerr << "Real Part" << endl;
01982                 tmpValue = imageComplexArray(row,col).imag();
01983                 imageComplexArray(row,col) = complex<imageType>(dataTable->item(row,col)->text().toDouble(),tmpValue);
01984             }
01985             /*else if(dataTable->viewingMagnitude() || dataTable->viewingPhase())
01986             {
01987                 dataTable->setItem(row,col,abs(imageComplexArray(row,col)));
01988                 printWarning("Ignoring changes to Absolute Magnitude and Phase. Please make changes in Imaginary and Real parts.");
01989             }*/
01990         }
01991         imageDataLoaded = false;
01992         imageDataSource = false;
01993         arrayLoaded = true; 
01994     }
01995 }
01996 
01997 void DGVImageVTK::interpolateDisplay()
01998 {
01999     if(loaded && viewing)
02000     {
02001         if(viewer->GetImageActor()->GetInterpolate()) 
02002         {
02003             printInfo("Disabling Interpolation");
02004             viewer->GetImageActor()->InterpolateOff();
02005             interpolateAct->setChecked(false);
02006         }
02007         else
02008         {
02009             printInfo("Enabling Interpolation");
02010             viewer->GetImageActor()->InterpolateOn();
02011             interpolateAct->setChecked(true);
02012         }
02013     }
02014 }
02015 
02016 void DGVImageVTK::meanGreyScale()
02017 {
02018     if(loaded && viewing)
02019     {
02020         viewer->SetColorLevel(Blitz.getMean());
02021         viewer->SetColorWindow(Blitz.getMean()); //Also good: (max-min)/2+min
02022     }
02023 }
02024 
02025 void DGVImageVTK::incrementSlice()
02026 {
02027     /*if(loaded && viewing)
02028     {
02029         if(viewer->GetSlice()+1 <= viewer->GetSliceMax())
02030         {
02031             cerr << "Incrementing from Slice " << viewer->GetSlice() << " to Slice " << viewer->GetSlice()+1 << endl;
02032             viewer->SetSlice(viewer->GetSlice()+1);
02033         }
02034     }*/
02035 }
02036 
02037 void DGVImageVTK::decrementSlice()
02038 {
02039     /*if(loaded && viewing)
02040     {
02041         if(viewer->GetSlice()-1 >= viewer->GetSliceMin())
02042         {
02043             cerr << "Decrementing from Slice " << viewer->GetSlice() << " to Slice " << viewer->GetSlice()-1 << endl;
02044             viewer->SetSlice(viewer->GetSlice()-1);
02045         }
02046     }*/
02047 }
02048 
02049 void DGVImageVTK::viewToXYPlane()
02050 {
02051     if(!permuted)
02052     {
02053         permute = vtkImagePermute::New();
02054         permuted = true;
02055     }
02056 
02057     permute->SetInput(imageData);
02058     permute->SetFilteredAxes(0,1,2);
02059     permute->Update();
02060 
02061     if(viewing)
02062     {
02063         viewer->SetInputConnection(permute->GetOutputPort());
02064         viewer->Render();
02065     }
02066 }
02067 
02068 void DGVImageVTK::viewToZXPlane()
02069 {
02070     if(!permuted)
02071     {
02072         permute = vtkImagePermute::New();
02073         permuted = true;
02074     }
02075 
02076     permute->SetInput(imageData);
02077     permute->SetFilteredAxes(1,2,0);
02078     permute->Update();
02079 
02080     if(viewing)
02081     {
02082         viewer->SetInputConnection(permute->GetOutputPort());
02083         viewer->Render();
02084     }
02085 }
02086 
02087 void DGVImageVTK::viewToZYPlane()
02088 {
02089     if(!permuted)
02090     {
02091         permute = vtkImagePermute::New();
02092         permuted = true;
02093     }
02094 
02095     permute->SetInput(imageData);
02096     permute->SetFilteredAxes(2,0,1);
02097     permute->Update();
02098 
02099     if(viewing)
02100     {
02101         viewer->SetInputConnection(permute->GetOutputPort());
02102         viewer->Render();
02103     }
02104 }
02105 
02106 void DGVImageVTK::createActions()
02107 {
02108     absoluteMagnitudeAct = new QAction(this);
02109     absoluteMagnitudeAct->setText(QApplication::translate("Image", "Absolute &Magnitude", 0, QApplication::UnicodeUTF8));
02110     absoluteMagnitudeAct->setShortcut(tr("Alt+m"));
02111     absoluteMagnitudeAct->setCheckable(true);
02112 
02113     imaginaryPartAct = new QAction(this);
02114     imaginaryPartAct->setText(QApplication::translate("Image", "&Imaginary Part", 0, QApplication::UnicodeUTF8));
02115     imaginaryPartAct->setShortcut(tr("Alt+i"));
02116     imaginaryPartAct->setCheckable(true);
02117 
02118     realPartAct = new QAction(this);
02119     realPartAct->setText(QApplication::translate("Image", "&Real Part", 0, QApplication::UnicodeUTF8));
02120     realPartAct->setShortcut(tr("Alt+r"));
02121     realPartAct->setCheckable(true);
02122 
02123     phaseAct = new QAction(this);
02124     phaseAct->setText(QApplication::translate("Image", "&Phase/Argument", 0, QApplication::UnicodeUTF8));
02125     phaseAct->setShortcut(tr("Alt+p"));
02126     phaseAct->setCheckable(true);
02127 
02128     complexGroup = new QActionGroup(this);
02129     complexGroup->addAction(absoluteMagnitudeAct);
02130     complexGroup->addAction(imaginaryPartAct);
02131     complexGroup->addAction(realPartAct);
02132     complexGroup->addAction(phaseAct);
02133     complexGroup->setDisabled(!complexData);
02134 }
02135 
02136 void DGVImageVTK::createConnections()
02137 {
02138     connect(absoluteMagnitudeAct, SIGNAL(triggered()), this, SLOT(refresh()));
02139     connect(imaginaryPartAct, SIGNAL(triggered()), this, SLOT(refresh()));
02140     connect(realPartAct, SIGNAL(triggered()), this, SLOT(refresh()));
02141     connect(phaseAct, SIGNAL(triggered()), this, SLOT(refresh()));
02142 }
02143 
02144 void DGVImageVTK::connectTable(DGVTableVTK *child)
02145 {
02146     child->linkToImageData(true); 
02147     QObject::connect(child,SIGNAL(cellChanged(int,int)), this, SLOT(updateData(int,int)));
02148 }
02149 
02150 void DGVImageVTK::dataToArray()
02151 {
02152     if(loaded && imageDataSource)
02153     {
02154         int* Size = imageData->GetDimensions();
02155         bool success;
02156         QString tmp1, tmp2, tmp3;
02157 
02159         printInfo("Dimensions of the picture read: " + tmp1.setNum(Size[0]) + " x " + tmp2.setNum(Size[1]));
02160 
02161         if(complexData)
02162             arrayToData(); 
02163 
02164         if(viewing && volume) 
02165             success = sliceToData();
02166         else
02167             success = Blitz.vtkImageDataToArray(imageData,imageArray);
02168 
02169         if(success)
02170         {
02171             if(!volume)
02172                 arrayLoaded = true;
02173             printInfo("Min and Max Pixel Values are " + tmp1.setNum(Blitz.getMin()) + " and " + tmp2.setNum(Blitz.getMax()) + ". Mean: " + tmp3.setNum(Blitz.getMean()));
02174         }
02175         else
02176             printError("vtk ImageData to Blitz Array cast failed");
02177     }
02178 }
02179 
02180 bool DGVImageVTK::sliceToData()
02181 {
02182     QString tmp1;
02183     bool success;
02184 
02185     if(sliceInView != viewer->GetSlice())
02186     {
02187         printInfo("Loading New Slice: " + tmp1.setNum(viewer->GetSlice()));
02188         sliceInView = viewer->GetSlice();
02189         success = Blitz.vtkImageDataToArray(imageData,viewer->GetSlice(),imageArray);
02190     }
02191     else
02192         success = true;
02193 
02194     return success;
02195 }
02196 
02197 void DGVImageVTK::arrayToData()
02198 {
02199     if(loaded && arrayLoaded)
02200     {
02201         QString tmp1, tmp2, tmp3;
02202 
02203         imageData = Blitz.arrayToVTKImageData(dataViewing());
02204         imageDataLoaded = true;
02205         //imageDataSource = false;
02206         externalData = false;
02207 
02208         printInfo("Min and Max Pixel Values are " + tmp1.setNum(Blitz.getMin()) + " and " + tmp2.setNum(Blitz.getMax()) + ". Mean: " + tmp3.setNum(Blitz.getMean()));
02209     }
02210 }
02211 
02212 void DGVImageVTK::checkDataIsManual()
02213 {
02214     if(((imageArray.rows() > 0 && imageArray.cols() > 0) || (imageComplexArray.rows() > 0 && imageComplexArray.cols() > 0) )  && !loaded && !imageDataSource)
02215     {
02216         arrayLoaded = true;
02217         loaded = true;
02218         DGVImageVTK::arrayToData();
02219         imageDataSource = false;
02220     }
02221 }
02222 
02223 void DGVImageVTK::addContextMenuExtras()
02224 {
02225     for(int j = 0; j < menusToAdd.size(); j ++)
02226         contextMenu->addAction(menusToAdd[j]->menuAction());
02227 }
02228 
02229 void DGVImageVTK::setupEvents()
02230 {
02231     if(viewing)
02232     {
02233         vtkCallbackCommand* callback = vtkCallbackCommand::New();
02234         vtkCallbackCommand* callbackWheelUp = vtkCallbackCommand::New();
02235         vtkCallbackCommand* callbackWheelDown = vtkCallbackCommand::New();
02236         vtkEventForwarderCommand* forward = vtkEventForwarderCommand::New();
02237 
02238         callback->SetCallback(handleKeys);
02239         callbackWheelUp->SetCallback(handleWheelUp);
02240         callbackWheelDown->SetCallback(handleWheelDown);
02241         forward->SetTarget(viewer); 
02242 
02243         QVTKWidget::GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::KeyPressEvent,forward,1.0); 
02244         //QVTKWidget::GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::MouseWheelForwardEvent,forward,1.0); //!< Forward keyboard events
02245         //QVTKWidget::GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::MouseWheelBackwardEvent,forward,1.0); //!< Forward keyboard events
02246         viewer->AddObserver(vtkCommand::KeyPressEvent,callback,1.0); 
02247         //viewer->AddObserver(vtkCommand::MouseWheelForwardEvent,callbackWheelUp,1.0); //!< Observe this command
02248         //viewer->AddObserver(vtkCommand::MouseWheelBackwardEvent,callbackWheelDown,1.0); //!< Observe this command
02250         QVTKWidget::GetRenderWindow()->GetInteractor()->RemoveObservers(vtkCommand::RightButtonPressEvent);
02251         QVTKWidget::GetRenderWindow()->GetInteractor()->RemoveObservers(vtkCommand::RightButtonReleaseEvent);
02252 
02253         callback->Delete();
02254         callbackWheelUp->Delete();
02255         callbackWheelDown->Delete();
02256         forward->Delete();
02257     }
02258 }
02259 
02260 void DGVImageVTK::setupViewerFromReader()
02261 {
02262     int bounds[6];
02263     QString tmp1, tmp2;
02264 
02265         imageData->GetExtent(bounds);
02266     printInfo("Image Size: " + tmp1.setNum(bounds[1]+1) + "x" + tmp2.setNum(bounds[3]+1));
02267 
02268     magnify = vtkImageMagnify::New();
02269     magnify->SetInput(imageData);
02270     if(bounds[1]+1 < minWindowSize && bounds[3]+1 < minWindowSize)
02271         magnify->SetMagnificationFactors(minWindowSize/(bounds[1]+1),minWindowSize/(bounds[3]+1),1);
02272     else
02273         magnify->SetMagnificationFactors(1,1,1);
02274     magnify->InterpolateOff();
02275 
02276     viewer->SetInputConnection(magnify->GetOutputPort());
02277     viewer->GetRenderer()->ResetCamera();
02278     QVTKWidget::SetRenderWindow(viewer->GetRenderWindow());
02279     viewer->SetupInteractor(QVTKWidget::GetRenderWindow()->GetInteractor());
02280 
02281     setupEvents();
02282 
02283     if(bounds[1]+1 > minWindowSize && bounds[3]+1 > minWindowSize)
02284     {
02285         viewer->SetSize(bounds[1]+1,bounds[3]+1);
02286         QVTKWidget::resize(bounds[1]+1,bounds[3]+1);
02287     }
02288     else
02289     {
02290         viewer->SetSize(minWindowSize-1,minWindowSize-1);
02291         QVTKWidget::resize(minWindowSize-1,minWindowSize-1);
02292     }
02293 
02294     loaded = true;
02295     arrayLoaded = false;
02296     imageDataSource = true;
02297     imageDataLoaded = true;
02298 
02299     magnify->Delete();
02300 }
02301 
02302 void DGVImageVTK::contextMenuEvent(QContextMenuEvent *event)
02303 {
02304     contextMenu = new QMenu(this); 
02305 
02307     addContextMenuExtras();
02308 
02311     contextMenu->addSeparator();
02312     tableAct = contextMenu->addAction(tr("Table"));
02313     tableAct->setToolTip("Display raw data table of the image data");
02314     tableAct->setStatusTip("Display raw data table of the image data");
02315     tableAct->setShortcut(tr("Ctrl+t"));
02316     connect(tableAct, SIGNAL(triggered()), this, SLOT(table()));
02318     surfacePlotAct = contextMenu->addAction(tr("Merged Surface Plot with Image"));
02319     surfacePlotAct->setToolTip("Surface Plot based on scalar warping and image data");
02320     surfacePlotAct->setStatusTip("Surface Plot based on scalar warping and image data");
02321     surfacePlotAct->setShortcut(tr("Ctrl+p"));
02322     connect(surfacePlotAct, SIGNAL(triggered()), this, SLOT(mergedSurfacePlot()));
02323     scanAct = contextMenu->addAction(tr("Start/Stop Scan of Volume"));
02324     scanAct->setToolTip("Scan through the image slices");
02325     scanAct->setStatusTip("Scan through the image slices");
02326     scanAct->setShortcut(tr("Ctrl+a"));
02327     scanAct->setEnabled(volume);
02328     connect(scanAct, SIGNAL(triggered()), this, SLOT(scan()));
02329     volumeAct = contextMenu->addAction(tr("Volumetric Plot"));
02330     volumeAct->setToolTip("Volume Plot based on scalar values of the image slices");
02331     volumeAct->setStatusTip("Volume Plot based on scalar values of the image slices");
02332     volumeAct->setShortcut(tr("Ctrl+v"));
02333     volumeAct->setEnabled(volume);
02334     connect(volumeAct, SIGNAL(triggered()), this, SLOT(generateVolume()));
02335     histAct = contextMenu->addAction(tr("Histogram"));
02336     histAct->setShortcut(tr("Ctrl+h"));
02337     connect(histAct, SIGNAL(triggered()), this, SLOT(histogram()));
02338 
02340     contextMenu->addSeparator();
02341     interpolateAct = contextMenu->addAction(tr("Interpolation"));
02342     interpolateAct->setCheckable(true);
02343     if(viewing)
02344         interpolateAct->setChecked(viewer->GetImageActor()->GetInterpolate());
02345     interpolateAct->setShortcut(tr("Ctrl+i"));
02346     connect(interpolateAct, SIGNAL(triggered()), this, SLOT(interpolateDisplay()));
02347     meanGreyAct = contextMenu->addAction(tr("Colour Level to Mean"));
02348     meanGreyAct->setShortcut(tr("Ctrl+l"));
02349     connect(meanGreyAct, SIGNAL(triggered()), this, SLOT(meanGreyScale()));
02350     if(volume)
02351         clipAct = contextMenu->addAction(tr("Crop Volume"));
02352     else
02353         clipAct = contextMenu->addAction(tr("Crop Image"));
02354     clipAct->setShortcut(tr("Ctrl+c"));
02355     connect(clipAct, SIGNAL(triggered()), this, SLOT(clip()));
02356 
02358     viewMenu = contextMenu->addMenu("View"); 
02359     viewXY = viewMenu->addAction(tr("xy-plane"));
02360     viewXY->setShortcut(tr("Ctrl+z"));
02361     viewXY->setEnabled(volume);
02362     connect(viewXY, SIGNAL(triggered()), this, SLOT(viewToXYPlane()));
02363     viewZX = viewMenu->addAction(tr("zx-plane"));
02364     viewZX->setShortcut(tr("Ctrl+y"));
02365     viewZX->setEnabled(volume);
02366     connect(viewZX, SIGNAL(triggered()), this, SLOT(viewToZXPlane()));
02367     viewZY = viewMenu->addAction(tr("zy-plane"));
02368     viewZY->setShortcut(tr("Ctrl+x"));
02369     connect(viewZY, SIGNAL(triggered()), this, SLOT(viewToZYPlane()));
02370     viewZY->setEnabled(volume);
02371 
02373     contextMenu->addSeparator()->setText(tr("Complex View"));
02375     contextMenu->addAction(absoluteMagnitudeAct);
02377     contextMenu->addAction(imaginaryPartAct);
02379     contextMenu->addAction(realPartAct);
02381     contextMenu->addAction(phaseAct);
02382     complexGroup->setDisabled(!complexData);
02383 
02384     contextMenu->addSeparator();
02387         saveAct = contextMenu->addAction(tr("Save Data as Image..."));
02388         saveAct->setShortcut(tr("Ctrl+s"));
02389         connect(saveAct, SIGNAL(triggered()), this, SLOT(saveImage()));
02390         saveStackAct = contextMenu->addAction(tr("Save Data as Image Stack..."));
02391         saveStackAct->setShortcut(tr("Ctrl+Shift+s"));
02392         saveStackAct->setEnabled(volume);
02393         connect(saveStackAct, SIGNAL(triggered()), this, SLOT(saveStack()));
02394         refreshAct = contextMenu->addAction(tr("Refresh"));
02395         refreshAct->setShortcut(tr("F5"));
02396         connect(refreshAct, SIGNAL(triggered()), this, SLOT(refresh()));
02397         renameAct = contextMenu->addAction(tr("Rename"));
02398         renameAct->setShortcut(tr("Ctrl+r"));
02399         connect(renameAct, SIGNAL(triggered()), this, SLOT(renameData()));
02401         closeAct = contextMenu->addAction(tr("Close"));
02402         closeAct->setShortcut(tr("Ctrl+w"));
02403         connect(closeAct, SIGNAL(triggered()), this, SLOT(close()));
02404 
02405         contextMenu->exec(event->globalPos());
02406 }
02407 
02408 void DGVImageVTK::timerEvent(QTimerEvent *event)
02409 {
02410     if(loaded && viewing)
02411     {
02412         int bounds[6];
02413 
02414         imageData->GetExtent(bounds);
02415 
02416         if(viewer->GetSlice()+1 <= viewer->GetSliceMax())
02417         {
02418             //cerr << "Slice " << viewer->GetSlice() << ", ";
02419             viewer->SetSlice(viewer->GetSlice()+1);
02420             viewer->GetRenderer()->ResetCamera();
02421         }
02422         else
02423         {
02424             killTimer(timerId);
02425             timerId = -1;
02426         }
02427     }
02428 }
02429 
02430 void DGVImageVTK::printError(QString msg)
02431 {
02432     if(verboseMode)
02433     {
02434         if(consoleAssigned)
02435         {
02436             console->printError(msg);
02437         }
02438         else
02439             cerr << msg.toStdString() << endl;
02440     }
02441 }
02442 
02443 void DGVImageVTK::printWarning(QString msg)
02444 {
02445     if(verboseMode)
02446     {
02447         if(consoleAssigned)
02448         {
02449             console->printWarning(msg);
02450         }
02451         else
02452             cerr << msg.toStdString() << endl;
02453     }
02454 }
02455 
02456 void DGVImageVTK::printInfo(QString msg)
02457 {
02458     if(verboseMode)
02459     {
02460         if(consoleAssigned)
02461         {
02462             console->printInfo(msg);
02463         }
02464         else
02465             cerr << msg.toStdString() << endl;
02466     }
02467 }
02468 
02469 void handleKeys(vtkObject* obj, unsigned long, void *clientData, void *callData)
02470 {
02471     ImageViewer* view = ImageViewer::SafeDownCast(obj);
02472 
02473     string keyPressed = view->GetRenderWindow()->GetInteractor()->GetKeySym();
02474 
02475     if(keyPressed == "Up")
02476     {
02477         /*if(view->GetZSlice()+1 <= view->GetWholeZMax())
02478         {
02479             cerr << "Incrementing from Slice " << view->GetZSlice() << " to Slice " << view->GetZSlice()+1 << endl;
02480             view->SetZSlice(view->GetZSlice()+1);
02481             view->Render();
02482         }*/
02483         //vtkImageViewer2
02484         if(view->GetSlice()+1 <= view->GetSliceMax())
02485         {
02486             cerr << "Incrementing from Slice " << view->GetSlice() << " to Slice " << view->GetSlice()+1 << endl;
02487             view->SetSlice(view->GetSlice()+1);
02488             view->GetRenderer()->ResetCamera();
02489         }
02490     }
02491     else if(keyPressed == "Down")
02492     {
02493         /*if(view->GetZSlice()-1 >= view->GetWholeZMin())
02494         {
02495             cerr << "Decrementing from Slice " << view->GetZSlice() << " to Slice " << view->GetZSlice()-1 << endl;
02496             view->SetZSlice(view->GetZSlice()-1);
02497             view->Render();
02498         }*/
02499         //vtkImageViewer2
02500         if(view->GetSlice()-1 >= view->GetSliceMin())
02501         {
02502             cerr << "Decrementing from Slice " << view->GetSlice() << " to Slice " << view->GetSlice()-1 << endl;
02503             view->SetSlice(view->GetSlice()-1);
02504             view->GetRenderer()->ResetCamera();
02505         }
02506     }
02507 }
02508 
02509 void handleWheelUp(vtkObject* obj, unsigned long, void *clientData, void *callData)
02510 {
02511     ImageViewer* view = ImageViewer::SafeDownCast(obj);
02512     //vtkImageData *tmpImg = view->GetInput();
02513     //vtkImageMagnify *mag = vtkImageMagnify::New();
02514 
02515     cerr << "Wheel Up!" << endl;
02516     view->GetRenderer()->GetActiveCamera()->Dolly(1.25);
02517     view->Render();
02518     /*mag->SetInput(tmpImg);
02519     mag->SetMagnificationFactors(2,2,1);
02520     mag->InterpolateOff();
02521 
02522     view->SetInputConnection(mag->GetOutputPort());
02523     view->Render();
02524 
02525     mag->Delete();*/
02526 }
02527 
02528 void handleWheelDown(vtkObject* obj, unsigned long, void *clientData, void *callData)
02529 {
02530     ImageViewer* view = ImageViewer::SafeDownCast(obj);
02531     //vtkImageData *tmpImg = view->GetInput();
02532     //vtkImageMagnify *mag = vtkImageMagnify::New();
02533 
02534     cerr << "Wheel Down!" << endl;
02535     view->GetRenderer()->GetActiveCamera()->Dolly(0.8);
02536     view->Render();
02537     /*mag->SetInput(tmpImg);
02538     mag->SetMagnificationFactors(1,1,1);
02539     mag->InterpolateOff();
02540 
02541     view->SetInputConnection(mag->GetOutputPort());
02542     //view->GetRenderer()->ResetCamera();
02543     view->Render();
02544 
02545     mag->Delete();*/
02546 }

Generated on Wed Sep 8 2010 01:36:51 for DGV by  doxygen 1.7.1