int main(int argc, char * argv[]) { int width = 0; int height = 0; int depth = 0; int channels = 1; unsigned char * img = NULL; img = readtiff(argv[1], &height, &width, &depth, &channels); int min_thresh = atoi(argv[2]); int max_thresh = atoi(argv[3]); int single_thresh = atoi(argv[4]); cout<<"width = "<<width<<" height = "<<height<<" depth = "<<depth<<" channels = "<<channels<<endl; cout<<"min_thresh = "<<min_thresh<<" max_thresh = "<<max_thresh<<" single_thresh = "<<single_thresh<<endl; ComponentTree tree; tree.create(argv[1], min_thresh, max_thresh, single_thresh); if(argc == 5) { string str_file(argv[1]); str_file = str_file.substr(0, str_file.rfind(".")); str_file.append(".bin.tree"); tree.save(str_file.c_str()); } else if(argc == 6) { tree.save(argv[5]); } }
void processWDestructibleElement(Image& image, ComponentTree& componentTree, WDestructibleElement& element, WDestructibleElementsCollection& wDestructibleElements, const vector<int>& priority) { image.setPixelValue(element.pixelPosition,element.futureNode->getLevel() - 1); componentTree.setComponent(element.pixelPosition,element.futureNode); for (auto& neighbor : image.getNeighbors(element.pixelPosition)) { if (element.futureNode->getLevel() <= image.at(neighbor)) { PIXEL_TYPE type = MINIMUM; Node* node = wDestructible(image,componentTree,neighbor,type); if (!node) { wDestructibleElements.removeElement(neighbor); } else { wDestructibleElements.addElement( WDestructibleElement(neighbor, image.at(neighbor), priority.at(neighbor), node, type == FUTURE_MINIMUM)); } } } }
CellTrack::Frame merge_frames(ComponentTree &tree, double* row, CellTrack::Frame &f1, CellTrack::Frame &f2) { int count = 0; CellTrack::Frame merge_frame = f1; for(int j = 0; j < f2.size(); j++) { int match = 0; for(int i=0; i < f1.size();i++) { //merge two cell if(fabs(row[i*(f2.size())+j] - 1.0)< 0.001) { match = 1; count++; CellTrack::Cell* c1 = f1[i]; CellTrack::Cell* c2 = f2[j]; if((tree.getNode(c1->label))->alpha_size < (tree.getNode(c2->label))->alpha_size) { c1->nextLabel = c2->nextLabel; // if c2 label is larger , assign c2's nextLabel to c1's label c1->label = c2->nextLabel; } c1->next = c2->next; assert(c2->next != NULL); (c2->next)->prev = c1; delete c2; c2 = NULL; break; // one j only match with one i } } //deal with the unmatched cell if(match == 0) { merge_frame.push_back(f2[j]); } } f1.clear(); f2.clear(); cout<<"\t"<<count<<"matches"<<endl; return merge_frame; }
int main(int argc, char * argv[]) { if(argc > 3 || argc < 2) { cout<<"usage : tree_graph <component_tree_file> [output_file]"<<endl; return 1; } ComponentTree tree; tree.load(argv[1]); //tree.printTree(); //tree.printReverseAlphaMapping(); if(argc == 3) tree.saveGraph(argv[2]); else { char graph_file[255] = ""; strcat(graph_file, argv[1]); strcat(graph_file, ".dot"); tree.saveGraph(graph_file); } }
bool CellTrackController::createCellTrack(vector<string> image_files, int _min, int _max, int _single) { if(_min > _max || _min < 0 || _single < 0 ) { return false; } else { this->clear(); ComponentTree *tree = new ComponentTree(); vector<string> tree_files; for(int i = 0; i < (int)image_files.size(); i++) { tree->clear(); tree->create((char*) image_files[i].c_str(), _min, _max, _single); //=============================================== string tree_file = image_files[i]; tree_file = tree_file.substr(0, tree_file.rfind(".")); tree_file.append(".bin.tree"); //=============================================== tree->save((const char*)tree_file.c_str()); tree_files.push_back(tree_file); } celltrack = new CellTrack(); bool rt = celltrack->createFromTrees(tree_files); if(rt) { this->initTracksState(); } /* vector<char*>::iterator it = tree_files.begin(); while(it != tree_files.end()) { delete (*it); it++; } */ return rt; } }
void doTopologicalWatershedOnBorder(Image& image, ComponentTree& componentTree, const vector<int>& priority) { WDestructibleElementsCollection elements = initializeSet(image,componentTree, pendingBorderPoints, priority); while(!elements.isEmpty()) { WDestructibleElement element = elements.getMinimum(); image.setPixelValue(element.pixelPosition,element.futureNode->getLevel() - 1); componentTree.setComponent(element.pixelPosition,element.futureNode); for (auto& neighbor : image.getNeighbors(element.pixelPosition)) { if (element.futureNode->getLevel() <= image.at(neighbor)) { PIXEL_TYPE type = MINIMUM; Node* node = wDestructible(image,componentTree,neighbor,type); if (!node) { elements.removeElement(neighbor); pendingInnerPoints.erase(neighbor); } else { if(elements.isPresent(neighbor)) { elements.addElement( WDestructibleElement(neighbor,image.at(neighbor), priority.at(neighbor),node, type == FUTURE_MINIMUM)); } else { pendingInnerPoints.insert(neighbor); } } } } } }
bool CellTrack::Alignment::align(ComponentTree &tree, Frame& f1, Frame & f2) { /* * 1. getParams variables */ clear(); m_numVars1 = f1.size(); m_numVars2 = f2.size(); m_weightMatrix.resize(m_numVars1); for(int i = 0 ; i < m_numVars1; i++) { m_weightMatrix[i].resize(m_numVars2); for(int j=0; j < m_numVars2; j++) m_weightMatrix[i][j] = 0.0; } vector<int> labels1; vector<int> labels2; vector<int> values1; vector<int> values2; int value = 0; //1.1 get labels1, labels2 and values1 , values2 Frame::iterator it = f1.begin(); while(it != f1.end()) { labels1.push_back((*it)->label); values1.push_back(value++); it++; } value = 0; it = f2.begin(); while(it != f2.end()) { labels2.push_back((*it)->label); values2.push_back(value++); it++; } /* * 2. set weight matrix */ //the matrix's value is the label's index in vector //which is more convenient than store label value int* matrix1 = tree.getMatrix(labels1,values1, -1); int* matrix2 = tree.getMatrix(labels2,values2, -1); int numVertices = tree.pixelCount(); // 2.1 set the num of overlap points for(int v = 0; v < numVertices ; v++) { //find the nodes in each component tree int label1 = matrix1[v]; int label2 = matrix2[v]; if(label1 == -1 || label2 == -1) continue; m_weightMatrix[label1][label2]++; } // 2.2 set the overlap value float intersection = 0; float joint = 1; for(int i = 0; i < m_numVars1; i++) { for(int j = 0; j < m_numVars2; j++) { intersection = m_weightMatrix[i][j]; joint = tree.getNode(labels1[i])->alpha_size + tree.getNode(labels2[j])->alpha_size - intersection; assert(joint > 0.0001); m_weightMatrix[i][j] = (float)intersection/joint; } } // 2.3 free space delete matrix1; delete matrix2; /* * 3. build the linear model */ // 3.1 getParams variable lprec *lp; int Ncol, *colno=NULL, k; REAL * row = NULL; int i=0,j=0; Ncol = m_numVars1 * m_numVars2; lp = make_lp(0,Ncol); if(lp == NULL) return false; colno = (int *) malloc(Ncol * sizeof(*colno)); row = (REAL *) malloc(Ncol * sizeof(*row)); if((colno == NULL) || (row == NULL)) return false; for(i=0;i< Ncol;i++) row[i]=1.0; // assign all the content of row as 1 set_add_rowmode(lp,TRUE); set_binary(lp,Ncol,TRUE); // 3.2 the sum of each row is less than 1 for(int i = 0; i < m_numVars1; i++) { k=0; for(j=0;j<m_numVars2;j++)colno[k++] = i*m_numVars2+j+1; //one path on constraint if(!add_constraintex(lp, k, row, colno, LE, 1)) return false; } // 3.3 the sum of each column is less than 1 for(int j = 0; j < m_numVars2; j++) { k=0; for(i=0;i<m_numVars1;i++)colno[k++] = i*m_numVars2+j+1; if(!add_constraintex(lp, k, row, colno, LE, 1)) return false; } set_add_rowmode(lp,FALSE); //I don't know why, just write it // 3.4 set the object k=0; for(i=0;i< m_numVars1; i++) { for(j=0; j< m_numVars2; j++) { colno[k] = i*m_numVars2+j+1; row[k++] = m_weightMatrix[i][j]; } } if(!set_obj_fnex(lp, k, row, colno))return false; set_maxim(lp); set_verbose(lp,IMPORTANT); // 3.5 solve the problem if(::solve(lp) != OPTIMAL) { cout<<"Not optimized results"<<endl; return false; } // 3.6 save result to m_row get_variables(lp,row); m_row = row; // 3.7 print out matched result // 3.8 free space //if(row != NULL) // free(row); if(colno != NULL) { free(colno); colno = NULL; } if(lp != NULL) { delete_lp(lp); } return true; }
bool CellTrack::Alignment::align(ComponentTree& tree1, ComponentTree& tree2) { /* * 1. check the valiad of the tree */ if(tree1.width() != tree2.width() || tree1.height() != tree2.height() || tree1.depth() != tree2.depth()) { cerr<<"The two trees with different size. Unalbe to align."<<endl; return false; } /* * 2. clear the original data and getParams member variable */ clear(); m_numVars1 = tree1.nodeCount(); m_numVars2 = tree2.nodeCount(); m_weightMatrix.resize(m_numVars1); for(int i = 0 ; i < m_numVars1; i++) { m_weightMatrix[i].resize(m_numVars2); for(int j=0; j < m_numVars2; j++) m_weightMatrix[i][j] = 0.0; } /* * 3. set weight matrix */ int numVertices = tree1.pixelCount(); int* matrix1 = tree1.getMappingMatrix(); int* matrix2 = tree2.getMappingMatrix(); // 3.1 get the overlap of each subset for(int v = 0; v < numVertices ; v++) { int label1 = matrix1[v]; int label2 = matrix2[v]; if(1) { if(label1 != m_numVars1-1 && label2 != m_numVars2-1 )m_weightMatrix[label1][label2]++; } else { m_weightMatrix[label1][label2]++; } } // 3.2 get the overlp of tree1's sub node with any of tree2's node // include the sub node and the merged component ComponentTree::Nodes::iterator it; for(int i = 0; i < m_numVars1- 1; i++) { for(int j = 0; j < m_numVars2- 1; j++) { ComponentTree::Node* node2 = tree2.getNode(j); if(! node2->childs.empty()) { it = node2->childs.begin(); //cout<<"node2 size = "<<node2->childs.size()<<endl; while( it != node2->childs.end()) { int jj = (*it)->label; m_weightMatrix[i][j] += m_weightMatrix[i][jj]; it++; } } } } // 3.3 merge tree1's match result for node with childs for(int i = 0; i < m_numVars1 - 1; i++) { for(int j = 0; j < m_numVars2 - 1; j++) { ComponentTree::Node* node1 = tree1.getNode(i); if(! node1->childs.empty()) { it = node1->childs.begin(); while( it != node1->childs.end()) { int ii = (*it)->label; m_weightMatrix[i][j] += m_weightMatrix[ii][j]; it++; } } } } // 3.4 get the 0 ~ 1 overlap value float intersection = 0; float joint = 1; for(int i = 0; i < m_numVars1; i++) { for(int j = 0; j < m_numVars2; j++) { intersection = m_weightMatrix[i][j]; joint = tree1.getNode(i)->alpha_size + tree2.getNode(j)->alpha_size - intersection; assert(joint > 0.0001); m_weightMatrix[i][j] = (float)intersection/joint; } } if(verbose) { cout<<"weight matrix : "<<endl; cout.precision(3); cout<<" t1\\t2 "; for(int j = 0; j < m_numVars2; j++) cout<<setw(7)<<j; cout<<endl; for(int i = 0; i < m_numVars1; i++) { cout<<i<<" : "; for(int j = 0; j < m_numVars2; j++) { cout<<setw(7)<<m_weightMatrix[i][j]<<" "; } cout<<endl; } } // 3.5 free matrix delete matrix1; delete matrix2; /* * 4. build the linear model */ ComponentTree::Paths ps1 = tree1.getPaths(); ComponentTree::Paths ps2 = tree2.getPaths(); // 4.1 getParams linear variable lprec *lp; int Ncol, *colno=NULL, k; REAL * row = NULL; int i=0,j=0; Ncol = m_numVars1 * m_numVars2; lp = make_lp(0,Ncol); if(lp == NULL) return false; colno = (int *) malloc(Ncol * sizeof(*colno)); row = (REAL *) malloc(Ncol * sizeof(*row)); if((colno == NULL) || (row == NULL)) return false; for(i=0;i< Ncol;i++) row[i]=1.0; // assign all the content of row as 1 set_add_rowmode(lp,TRUE); set_binary(lp,Ncol,TRUE); // 4.2 add ps1 constraints //one path one constraint ComponentTree::Paths::iterator it2=ps1.begin(); while(it2 != ps1.end()) { k=0; ComponentTree::Path::iterator itr = (*it2).begin(); while(itr != (*it2).end()) { i = (*itr); for(j=0;j<m_numVars2;j++)colno[k++] = i*m_numVars2+j+1; itr++; } if(!add_constraintex(lp, k, row, colno, LE, 1)) return false; it2++; } // 4.3 : add ps2 constraints it2=ps2.begin(); while (it2 != ps2.end()) { ComponentTree::Path::iterator itr = (*it2).begin(); k=0; while(itr != (*it2).end()) { j = (*itr); for(i=0;i<m_numVars1;i++)colno[k++] = i*m_numVars2+j+1; itr++; } if(!add_constraintex(lp, k, row, colno, LE, 1)) return false; it2++; } set_add_rowmode(lp,FALSE); // 4.4 add the object k=0; for(i=0;i< m_numVars1; i++) for(j=0; j< m_numVars2; j++) { colno[k] = i*m_numVars2+j+1; row[k++] = m_weightMatrix[i][j]; } if(!set_obj_fnex(lp, k, row, colno))return false; set_maxim(lp); set_verbose(lp,IMPORTANT); // 4.5 solve the linear problem if(::solve(lp) != OPTIMAL) { cout<<"Not optimized results"<<endl; return false; } // 4.6 save results to m_row // print out the match pairs get_variables(lp,row); m_row = row; if(verbose) { cout<<"mapping : "; for(int i = 0; i < m_numVars1; i++) { for(int j = 0; j < m_numVars2; j++) { if(fabs(row[i*m_numVars2+j] - 1.0)< 0.001) { cout<<i<<"<->"<<j<<" "; break; // one i only match with one j } } } cout<<endl; } // 4.7 free heap space //if(row != NULL) // free(row); if(colno != NULL) free(colno); if(lp != NULL) { delete_lp(lp); } return true; }