]> Creatis software - clitk.git/commitdiff
updated experimental fusion sequence visualization mode to enable temporal linking
authorrblanc <rblanc33@gmail.com>
Tue, 26 Feb 2013 09:40:52 +0000 (10:40 +0100)
committerrblanc <rblanc33@gmail.com>
Tue, 26 Feb 2013 09:40:52 +0000 (10:40 +0100)
vv/qt_ui/vvOverlayPanel.ui
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvOverlayPanel.cxx
vv/vvOverlayPanel.h
vv/vvSlicerManager.h

index 0e5a01fcac5f9d197b211f7ed0f64c5976a617db..05986d84a313a33c8a50417191d5ceb1920ebe64 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>444</width>
-    <height>612</height>
+    <width>446</width>
+    <height>679</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -65,9 +65,9 @@ p, li { white-space: pre-wrap; }
       </property>
       <property name="geometry">
        <rect>
-        <x>220</x>
+        <x>230</x>
         <y>60</y>
-        <width>80</width>
+        <width>91</width>
         <height>17</height>
        </rect>
       </property>
@@ -78,9 +78,9 @@ p, li { white-space: pre-wrap; }
      <widget class="QCheckBox" name="fCTUSActivateSpaceSyncCheckBox">
       <property name="geometry">
        <rect>
-        <x>220</x>
+        <x>270</x>
         <y>10</y>
-        <width>61</width>
+        <width>81</width>
         <height>17</height>
        </rect>
       </property>
@@ -115,7 +115,7 @@ p, li { white-space: pre-wrap; }
        <rect>
         <x>30</x>
         <y>0</y>
-        <width>171</width>
+        <width>231</width>
         <height>32</height>
        </rect>
       </property>
@@ -141,7 +141,7 @@ p, li { white-space: pre-wrap; }
        <rect>
         <x>130</x>
         <y>36</y>
-        <width>151</width>
+        <width>201</width>
         <height>20</height>
        </rect>
       </property>
@@ -149,17 +149,20 @@ p, li { white-space: pre-wrap; }
        <enum>Qt::Horizontal</enum>
       </property>
      </widget>
-     <widget class="QPushButton" name="fCTUSLoadSignalPushButton">
+     <widget class="QPushButton" name="fCTUSLoadCorrespondancesPushButton">
       <property name="geometry">
        <rect>
         <x>20</x>
         <y>60</y>
-        <width>131</width>
+        <width>171</width>
         <height>23</height>
        </rect>
       </property>
+      <property name="toolTip">
+       <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Load a file indicating the correspondances between time indices between both sequences.&lt;/p&gt;&lt;p&gt;The format needs to be the following:&lt;/p&gt;&lt;p&gt;let nt1 the number of frames in sequence 1, resp. nt2 and seq. 2 &lt;/p&gt;&lt;p&gt;The file must contain nt1 + nt2 entries.&lt;/p&gt;&lt;p&gt;entry i (i&amp;lt;=nt1) indicates for the i-th frame of sequence 1 the index to display for sequence 2.&lt;/p&gt;&lt;p&gt;resp. i&amp;gt;nt1 indicate corresp from seq. 2 to seq. 1&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+      </property>
       <property name="text">
-       <string>Load Fused Seq. Signal</string>
+       <string>Load Correspondances</string>
       </property>
      </widget>
     </widget>
index a7dee1f3398e9fdcada9dfe5578a0f70541db920..a06870f5baf2074d74856776a9b49c36ff9e0adf 100644 (file)
@@ -88,6 +88,7 @@ It is distributed under dual licence
 
 // Standard includes
 #include <iostream>
+#include <fstream>
 #include <sstream>
 #include <iomanip>
 
@@ -294,7 +295,7 @@ vvMainWindow::vvMainWindow():vvMainWindowBase()
   connect(actionDocumentation,SIGNAL(triggered()),this,SLOT(ShowDocumentation()));
   connect(actionRegister_vv,SIGNAL(triggered()),this,SLOT(PopupRegisterForm()));
 
-  connect(overlayPanel, SIGNAL(FusionSequenceSignalButtonPressed()), this, SLOT(SelectFusionSequenceTemporalSignal()));
+  connect(overlayPanel, SIGNAL(FusionSequenceCorrespondancesButtonPressed()), this, SLOT(SelectFusionSequenceCorrespondances()));
 
 
   ///////////////////////////////////////////////
@@ -1651,6 +1652,7 @@ void vvMainWindow::CloseImage(QTreeWidgetItem* item, int column)
         }
         
         //TODO: also remove the image overlaid with the main sequence, as it is becoming invalid...
+        //this shall be done by calling this->CloseImage() with the correct index;...
       }
 
       linkPanel->removeImage(index);
@@ -2443,7 +2445,7 @@ void vvMainWindow::SelectFusionSequence()
 
 
 //------------------------------------------------------------------------------
-void vvMainWindow::SelectFusionSequenceTemporalSignal() {
+void vvMainWindow::SelectFusionSequenceCorrespondances() {
 
   //make sure the index is right?
   //in the end, I should attach the temporal data to the right sequence!
@@ -2454,35 +2456,51 @@ void vvMainWindow::SelectFusionSequenceTemporalSignal() {
   }
 
   //open a dialog box to find a file
-  QString Extensions = EXTENSIONS;
-  Extensions += ";;All Files (*)";
+  //QString Extensions = EXTENSIONS;
+  QString Extensions = ";;All Files (*)";
   QString fileName = QFileDialog::getOpenFileName(this,tr("Load respiratory signal for fused sequence"),mInputPathName,Extensions);
   if (fileName.isNull())
     return;
 
   //read it as a vector of values
-  std::vector<double> signal;
-  //...TODO, look for itk functions that can do that... vnl in the worst case.
-  signal.push_back(1);signal.push_back(2);
-
-  //TODO: instead: if the loaded signal is longer, just crop it...
-  //this allows loading only the first few frames when testing.
-  //->maybe raise a message that this behavior may be unsafe...
-
-  //if compatible with the fused image sequence (number of images = number of entries), enable the temporalSync
-  if ( signal.size() >= mSlicerManagers[index]->GetFusionSequenceNbFrames()) {
-    //for convenience, associate this sequence to both the current slicer manager, and to the linked one
-    mSlicerManagers[index]->SetFusionSequenceTemporalSignal(signal);
-    mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetFusionSequenceTemporalSignal(signal);
-    overlayPanel->enableFusionSequenceTemporalSync();
-    QMessageBox::information(this,tr("Adding signal"),"would add the signal from file: "+ fileName);
+  vnl_vector<double> tmpVect;
+
+  std::ifstream file;
+  file.open(fileName.toStdString().c_str());
+  tmpVect.read_ascii(file);
+  file.close();
+
+  //if compatible with the fused image sequence (number of entries = nb of entries in main sequence + nb of entries in joint sequence), enable the temporalSync
+  bool signalOK = true;
+  unsigned nbFrameMain = mSlicerManagers[index]->GetImage()->GetTransform().size();
+  unsigned nbFrameSecondary = mSlicerManagers[index]->GetFusionSequenceNbFrames();
+
+  std::vector<unsigned> temporalCorrespondances;
+  if ( tmpVect.size() == nbFrameMain + nbFrameSecondary ) {
+    for (unsigned i=0 ; i<tmpVect.size() ; i++) {
+      if (i<nbFrameMain) { //first part of the file: i -> index in secondary seq.
+        if ( tmpVect(i)<nbFrameSecondary ) temporalCorrespondances.push_back(tmpVect(i));
+        else { signalOK=false; break; } //pointing outside the secondary sequence...
+      }
+      else { //first part of the file -> index in secondary seq.
+        if ( tmpVect(i)<nbFrameMain ) temporalCorrespondances.push_back(tmpVect(i));
+        else { signalOK=false; break; } //pointing outside the secondary sequence...      
+      }      
+    }
   }
-  else {//else, send a message to signal the failure...
-    QString error = "The provided signal doesn't have the same duration as the sequence\n";
+  else {signalOK=false;}
+  if (!signalOK) {//else, send a message to signal the failure...
+    QString error = "The provided temporal correspondances is invalid - check tooltip.\n";
     error += "Ignoring file: " + fileName;
-    QMessageBox::information(this,tr("Problem adding signal!"),error);
+    QMessageBox::information(this,tr("Problem adding temporal correspondances!"),error);
     return;
   }
+  else {
+    //for convenience, associate this sequence to both the current slicer manager, and to the linked one
+    mSlicerManagers[index]->SetFusionSequenceCorrespondances(temporalCorrespondances);
+    mSlicerManagers[ mSlicerManagers[index]->GetFusionSequenceIndexOfLinkedManager() ]->SetFusionSequenceCorrespondances(temporalCorrespondances);
+    overlayPanel->enableFusionSequenceTemporalSync();
+  }
 
 }
 //------------------------------------------------------------------------------
@@ -2651,21 +2669,13 @@ void vvMainWindow::SetFusionSequenceProperty(int fusionSequenceFrameIndex, bool
     if (spatialSyncFlag) { //reslice the CT
 
       if (temporalSyncFlag) { //do the temporal synchronisation
-        //TODO: add the temporal synchronisation stuff
-        //if the button is checked, get the phase of the requested US frame from the available signal
-        //and select the corresponding one in the CT. (check the one just before, and the one just after, and select the closest)
-
-        //TODO: do it also the other way around, when modifying the time index related to CT, select a close frame
-        //this should not be done here directly, but the code should be inspired from the one here
-        //->find a good US frame such that when calling this function with this US frame, it produces the expected result
-
-
-        //TODO: select the right CT image to display
         int mainSequenceFrameIndex=0;
         //estimate the TSlice to set to the CT
-
+        unsigned nbFramesMain = mSlicerManagers[index]->GetImage()->GetTransform().size();
+        mainSequenceFrameIndex = mSlicerManagers[index]->GetFusionSequenceCorrespondances()[ nbFramesMain + fusionSequenceFrameIndex];
         //and set it!
         mSlicerManagers[index]->SetTSlice(mainSequenceFrameIndex, false);
+        //warning, there is a loopback, and modification of the TSlice in main sequence forces an update of the TSlice in secondary, etc... 
       }
 
 
@@ -2921,12 +2931,13 @@ void vvMainWindow::HorizontalSliderMoved(int value,int column, int slicer_index)
           if (mSlicerManagers[i]->GetFusionSequenceTemporalSyncFlag()) {            
             //WARNING: for some obscure reason, there are problems when accessing mSlicerManagers[mSlicerManagers[i]->GetFusionSequenceIndexOfLinkedManager()]->GetFusionSequenceFrameIndex();
 
-            //int estimatedValue=mSlicerManagers[mSlicerManagers[i]->GetFusionSequenceIndexOfLinkedManager()]->GetFusionSequenceFrameIndex();
             int estimatedValue=0;
-            //TODO: if temporal sync is active
             //estimate a corresponding time index for the secondary (US) sequence, and update it accordingly.
-            //estimatedValue = ...
-            overlayPanel->updateFusionSequenceSliderValueFromWindow(estimatedValue, true);
+            estimatedValue = mSlicerManagers[i]->GetFusionSequenceCorrespondances()[ value ];       
+            //TODO: at the moment, there is a loop in TSlice modifications
+            //modifying sequence 1 causes seq 2 to update, which in turns update seq1...
+            //I disable control on seq1 at the moment.
+            //overlayPanel->updateFusionSequenceSliderValueFromWindow(estimatedValue, true);
           }
         }
       }
index 15ec68779abf129e1e2f39f987a2d242f275f33e..dd95c0a83fa273f65b6b6ecb4a83052f806424f6 100644 (file)
@@ -161,7 +161,7 @@ public slots:
   void SelectFusionImage();
   //select the file(s) from the disk containing the image sequence to fuse
   void SelectFusionSequence();
-  void SelectFusionSequenceTemporalSignal();
+  void SelectFusionSequenceCorrespondances();
 
   void ResetTransformationToIdentity();
 
index 649f1fd9360f8fb44b9a6c3575141b69f96c4b56..b394bb55de4fc079c9c8e1123f8723d1de27661a 100644 (file)
@@ -65,7 +65,7 @@ vvOverlayPanel::vvOverlayPanel(QWidget * parent):QWidget(parent)
   connect(fCTUSSlider,SIGNAL(valueChanged(int)),this,SLOT(setFusionSequenceProperty()));
   connect(fCTUSActivateSpaceSyncCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setFusionSequenceProperty()));
   connect(fCTUSActivateTimeSyncCheckBox,SIGNAL(stateChanged(int)),this,SLOT(setFusionSequenceProperty()));
-  connect(fCTUSLoadSignalPushButton,SIGNAL(clicked()),this,SIGNAL(FusionSequenceSignalButtonPressed()));
+  connect(fCTUSLoadCorrespondancesPushButton,SIGNAL(clicked()),this,SIGNAL(FusionSequenceCorrespondancesButtonPressed()));
 }
 
 void vvOverlayPanel::getCurrentImageName(QString name)
index b0e69db92f2726b0c6aec58314c6462c45b92156..5329bf853cb1a17707ef2b61ce24b6a07664c40f 100644 (file)
@@ -68,7 +68,7 @@ signals:
   void OverlayPropertyUpdated(int color, int linked, double window, double level);
   void FusionPropertyUpdated(int opacity, int thresOpacity, int colormap, double window, double level, bool showLegend);
   void FusionSequencePropertyUpdated(int sequenceFrameIndex, bool spatialSync, unsigned int sequenceLength, bool temporalSync);
-  void FusionSequenceSignalButtonPressed();
+  void FusionSequenceCorrespondancesButtonPressed();
 
 private:
   bool disableFusionSignals;
index 3479dc6c887dfc20d5ea5e844187345261f52f00..60f239219532764c57a2e971f717c691066ba88f 100644 (file)
@@ -177,7 +177,7 @@ class vvSlicerManager : public QObject {
                mFusionSequenceListInitialTransformMatrices.push_back( tmpMat );
   }
   void SetFusionSequenceIndexOfLinkedManager(int index) { mFusionSequenceIndexLinkedManager = index; }
-  void SetFusionSequenceTemporalSignal(std::vector<double> s) { mFusionSequenceTemporalSignal = s; }
+  void SetFusionSequenceCorrespondances(std::vector<unsigned> s) { mFusionSequenceCorrespondances = s; }
   
   void SetFusionSequenceInvolvmentCode(int code) { mFusionSequenceInvolvementCode=code; }
   int GetFusionSequenceInvolvmentCode() { return mFusionSequenceInvolvementCode;}
@@ -195,7 +195,7 @@ class vvSlicerManager : public QObject {
   const vtkSmartPointer<vtkMatrix4x4>& GetFusionSequenceInitialTransformMatrixAtFrame(unsigned i) {
          return mFusionSequenceListInitialTransformMatrices[i];
   }
-  const std::vector<double>& GetFusionSequenceTemporalSignal() {return mFusionSequenceTemporalSignal;}
+  const std::vector<unsigned>& GetFusionSequenceCorrespondances() {return mFusionSequenceCorrespondances;}
 
   double GetColorWindow() const;
   double GetColorLevel() const;
@@ -332,7 +332,7 @@ protected:
   bool mFusionSequenceSpatialSyncFlag, mFusionSequenceTemporalSyncFlag; //flags indicating whether the spatial/temporal synchronization are actives
   vtkSmartPointer<vtkMatrix4x4> mFusionSequenceMainTransform;
   std::vector< vtkSmartPointer<vtkMatrix4x4> > mFusionSequenceListInitialTransformMatrices;
-  std::vector<double> mFusionSequenceTemporalSignal;
+  std::vector<unsigned> mFusionSequenceCorrespondances;
   
   int mPreset;
   SlicingPresetType mSlicingPreset;