EdgeConnectorGraphBased.cpp
Go to the documentation of this file.
00001 #include <face_contour_detector/filters/EdgeConnectorGraphBased.h>
00002 #include <string>
00003 #include <face_contour_detector/ImageForest.h>
00004 #include <map>
00005 #include <vector>
00006 #include <opencv/cv.h>
00007 #include <ros/assert.h>
00008 
00009 namespace face_contour_detector {
00010 
00011         namespace filters {
00012 
00013                 EdgeConnectorGraphBased::EdgeConnectorGraphBased() {
00014                         ResetParameters();
00015                 }
00016 
00017                 std::vector<Parameter> EdgeConnectorGraphBased::GetParameters() {
00018                         std::vector<Parameter> re;
00019                         std::string name("searchRadius");
00020                         re.push_back(Parameter(name, &m_searchRadius, 2, 50));
00021                         return re;
00022                 }
00023 
00024                 void EdgeConnectorGraphBased::Apply(const cv::Mat& input, cv::Mat& result) {
00025                         ROS_ASSERT(input.channels() == 1);
00026 
00027                         ImageForest forest(input, 200);
00028                         std::map<int, ImageForest::Graph> graphs = forest.GetGraphs();
00029 
00030                         result = input;
00031 
00032                         for (int i = 1; i <= forest.NumGraphs(); i++) {
00033                                 std::vector<ImageForest::Point>::iterator itPoints;
00034                                 for (itPoints = graphs[i].endPoints.begin(); itPoints != graphs[i].endPoints.end(); itPoints++) {
00035                                         ImageForest::Point found(-1,-1);
00036                                         for (int dy = -m_searchRadius; dy <= m_searchRadius; dy++) {
00037                                                 for (int dx = -m_searchRadius; dx <= m_searchRadius; dx++) {
00038                                                         int x = dx + itPoints->x;
00039                                                         int y = dy + itPoints->y;
00040                                                         if (x >= 0 && x < input.cols && y >= 0 && y < input.rows) {
00041                                                                 int otherId = forest.GetGraphId(x,y);
00042                                                                 if (otherId > i) {
00043                                                                         if (found.x == -1 ||
00044                                                                                 itPoints->Distance(ImageForest::Point(x,y)) < itPoints->Distance(found)) {
00045 
00046                                                                                 found = ImageForest::Point(x,y);
00047                                                                         }
00048                                                                 }
00049                                                         }
00050                                                 }
00051                                         }
00052                                         if (found.x != -1) {
00053                                                 M_Connect(result, itPoints->x, itPoints->y, found.x, found.y);
00054                                         }
00055                                 }
00056                         }
00057                 }
00058 
00059                 void EdgeConnectorGraphBased::ResetParameters() {
00060                         m_searchRadius = 4;
00061                         m_connectValue = 255;
00062                 }
00063 
00064                 const std::string& EdgeConnectorGraphBased::GetFilterName() {
00065                         return m_filterName;
00066                 }
00067 
00068                 void EdgeConnectorGraphBased::M_Connect(cv::Mat& image, int x1, int y1, int x2, int y2) {
00069                                 ROS_ASSERT(x1 < image.cols && x1 >= 0);
00070                                 ROS_ASSERT(x2 < image.cols && x2 >= 0);
00071                                 ROS_ASSERT(y1 < image.rows && y1 >= 0);
00072                                 ROS_ASSERT(y2 < image.rows && y2 >= 0);
00073                                 //std::cout<<"connect ("<<x1<<", "<<y1<<") to ("<<x2<<", "<<y2<<")"<<std::endl;
00074                                 //image.at<unsigned char>(y1,x1) = 170;
00075                                 //image.at<unsigned char>(y2,x2) = 170;
00076                                 double dx = x2-x1; //=c
00077                                 double dy = y2-y1; //=a
00078                                 //std::cout<<"dx="<<dx<<" dy="<<dy<<std::endl;
00079                                 //special cases
00080                                 //only y direction
00081                                 if (dx == 0) {
00082                                         if (dy > 0) {
00083                                                 for (int i = 1; i < dy; i++) {
00084                                                         image.at<unsigned char>(y1+i, x1) = m_connectValue;
00085                                                 }
00086                                         } else if (dy < 0) {
00087                                                 for (int i = -1; i > dy; i--) {
00088                                                         image.at<unsigned char>(y1+i, x1) = m_connectValue;
00089                                                 }
00090                                         }
00091                                         return;
00092                                 }
00093                                 //only x direction
00094                                 if (dy == 0) {
00095                                         if (dx > 0) {
00096                                                 for (int i = 1; i < dx; i++) {
00097                                                         image.at<unsigned char>(y1, x1+i) = m_connectValue;
00098                                                 }
00099                                         } else if (dx < 0) {
00100                                                 for (int i = -1; i > dx; i--) {
00101                                                         image.at<unsigned char>(y1, x1+i) = m_connectValue;
00102                                                 }
00103                                         }
00104                                         return;
00105                                 }
00106                                 //same stepsize in x and y direction
00107                                 if (dx == dy) {
00108                                         if (dx > 0) {
00109                                                 for (int i = 1; i < dx; i++) {
00110                                                         image.at<unsigned char>(y1+1, x1+i) = m_connectValue;
00111                                                 }
00112                                         } else if (dx < 0) {
00113                                                 for (int i = -1; i > dx; i--) {
00114                                                         image.at<unsigned char>(y1+1, x1+1) = m_connectValue;
00115                                                 }
00116                                         }
00117                                         return;
00118                                 }
00119                                 //non special cases
00120                                 //                C
00121                                 //              / |
00122                                 //    A - B
00123                                 double b = sqrt(dx*dx + dy*dy);
00124                                 double alpha = acos((b*b + dx*dx - dy*dy)/(2.0*std::abs(b)*std::abs(dx)));
00125                                 double sinAlpha = sin(alpha);
00126                                 double sinGamma = sin(M_PI/2.0 - alpha);
00127                                 //x-direction
00128                                 if (dx > 0.0) {
00129                                         for (double currX = double(x1)+0.5; currX < x2; currX += 1.0) {
00130                                                 double currY = (currX-double(x1))*sinAlpha/sinGamma;
00131                                                 if (dy < 0) {
00132                                                         currY *= -1;
00133                                                 }
00134                                                 currY += y1;
00135                                                 ROS_ASSERT(currY >= 0 && currY < image.rows);
00136                                                 image.at<unsigned char>(int(round(currY)), int(ceil(currX))) = m_connectValue;
00137                                         }
00138                                 } else if (dx < 0.0) {
00139                                         for (double currX = double(x1)-0.5; currX > x2; currX -= 1.0) {
00140                                                 double currY = (double(x1)-currX)*sinAlpha/sinGamma;
00141                                                 if (dy < 0) {
00142                                                         currY *= -1.0;
00143                                                 }
00144                                                 currY += y1;
00145                                                 ROS_ASSERT(currY >= 0 && currY < image.rows);
00146                                                 image.at<unsigned char>(int(round(currY)), int(floor(currX))) = m_connectValue;
00147                                         }
00148                                 }
00149                                 //y-direction
00150                                 if (dy > 0.0) {
00151                                         for (double currY = double(y1)+0.5; currY < y2; currY += 1.0) {
00152                                                 double currX = (currY-double(y1))*sinGamma/sinAlpha;
00153                                                 if (dx < 0) {
00154                                                         currX *= -1.0;
00155                                                 }
00156                                                 currX += x1;
00157                                                 ROS_ASSERT(currX >= 0 && currX < image.cols);
00158                                                 image.at<unsigned char>(int(ceil(currY)), int(round(currX))) = m_connectValue;
00159                                         }
00160                                 } else if (dy < 0.0) {
00161                                         for (double currY = double(y1)-0.5; currY > y2; currY -= 1.0) {
00162                                                 double currX = (double(y1)-currY)*sinGamma/sinAlpha;
00163                                                 if (dx < 0) {
00164                                                         currX *= -1.0;
00165                                                 }
00166                                                 currX += x1;
00167                                                 ROS_ASSERT(currX >= 0 && currX < image.cols);
00168                                                 image.at<unsigned char>(int(floor(currY)), int(round(currX))) = m_connectValue;
00169                                         }
00170                                 }
00171                         }
00172 
00173                 //static
00174                 std::string EdgeConnectorGraphBased::m_filterName = std::string("EdgeConnectorGraphBased");
00175         } //namespace filters
00176 
00177 } //namespace face_contour_detector
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends


face_contour_detector
Author(s): Fabian Wenzelmann and Julian Schmid
autogenerated on Wed Dec 26 2012 16:18:17