<x>0</x>
<y>0</y>
<width>325</width>
- <height>131</height>
+ <height>214</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QGridLayout">
- <property name="margin">
- <number>2</number>
- </property>
- <property name="spacing">
- <number>2</number>
- </property>
- <item row="0" column="0" colspan="4">
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
</property>
</widget>
</item>
- <item row="2" column="0" colspan="4">
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Coordinates are in mm</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="5">
<widget class="QTableWidget" name="tableWidget">
<property name="columnCount">
<number>7</number>
<string>remove last landmark.</string>
</property>
<property name="text">
- <string/>
+ <string>1</string>
</property>
<property name="icon">
<iconset resource="../vvIcons.qrc">
</widget>
</item>
<item row="3" column="1">
- <spacer>
+ <widget class="QPushButton" name="removeAllButton">
+ <property name="text">
+ <string>All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../vvIcons.qrc">
+ <normaloff>:/common/icons/standardbutton-cancel-16.png</normaloff>:/common/icons/standardbutton-cancel-16.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <spacer name="spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>40</width>
+ <width>39</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
- <item row="3" column="2">
+ <item row="3" column="3">
<widget class="QPushButton" name="loadButton">
<property name="text">
<string>Load</string>
</property>
</widget>
</item>
- <item row="3" column="3">
+ <item row="3" column="4">
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Coordinates are in mm</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
<resources>
#include <sys/stat.h>
#include <errno.h>
-typedef enum {O_BASE,O_OVERLAY,O_FUSION,O_VF,O_CONTOUR} OpenModeType;
+typedef enum {O_BASE,O_OVERLAY,O_FUSION,O_VF,O_CONTOUR,O_LANDMARKS} OpenModeType;
typedef enum {P_NORMAL,P_SEQUENCE,P_WINDOW,P_LEVEL} ParseModeType;
void load_image_first_error()
window.LoadImages(sequence_filenames, vvImageReader::MERGEDWITHTIME);
else if (open_mode==O_OVERLAY)
window.AddOverlayImage(n_image_loaded-1,sequence_filenames,vvImageReader::MERGEDWITHTIME);
+ else if (open_mode==O_LANDMARKS)
+ window.AddLandmarks(n_image_loaded-1,sequence_filenames);
else {
std::cerr << "Sequences are not managed for opening " << open_mode_names[open_mode] << std::endl;
exit(1);
<< "--overlay file \t Overlay the image in file with complementary colors." << std::endl
<< "--fusion file \t Overlay the image in file with alpha blending and colormap." << std::endl
//<< "--roi file \t Overlay binary mask images. Option may be repeated on a single base image." << std::endl
- << "--contour file \t Overlay DICOM RT-STRUCT contours." << std::endl;
+ << "--contour file \t Overlay DICOM RT-STRUCT contours." << std::endl
+ << "--landmarks [--sequence] file(s) \t Overlay the landmarks in file(s) (.txt or .pts)." << std::endl;
exit(0);
} else if (current=="--vf") {
if (!n_image_loaded) load_image_first_error();
} else if (current=="--fusion") {
if (!n_image_loaded) load_image_first_error();
open_mode = O_FUSION;
+ } else if (current=="--landmarks") {
+ if (!n_image_loaded) load_image_first_error();
+ open_mode = O_LANDMARKS;
} else if (current == "--sequence") {
if(open_mode==O_BASE) n_image_loaded++; //count only one for the whole sequence
parse_mode=P_SEQUENCE;
window.AddDCStructContour(n_image_loaded-1,current.c_str());
else if (open_mode==O_FUSION)
window.AddFusionImage(n_image_loaded-1,current.c_str());
+ else if (open_mode==O_LANDMARKS)
+ window.AddLandmarks(n_image_loaded-1,image);
open_mode = O_BASE;
}
}
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "clitkCommon.h"
+#include <itksys/SystemTools.hxx>
//--------------------------------------------------------------------
vvLandmarks::vvLandmarks(int size)
{
- mLandmarks.resize(0);
- mFilename = "";
+ mLandmarks.resize(size);
+ mFilenames.resize(0);
+ mTime = 0;
for (int i = 0; i < size; i++) {
+ mLandmarks[i].resize(0);
vtkPoints *points = vtkPoints::New();
mPoints.push_back(points);
+ mIds.push_back(vtkFloatArray::New());
+ mLabels.push_back(vtkStringArray::New());
+ mLabels.back()->SetName("labels");
}
mPolyData = vtkPolyData::New();
- mIds = vtkFloatArray::New();
- mLabels = vtkStringArray::New();
- mLabels->SetName("labels");
}
//--------------------------------------------------------------------
{
for (unsigned int i = 0; i < mPoints.size(); i++) {
mPoints[i]->Delete();
+ mIds[i]->Delete();
+ mLabels[i]->Delete();
}
/*for(unsigned int i = 0; i < mText.size(); i++) {
mText[i]->Delete();
}*/
- if (mIds)
- mIds->Delete();
if (mPolyData)
mPolyData->Delete();
- if (mLabels)
- mLabels->Delete();
}
//--------------------------------------------------------------------
point.coordinates[2] = z;
point.coordinates[3] = t;
point.pixel_value=value;
- mLandmarks.push_back(point);
+ mLandmarks[mTime].push_back(point);
idPoint = mPoints[int(t)]->InsertNextPoint(x,y,z);
std::string str_vtkIdType; // string which will contain the result
std::ostringstream convert; // stream used for the conversion
convert << idPoint; // insert the textual representation of 'idPoint' in the characters in the stream
str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
- mLabels->InsertNextValue(str_vtkIdType.c_str());
+ mLabels[mTime]->InsertNextValue(str_vtkIdType.c_str());
std::stringstream numberVal;
numberVal << (mLandmarks.size()-1);
mText.push_back(number);
*/
- mIds->InsertNextTuple1(0.55);
+ mIds[mTime]->InsertNextTuple1(0.55);
//mIds->InsertTuple1(mLandmarks.size(),mLandmarks.size());
SetTime(int(t));
}
//--------------------------------------------------------------------
void vvLandmarks::RemoveLastLandmark()
{
- mPoints[mLandmarks.back().coordinates[3]]->SetNumberOfPoints(
- mPoints[mLandmarks.back().coordinates[3]]->GetNumberOfPoints()-1);
+ mPoints[mTime]->SetNumberOfPoints(mPoints[mTime]->GetNumberOfPoints()-1);
// mText.pop_back();
- mLandmarks.pop_back();
- mIds->RemoveLastTuple();
- mLabels->SetNumberOfValues(mLabels->GetNumberOfValues()-1);
- mLabels->Modified();
+ mLandmarks[mTime].pop_back();
+ mIds[mTime]->RemoveLastTuple();
+ mLabels[mTime]->SetNumberOfValues(mLabels[mTime]->GetNumberOfValues()-1);
+ mLabels[mTime]->Modified();
mPolyData->Modified();
}
//--------------------------------------------------------------------
// erase a vtkPoint by shifiting the array .
// not a problem here because there are no
// pologyons linking the points
- int npoints = mPoints[mLandmarks[index].coordinates[3]]->GetNumberOfPoints();
- int t = mLandmarks[index].coordinates[3];
+ int t = mTime;//mLandmarks[index].coordinates[3];
+ int npoints = mPoints[t]->GetNumberOfPoints();
for (int i = index; i < npoints - 1; i++) {
mPoints[t]->InsertPoint(i, mPoints[t]->GetPoint(i+1));
std::string str_i; // string which will contain the result
std::ostringstream convert; // stream used for the conversion
convert << i; // insert the textual representation of 'i' in the characters in the stream
str_i = convert.str(); // set 'str_i' to the contents of the stream
- mLabels->SetValue(i,str_i.c_str());
+ mLabels[t]->SetValue(i,str_i.c_str());
}
mPoints[t]->SetNumberOfPoints(npoints-1);
- mLabels->SetNumberOfValues(npoints-1);
- mLabels->Modified();
+ mLabels[t]->SetNumberOfValues(npoints-1);
+ mLabels[t]->Modified();
mPolyData->Modified();
- mLandmarks.erase(mLandmarks.begin() + index);
- mIds->RemoveLastTuple();
+ mLandmarks[t].erase(mLandmarks[t].begin() + index);
+ mIds[t]->RemoveLastTuple();
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+void vvLandmarks::RemoveAll()
+{
+ for (unsigned int i = 0; i < mLandmarks.size(); i++) {
+ mLandmarks[i].clear();
+ mPoints[i]->SetNumberOfPoints(0);
+ mLabels[i]->SetNumberOfValues(0);
+ mIds[i]->SetNumberOfValues(0);
+ }
+}
+//--------------------------------------------------------------------
//--------------------------------------------------------------------
void vvLandmarks::ChangeComments(int index, std::string comments)
{
- mLandmarks[index].comments = comments;
+ mLandmarks[mTime][index].comments = comments;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
double vvLandmarks::GetPixelValue(int index)
{
- return mLandmarks[index].pixel_value;
+ return mLandmarks[mTime][index].pixel_value;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
float* vvLandmarks::GetCoordinates(int index)
{
- return mLandmarks[index].coordinates;
+ return mLandmarks[mTime][index].coordinates;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
std::string vvLandmarks::GetComments(int index)
{
- return mLandmarks[index].comments;
+ return mLandmarks[mTime][index].comments;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
-void vvLandmarks::LoadFile(std::string filename)
+bool vvLandmarks::LoadFile(std::vector<std::string> filenames)
{
- std::ifstream fp(filename.c_str(), std::ios::in|std::ios::binary);
- if (!fp.is_open()) {
- std::cerr <<"Unable to open file " << filename << std::endl;
- return;
- }
- mFilename = filename;
- mLandmarks.clear();
- vtkIdType idPoint;
- char line[255];
- for (unsigned int i = 0; i < mPoints.size(); i++)
+ // all files in the sequence must be of the same type
+ std::string extension = itksys::SystemTools::GetFilenameExtension(filenames[0]);
+ if (extension == ".txt")
+ return LoadTxtFile(filenames);
+ else if (extension == ".pts")
+ return LoadPtsFile(filenames);
+
+ return false;
+}
+
+//--------------------------------------------------------------------
+bool vvLandmarks::LoadTxtFile(std::vector<std::string> filenames)
+{
+ mFilenames = filenames;
+ for (unsigned int i = 0; i < mPoints.size(); i++) {
+ mLandmarks[i].clear();
mPoints[i]->SetNumberOfPoints(0);
- bool first_line=true;
- while (fp.getline(line,255)) {
- // DD(line);
- std::string stringline = line;
- if (first_line) {
- first_line=false;
- ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
- if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0) {
- std::istringstream ss(stringline.c_str()+9);
- ss >> mFormatVersion;
- continue; //skip first line
- } else
- mFormatVersion=0;
+ }
+
+ int err = 0;
+ for (unsigned int f = 0; f < filenames.size(); f++) {
+ std::ifstream fp(filenames[f].c_str(), std::ios::in|std::ios::binary);
+ if (!fp.is_open()) {
+ std::cerr <<"Unable to open file " << filenames[f] << std::endl;
+ err++;
}
- if (stringline.size() > 1) {
- vvLandmark point;
- int previousSpace = 0;
- int space=0;
- if (mFormatVersion>0) {
+ vtkIdType idPoint;
+ char line[255];
+ bool first_line=true;
+ while (fp.getline(line,255)) {
+ // DD(line);
+ std::string stringline = line;
+ stringline += "\n";
+
+ if (first_line) {
+ first_line=false;
+ ///New landmark format: first line is "LANDMARKSXX", where XX is the version number
+ if (stringline.size() >= 10 && stringline.compare(0,9,"LANDMARKS")==0) {
+ std::istringstream ss(stringline.c_str()+9);
+ ss >> mFormatVersion;
+ continue; //skip first line
+ } else
+ mFormatVersion=0;
+ }
+ if (stringline.size() > 1) {
+ vvLandmark point;
+ int previousSpace = 0;
+ int space=0;
+ if (mFormatVersion>0) {
+ space = stringline.find(" ", previousSpace+1);
+ if (space < -1 || space > (int)stringline.size()) {
+ ErrorMsg(mLandmarks.size(),"index");
+ continue;
+ }
+ //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
+ previousSpace = space;
+ }
space = stringline.find(" ", previousSpace+1);
if (space < -1 || space > (int)stringline.size()) {
- ErrorMsg(mLandmarks.size(),"index");
+ ErrorMsg(mLandmarks.size(),"x position");
continue;
}
- //int index = atoi(stringline.substr(previousSpace,space - previousSpace).c_str());
+ point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ // DD(point.coordinates[0]);
previousSpace = space;
- }
- space = stringline.find(" ", previousSpace+1);
- if (space < -1 || space > (int)stringline.size()) {
- ErrorMsg(mLandmarks.size(),"x position");
- continue;
- }
- point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
- // DD(point.coordinates[0]);
- previousSpace = space;
- space = stringline.find(" ", previousSpace+1);
- if (space < -1 || space > (int)stringline.size()) {
- ErrorMsg(mLandmarks.size(),"y position");
- continue;
- }
- point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
- // DD(point.coordinates[1]);
- previousSpace = space;
- space = stringline.find(" ", previousSpace+1);
- if (space < -1 || space > (int)stringline.size()) {
- ErrorMsg(mLandmarks.size(),"z position");
- continue;
- }
- point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
- previousSpace = space;
- if (mFormatVersion>0) {
space = stringline.find(" ", previousSpace+1);
if (space < -1 || space > (int)stringline.size()) {
- ErrorMsg(mLandmarks.size(),"t position");
+ ErrorMsg(mLandmarks.size(),"y position");
continue;
}
- point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ // DD(point.coordinates[1]);
previousSpace = space;
space = stringline.find(" ", previousSpace+1);
if (space < -1 || space > (int)stringline.size()) {
- ErrorMsg(mLandmarks.size(),"pixel value");
+ ErrorMsg(mLandmarks.size(),"z position");
continue;
}
- point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
- // DD(point.pixel_value);
- } else {
- point.pixel_value=0.; //Not in file
- point.coordinates[3]=0.;
- }
- previousSpace = space;
- //this is the maximum size of comments
- space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
- if (previousSpace != -1) {
- point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
+ point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ previousSpace = space;
+ if (mFormatVersion>0) {
+ space = stringline.find(" ", previousSpace+1);
+ if (space < -1 || space > (int)stringline.size()) {
+ ErrorMsg(mLandmarks.size(),"t position");
+ continue;
+ }
+ point.coordinates[3] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ previousSpace = space;
+ space = stringline.find(" ", previousSpace+1);
+ if (space < -1 || space > (int)stringline.size()) {
+ ErrorMsg(mLandmarks.size(),"pixel value");
+ continue;
+ }
+ point.pixel_value = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ // DD(point.pixel_value);
+ } else {
+ point.pixel_value=0.; //Not in file
+ point.coordinates[3]=(float)f;
+ }
+ previousSpace = space;
+ //this is the maximum size of comments
+ space = (stringline.find("\n", previousSpace+1) < 254 ? stringline.find("\n", previousSpace+1) : 254);
+ if (previousSpace != -1) {
+ point.comments = stringline.substr(previousSpace,space - (previousSpace)).c_str();
+ }
+ // DD(point.comments);
+ mLandmarks[int(point.coordinates[3])].push_back(point);
+ mIds[int(point.coordinates[3])]->InsertNextTuple1(0.55);
+ idPoint = mPoints[int(point.coordinates[3])]->InsertNextPoint(
+ point.coordinates[0],point.coordinates[1],point.coordinates[2]);
+ std::string str_vtkIdType; // string which will contain the result
+ std::ostringstream convert; // stream used for the conversion
+ convert << idPoint; // insert the textual representation of 'idPoint' in the characters in the stream
+ str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
+ mLabels[int(point.coordinates[3])]->InsertNextValue(str_vtkIdType.c_str());
}
- // DD(point.comments);
- mLandmarks.push_back(point);
- mIds->InsertNextTuple1(0.55);
- idPoint = mPoints[int(point.coordinates[3])]->InsertNextPoint(
- point.coordinates[0],point.coordinates[1],point.coordinates[2]);
- std::string str_vtkIdType; // string which will contain the result
- std::ostringstream convert; // stream used for the conversion
- convert << idPoint; // insert the textual representation of 'idPoint' in the characters in the stream
- str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
- mLabels->InsertNextValue(str_vtkIdType.c_str());
}
}
+
+ if (err > 0 && err == filenames.size())
+ return false;
+
SetTime(0);
+
+ return true;
}
//--------------------------------------------------------------------
+//--------------------------------------------------------------------
+bool vvLandmarks::LoadPtsFile(std::vector<std::string> filenames)
+{
+ mFilenames = filenames;
+ for (unsigned int i = 0; i < mPoints.size(); i++) {
+ mPoints[i]->SetNumberOfPoints(0);
+ mLandmarks[i].clear();
+ }
+
+ int err = 0;
+ for (unsigned int f = 0; f < filenames.size(); f++) {
+ std::ifstream fp(filenames[f].c_str(), std::ios::in|std::ios::binary);
+ if (!fp.is_open()) {
+ std::cerr <<"Unable to open file " << filenames[f] << std::endl;
+ err++;
+ }
+ vtkIdType idPoint;
+ char line[255];
+ bool first_line=true;
+ while (fp.getline(line,255)) {
+ std::string stringline = line;
+ stringline += "\n";
+
+ std::string separators = "\t\n\r ";
+ if (stringline.size() > 1) {
+ vvLandmark point;
+ int previousSpace = 0;
+ int space=0;
+
+ if (stringline[0] == '#') // comments
+ continue;
+
+ space = stringline.find_first_of(separators, previousSpace+1);
+ if (space == std::string::npos) {
+ ErrorMsg(mLandmarks.size(),"x position");
+ continue;
+ }
+ point.coordinates[0] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ // DD(point.coordinates[0]);
+ previousSpace = space;
+ space = stringline.find_first_of(separators, previousSpace+1);
+ if (space == std::string::npos) {
+ ErrorMsg(mLandmarks.size(),"y position");
+ continue;
+ }
+ point.coordinates[1] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ // DD(point.coordinates[1]);
+ previousSpace = space;
+ space = stringline.find_first_of(separators, previousSpace+1);
+ if (space == std::string::npos) {
+ ErrorMsg(mLandmarks.size(),"z position");
+ continue;
+ }
+ point.coordinates[2] = atof(replace_dots(stringline.substr(previousSpace,space - previousSpace)).c_str());
+ previousSpace = space;
+ point.pixel_value=0.; //Not in file
+ point.coordinates[3]=(float)f; //Not in file
+ point.comments = ""; //Not in file
+
+ // DD(point.comments);
+ mLandmarks[int(point.coordinates[3])].push_back(point);
+ mIds[int(point.coordinates[3])]->InsertNextTuple1(0.55);
+ idPoint = mPoints[int(point.coordinates[3])]->InsertNextPoint(
+ point.coordinates[0],point.coordinates[1],point.coordinates[2]);
+ std::string str_vtkIdType; // string which will contain the result
+ std::ostringstream convert; // stream used for the conversion
+ convert << idPoint; // insert the textual representation of 'idPoint' in the characters in the stream
+ str_vtkIdType = convert.str(); // set 'str_vtkIdType' to the contents of the stream
+ mLabels[int(point.coordinates[3])]->InsertNextValue(str_vtkIdType.c_str());
+ }
+ }
+ }
+
+ SetTime(0);
+ DD("vvLandmarks::LoadPtsFile")
+ if (err > 0 && err == filenames.size())
+ return false;
+
+
+ return true;
+}
+//--------------------------------------------------------------------
//--------------------------------------------------------------------
bool vvLandmarks::ErrorMsg(int num,const char * text)
void vvLandmarks::SaveFile(std::string filename)
{
std::string fileContent = "LANDMARKS1\n"; //File format version identification
- for (unsigned int i = 0; i < mLandmarks.size(); i++) {
- std::stringstream out;
- out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
- out << i << " "
- << mLandmarks[i].coordinates[0] << " "
- << mLandmarks[i].coordinates[1] << " "
- << mLandmarks[i].coordinates[2] << " "
- << mLandmarks[i].coordinates[3] << " "
- << mLandmarks[i].pixel_value << " ";
- fileContent += out.str();
- if (mLandmarks[i].comments.size() == 0)
- fileContent += " ";
- else
- fileContent += mLandmarks[i].comments;
- fileContent += "\n";
+ for (unsigned int t = 0; t < mLandmarks.size(); t++) {
+ for (unsigned int i = 0; i < mLandmarks[t].size(); i++) {
+ std::stringstream out;
+ out.imbue(std::locale("C")); //This is to specify that the dot is to be used as the decimal separator
+ out << i << " "
+ << mLandmarks[t][i].coordinates[0] << " "
+ << mLandmarks[t][i].coordinates[1] << " "
+ << mLandmarks[t][i].coordinates[2] << " "
+ << mLandmarks[t][i].coordinates[3] << " "
+ << mLandmarks[t][i].pixel_value << " ";
+ fileContent += out.str();
+ if (mLandmarks[t][i].comments.size() == 0)
+ fileContent += " ";
+ else
+ fileContent += mLandmarks[t][i].comments;
+ fileContent += "\n";
+ }
}
std::ofstream fp(filename.c_str(), std::ios::trunc);
if ( !fp ) {
{
if (time >= 0 && time <= ((int)mPoints.size() -1)) {
mPolyData->SetPoints(mPoints[time]);
- mPolyData->GetPointData()->SetScalars(mIds);
- mPolyData->GetPointData()->AddArray(mLabels);
+ mPolyData->GetPointData()->SetScalars(mIds[time]);
+ mPolyData->GetPointData()->AddArray(mLabels[time]);
mPolyData->Modified();
mPolyData->Update();
+ mTime = time;
}
}
//--------------------------------------------------------------------
vvLandmarks(int size);
~vvLandmarks();
- void LoadFile(std::string filename);
+ bool LoadFile(std::vector<std::string> filename);
void SaveFile(std::string filename);
void AddLandmark(float x,float y,float z,float t,double value);
void RemoveLastLandmark();
void RemoveLandmark(int index);
+ void RemoveAll();
+
void ChangeComments(int index, std::string comments);
float* GetCoordinates(int index);
double GetPixelValue(int index);
std::string GetComments(int index);
- unsigned int GetNumberOfPoints() { return (unsigned int) mLandmarks.size(); }
+ unsigned int GetNumberOfPoints() { return (unsigned int) mLandmarks[mTime].size(); }
//int GetNumberOfSources(){return mText.size();}
vtkPolyData* GetOutput() {
}
//vtkPolyData* GetSources(int i){return mText[i]->GetOutput();}
void SetTime(int time);
+ int GetTime() {return mTime; }
bool ErrorMsg(int num,const char * text);
private:
///Helper function to tackle the use of the comma as the decimal separator
std::string replace_dots(std::string input);
- std::vector<vvLandmark> mLandmarks;
+
+ typedef std::vector<vvLandmark> LandmarkContainerType;
+ std::vector<LandmarkContainerType> mLandmarks;
+
vtkPolyData *mPolyData;
std::vector<vtkPoints*> mPoints;
- vtkFloatArray* mIds;
+ std::vector<vtkFloatArray*> mIds;
//std::vector<vvLandmarksGlyph*> mText;
- vtkStringArray* mLabels;
- std::string mFilename;
+ std::vector<vtkStringArray*> mLabels;
+ std::vector<std::string> mFilenames;
int mFormatVersion;
+ int mTime;
+
+ bool LoadTxtFile(std::vector<std::string> filenames);
+ bool LoadPtsFile(std::vector<std::string> filenames);
+
};
#endif
#include "vvLandmarks.h"
#include <vtksys/SystemTools.hxx>
+#include <clitkDD.h>
//====================================================================
vvLandmarksPanel::vvLandmarksPanel(QWidget * parent):QWidget(parent)
connect(loadButton, SIGNAL(clicked()),this,SLOT(Load()));
connect(saveButton, SIGNAL(clicked()),this,SLOT(Save()));
connect(removeButton, SIGNAL(clicked()),this,SLOT(RemoveSelectedPoints()));
+ connect(removeAllButton, SIGNAL(clicked()),this,SLOT(RemoveAllPoints()));
connect(tableWidget,SIGNAL(cellChanged(int,int)),this,SLOT(CommentsChanged(int,int)));
+ connect(tableWidget,SIGNAL(doubleClicked(const QModelIndex &)),this,SLOT(SelectPoint()));
}
void vvLandmarksPanel::Load()
{
QString file = QFileDialog::getOpenFileName(this,tr("Load Landmarks"),
- mCurrentPath.c_str(),tr("Landmarks ( *.txt)"));
- if (!file.isEmpty())
- mCurrentLandmarks->LoadFile(file.toStdString());
+ mCurrentPath.c_str(),tr("Landmarks ( *.txt *.pts)"));
+ if (!file.isEmpty()) {
+ std::vector<std::string> files(1, file.toStdString());
+ LoadFromFile(files);
+ }
+}
+
+bool vvLandmarksPanel::LoadFromFile(std::vector<std::string> files)
+{
+ if (!mCurrentLandmarks->LoadFile(files))
+ return false;
+
SetCurrentLandmarks(mCurrentLandmarks,2);
emit UpdateRenderWindows();
+ return true;
}
void vvLandmarksPanel::Save()
}
}
+void vvLandmarksPanel::SelectPoint()
+{
+ if (tableWidget->rowCount() > 0) {
+ QList<QTableWidgetItem *> items = tableWidget->selectedItems();
+ if (!items.empty()) {
+ // we're using single-selection mode
+ int row = items[0]->row();
+ mSelectedPoint[0] = mCurrentLandmarks->GetCoordinates(row)[0];
+ mSelectedPoint[1] = mCurrentLandmarks->GetCoordinates(row)[1];
+ mSelectedPoint[2] = mCurrentLandmarks->GetCoordinates(row)[2];
+ mSelectedPoint[3] = mCurrentLandmarks->GetCoordinates(row)[3];
+
+ emit SelectedPointChanged();
+ }
+ }
+
+}
+
+
void vvLandmarksPanel::RemoveSelectedPoints()
{
if (tableWidget->rowCount() > 0) {
}
}
+void vvLandmarksPanel::RemoveAllPoints()
+{
+ mCurrentLandmarks->RemoveAll();
+ tableWidget->clearContents();
+ tableWidget->setRowCount(0);
+ emit UpdateRenderWindows();
+}
+
void vvLandmarksPanel::AddPoint()
{
AddPoint(mCurrentLandmarks->GetNumberOfPoints()-1);
void vvLandmarksPanel::AddPoint(int landmarksIndex)
{
- int rowIndex = landmarksIndex; //tableWidget->rowCount();
+ int rowIndex = tableWidget->rowCount();
+// DD(rowIndex);
tableWidget->setRowCount(rowIndex+1);
tableWidget->setRowHeight(rowIndex,20);
- QTableWidgetItem* iItem = new QTableWidgetItem(QString::number(landmarksIndex));
+ QTableWidgetItem* iItem = new QTableWidgetItem(QString::number(rowIndex));
iItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
tableWidget->setItem(rowIndex,0,iItem);
void vvLandmarksPanel::SetCurrentLandmarks(vvLandmarks* lm,int time)
{
+ if (time != lm->GetTime())
+ return;
+
loadButton->setEnabled(1);
saveButton->setEnabled(1);
removeButton->setEnabled(1);
mCurrentLandmarks = lm;
tableWidget->clearContents();
- tableWidget->setRowCount(mCurrentLandmarks->GetNumberOfPoints());
- for (unsigned int i = 0; i < mCurrentLandmarks->GetNumberOfPoints(); i++)
- AddPoint(i);
+ tableWidget->setRowCount(0);
+ for (unsigned int i = 0; i < mCurrentLandmarks->GetNumberOfPoints(); i++) {
+ AddPoint(i);
+ }
//if (time > 1)
//tableWidget->setColumnHidden(4,1);
//else
mCurrentPath = path;
}
void SetCurrentImage(std::string filename);
+ double* GetSelectedPoint() { return mSelectedPoint; }
public slots:
void Load();
+ bool LoadFromFile(std::vector<std::string> file);
void Save();
void RemoveSelectedPoints();
+ void RemoveAllPoints();
void AddPoint();
+ void SelectPoint();
void CommentsChanged(int row, int column);
signals:
void UpdateRenderWindows();
+ void SelectedPointChanged();
private:
void AddPoint(int);
+
vvLandmarks* mCurrentLandmarks;
std::string mCurrentPath;
+ double mSelectedPoint[4];
}; // end class vvLandmarksPanel
//====================================================================
connect(overlayPanel,SIGNAL(FusionPropertyUpdated(int,int,int,double,double, bool)),
this,SLOT(SetFusionProperty(int,int,int,double,double, bool)));
connect(landmarksPanel,SIGNAL(UpdateRenderWindows()),this,SLOT(UpdateRenderWindows()));
+ connect(landmarksPanel,SIGNAL(SelectedPointChanged()),this,SLOT(GoToLandmark()));
playMode = 0;//pause
mFrameRate = 10;
mInputPathName = itksys::SystemTools::GetFilenamePath(files[0].toStdString()).c_str();
std::vector<std::string> vector;
- unsigned int currentDim = 0;
- std::vector<double> currentSpacing;
- std::vector<int> currentSize;
- std::vector<double> currentOrigin;
-
- for (int i = 0; i < files.size(); i++) {
- itk::ImageIOBase::Pointer reader = itk::ImageIOFactory::CreateImageIO(
- files[i].toStdString().c_str(), itk::ImageIOFactory::ReadMode);
- if (reader) {
- reader->SetFileName(files[i].toStdString().c_str());
- reader->ReadImageInformation();
- if (i == 0)
- currentDim = reader->GetNumberOfDimensions();
- bool IsOk = true;
- for (unsigned int j = 0; j < currentDim; j++) {
- if (i == 0) {
- if (j == 0) {
- currentSpacing.resize(currentDim);
- currentSize.resize(currentDim);
- currentOrigin.resize(currentDim);
- }
- currentOrigin[j] = reader->GetOrigin(j);
- currentSpacing[j] = reader->GetSpacing(j);
- currentSize[j] = reader->GetDimensions(j);
- } else if (currentDim != reader->GetNumberOfDimensions()
- || currentSpacing[j] != reader->GetSpacing(j)
- || currentSize[j] != (int)reader->GetDimensions(j)
- || currentOrigin[j] != reader->GetOrigin(j)) {
- QString error = "Cannot read file (too different from others ";
- error += files[i].toStdString().c_str();
- QMessageBox::information(this,tr("Reading problem"),error);
- IsOk = false;
- break;
- }
- }
- if (IsOk)
- vector.push_back(files[i].toStdString());
- } else {
- QString error = "Cannot read file info for ";
- error += files[i].toStdString().c_str();
- error += "\n";
- error += "Maybe you're trying to open an image in an unsupported format?\n";
- QMessageBox::information(this,tr("Reading problem"),error);
- }
- }
+ for (int i = 0; i < files.size(); i++)
+ vector.push_back(files[i].toStdString());
sort(vector.begin(),vector.end());
if (vector.size() > 1)
LoadImages(vector, vvImageReader::MERGEDWITHTIME);
}
DataTree->topLevelItem(selected)->setSelected(1);
mCurrentSelectedImageId = id;
+
+ landmarksPanel->SetCurrentLandmarks(mSlicerManagers[selected]->GetLandmarks(),
+ mSlicerManagers[selected]->GetTSlice());
+ landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
+ landmarksPanel->SetCurrentImage(mSlicerManagers[selected]->GetFileName().c_str());
+
emit SelectedImageHasChanged(mSlicerManagers[selected]);
}
//------------------------------------------------------------------------------
infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
- mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
+ mSlicerManagers[index]->GetTSlice());
landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
}
}
- infoPanel->setFileName(image);
- infoPanel->setDimension(dim);
- infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
- infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
- infoPanel->setOrigin(GetVectorDoubleAsString(origin));
- infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
- infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
-
- landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
- mSlicerManagers[index]->GetSlicer(0)->GetImage()->GetVTKImages().size());
- landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
- landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
-
- overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
- for (int i = 0; i < 4; i++) {
- if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
- mSlicerManagers[index]->UpdateInfoOnCursorPosition(i);
- break;
- }
- }
+// infoPanel->setFileName(image);
+// infoPanel->setDimension(dim);
+// infoPanel->setSizePixel(GetVectorIntAsString(inputSize));
+// infoPanel->setSizeMM(GetVectorDoubleAsString(sizeMM));
+// infoPanel->setOrigin(GetVectorDoubleAsString(origin));
+// infoPanel->setSpacing(GetVectorDoubleAsString(inputSpacing));
+// infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
+//
+// landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
+// mSlicerManagers[index]->GetTSlice());
+// landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
+// landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
+//
+// overlayPanel->getCurrentImageName(mSlicerManagers[index]->GetFileName().c_str());
+// for (int i = 0; i < 4; i++) {
+// if (DataTree->selectedItems()[0]->data(i+1,Qt::CheckStateRole).toInt() > 0 || i == 3) {
+// mSlicerManagers[index]->UpdateInfoOnCursorPosition(i);
+// break;
+// }
+// }
WindowLevelChanged();
slicingPresetComboBox->setCurrentIndex(mSlicerManagers[index]->GetSlicingPreset());
QMessageBox::information(this,tr("Problem reading Fusion !"),"File doesn't exist!");
}
//------------------------------------------------------------------------------
-
+//------------------------------------------------------------------------------
+void vvMainWindow::AddLandmarks(int index, std::vector<std::string> files)
+{
+ if (!landmarksPanel->LoadFromFile(files))
+ QMessageBox::information(this,tr("Problem reading Landmarks !"),"File doesn't exist!");
+
+ landmarksPanel->SetCurrentPath(mInputPathName.toStdString());
+ landmarksPanel->SetCurrentImage(mSlicerManagers[index]->GetFileName().c_str());
+}
//------------------------------------------------------------------------------
void vvMainWindow::OpenField()
}
//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void vvMainWindow::GoToLandmark()
+{
+ int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
+ for (int column = 1; column < 5; column++) {
+ if (DataTree->selectedItems()[0]->data(column,Qt::CheckStateRole).toInt() > 1) {
+ double* cursorPos = landmarksPanel->GetSelectedPoint();
+ mSlicerManagers[index]->GetSlicer(column-1)->SetCurrentPosition(
+ cursorPos[0],cursorPos[1],cursorPos[2],cursorPos[3]);
+ mSlicerManagers[index]->UpdateViews(1,column-1);
+ mSlicerManagers[index]->UpdateLinked(column-1);
+ break;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
void vvMainWindow::PlayPause()
{
void AddOverlayImage(int index, std::vector<std::string> fileNames, vvImageReader::LoadedImageType type);
void AddFusionImage(int index, QString filename);
void AddROI(int index, QString filename);
- ///Adds a mesh to a SlicerManager, with optional warping by vector field
+ void AddLandmarks(int index, std::vector<std::string>);
+///Adds a mesh to a SlicerManager, with optional warping by vector field
void AddContour(int image_index, vvMesh::Pointer contour, bool propagation);
///This is used to show an image when opened or computed
void ShowLastImage();
void SetFusionProperty(int opacity, int tresOpacity, int colormap,double window,double level, bool showLegend);
void GoToCursor();
+ void GoToLandmark();
void PlayPause();
void PlayNext();
void ChangeFrameRate(int rate) {