/** * \file image_processing_helper.cpp * \brief Helper functions for the image_processing main file * * Copyright 2007-2013 IMP Inventors. All rights reserved. * */ #include "IMP/em2d/internal/image_processing_helper.h" #include "IMP/em2d/opencv_interface.h" #include "IMP/exception.h" #include #include IMPEM2D_BEGIN_INTERNAL_NAMESPACE cvPixels get_neighbors2d(const cvPixel &p, const cv::Mat &m, int mode, int sign, bool cycle) { cvPixels neighbors,final_neighbors; if(mode !=4 && mode !=8) IMP_THROW("Mode must be either 4 or 8",ValueException); if(sign !=1 && sign !=0 && sign!=-1) IMP_THROW("Sign must be -1,0, or 1",ValueException); if(mode == 4) { if(sign == 0) { neighbors.push_back(p+cvPixel(-1, 0)); neighbors.push_back(p+cvPixel( 0, 1)); neighbors.push_back(p+cvPixel( 1, 0)); neighbors.push_back(p+cvPixel( 0,-1)); } else if( sign == 1) { neighbors.push_back(p+cvPixel(0,1)); neighbors.push_back(p+cvPixel(1,0)); } else { neighbors.push_back(p+cvPixel(-1, 0)); neighbors.push_back(p+cvPixel( 0,-1)); } } else { if(sign == 0) { neighbors.push_back(p+cvPixel(-1, 0)); neighbors.push_back(p+cvPixel(-1, 1)); neighbors.push_back(p+cvPixel( 0, 1)); neighbors.push_back(p+cvPixel( 1, 1)); neighbors.push_back(p+cvPixel( 1, 0)); neighbors.push_back(p+cvPixel( 1,-1)); neighbors.push_back(p+cvPixel( 0,-1)); neighbors.push_back(p+cvPixel(-1,-1)); } else if( sign == 1) { neighbors.push_back(p+cvPixel(-1, 0)); neighbors.push_back(p+cvPixel(-1, 1)); neighbors.push_back(p+cvPixel( 0,-1)); neighbors.push_back(p+cvPixel(-1,-1)); } else { neighbors.push_back(p+cvPixel( 0, 1)); neighbors.push_back(p+cvPixel( 1, 1)); neighbors.push_back(p+cvPixel( 1, 0)); neighbors.push_back(p+cvPixel( 1,-1)); } } if(cycle) { // Cycle indexes out of the matrix for(unsigned int i=0;i= m.rows) q.x = 0; if(q.y < 0) q.y = m.cols-1; if(q.y >= m.cols) q.y = 0; final_neighbors.push_back(q); } } else { // Clean neighbors with indexes out of the matrix for(unsigned int i=0;i= 0 && q.x=0 && q.y root_j) { root = root_j; } // Set the lowest label set_root(Labels,j,root); } set_root(Labels,i,root); return root; } //! Decission tree copy function void do_copy_tree(const cvPixel &p, const cvPixel &a, cvIntMat &mat_to_label) { mat_to_label(p) = mat_to_label(a); } //! Decission tree copy function void do_copy_tree(const cvPixel &p, const cvPixel &a, const cvPixel &c, cvIntMat &mat_to_label, Ints &Labels) { mat_to_label(p) = do_union(Labels,mat_to_label(c),mat_to_label(a)); } //! Sets a new label for a pixel int get_new_label(const cvPixel &p, cvIntMat &mat_to_label, Ints &Labels, int label) { mat_to_label(p) = label; Labels.push_back(label); int next_label=label+1; return next_label; } int find_root(const Ints &Labels, int i) { int root = i; while(Labels[root] < root) { root = Labels[root]; } return root; } void set_root(Ints &Labels,int i, int root) { while(Labels[i](row,col-1); double w2 = m.at(row, col); double w3 = m.at(row,col+1); peak[0]=((col-1) *w1 + col*w2 + (col+1) * w3)/(w1+w2+w3); } else if(col==col0 || col==coln) { // Column borders, average double w1 = m.at(row-1,col); double w2 = m.at(row ,col); double w3 = m.at(row+1,col); peak[1]=((row-1)*w1+row*w2+(row+1)*w3)/(w1+w2+w3); peak[0]=col; } else { // Points inside the matrix unsigned int row_origin = row-1; unsigned int col_origin = col-1; // Weight on a region 3x3 cv::Mat region(m,cv::Rect(col_origin,row_origin,3,3)); algebra::Vector2D v = internal::get_weighted_centroid(region); peak[0]=col_origin + v[0]; peak[1]=row_origin + v[1]; } return peak; } algebra::Vector2D get_weighted_centroid(const cv::Mat &m) { algebra::Vector2D center(0.,0.); double denominator=0.0; for (int i=1;i<=m.cols;++i) { for (int j=1;j<=m.rows;++j) { // double value = m.at(i-1,j-1); double value = m.at(i-1,j-1); denominator+= value; center[0] += value*i; center[1] += value*j; } } // Adjust center for the fact that the indices of m start at 0. center = center/denominator; // Following OpenCV convention the center is (col,row) center[0] -= 1; center[1] -= 1; return center; } IMPEM2D_END_INTERNAL_NAMESPACE