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
00125
00126
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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();
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
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();
01304
01305
01306
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();
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;
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;
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);
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());
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 )
01700 {
01701 killTimer(timerId);
01702 timerId = -1;
01703 }
01704 else
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
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
01916
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
01960 if(!dataTable->isViewChanging())
01961 {
01962
01963 if(!complexData)
01964 {
01965
01966 imageArray(row,col) = dataTable->item(row,col)->text().toDouble();
01967 }
01968 else
01969 {
01970 imageType tmpValue;
01971
01972
01973 if(dataTable->viewingImaginaryPart())
01974 {
01975
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
01982 tmpValue = imageComplexArray(row,col).imag();
01983 imageComplexArray(row,col) = complex<imageType>(dataTable->item(row,col)->text().toDouble(),tmpValue);
01984 }
01985
01986
01987
01988
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());
02022 }
02023 }
02024
02025 void DGVImageVTK::incrementSlice()
02026 {
02027
02028
02029
02030
02031
02032
02033
02034
02035 }
02036
02037 void DGVImageVTK::decrementSlice()
02038 {
02039
02040
02041
02042
02043
02044
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
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
02245
02246 viewer->AddObserver(vtkCommand::KeyPressEvent,callback,1.0);
02247
02248
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
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
02478
02479
02480
02481
02482
02483
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
02494
02495
02496
02497
02498
02499
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
02513
02514
02515 cerr << "Wheel Up!" << endl;
02516 view->GetRenderer()->GetActiveCamera()->Dolly(1.25);
02517 view->Render();
02518
02519
02520
02521
02522
02523
02524
02525
02526 }
02527
02528 void handleWheelDown(vtkObject* obj, unsigned long, void *clientData, void *callData)
02529 {
02530 ImageViewer* view = ImageViewer::SafeDownCast(obj);
02531
02532
02533
02534 cerr << "Wheel Down!" << endl;
02535 view->GetRenderer()->GetActiveCamera()->Dolly(0.8);
02536 view->Render();
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546 }