Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * geodesic_erosion.cpp - implementation of morphological geodesic erosion 00004 * 00005 * Created: Sat Jun 10 16:21:30 2006 00006 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <core/exception.h> 00025 00026 #include <fvfilters/morphology/geodesic_erosion.h> 00027 #include <fvfilters/morphology/segenerator.h> 00028 #include <fvfilters/morphology/erosion.h> 00029 #include <fvfilters/max.h> 00030 00031 #include <fvutils/color/colorspaces.h> 00032 #include <fvutils/statistical/imagediff.h> 00033 00034 #include <cstdlib> 00035 #include <cstring> 00036 00037 namespace firevision { 00038 #if 0 /* just to make Emacs auto-indent happy */ 00039 } 00040 #endif 00041 00042 /** Marker */ 00043 const unsigned int FilterGeodesicErosion::MARKER = 0; 00044 /** Mask */ 00045 const unsigned int FilterGeodesicErosion::MASK = 1; 00046 00047 #define ERROR(m) { \ 00048 fawkes::Exception e("FilterGeodesicErosion failed"); \ 00049 e.append("Function: %s", __FUNCTION__); \ 00050 e.append("Message: %s", m); \ 00051 throw e; \ 00052 } 00053 00054 /** @class FilterGeodesicErosion <fvfilters/morphology/geodesic_erosion.h> 00055 * Morphological geodesic erosion. 00056 * @author Tim Niemueller 00057 */ 00058 00059 /** Constructor. 00060 * @param se_size Structuring element size. 00061 */ 00062 FilterGeodesicErosion::FilterGeodesicErosion(unsigned int se_size) 00063 : MorphologicalFilter("Morphological Geodesic Erosion") 00064 { 00065 this->se_size = (se_size > 0) ? se_size : 1; 00066 iterations = 0; 00067 00068 erode = new FilterErosion(); 00069 max = new FilterMax(); 00070 diff = new ImageDiff(); 00071 00072 isotropic_se = SEGenerator::square(this->se_size, this->se_size); 00073 00074 erode->set_structuring_element( isotropic_se, se_size, se_size, se_size / 2, se_size / 2 ); 00075 } 00076 00077 00078 /** Destructor. */ 00079 FilterGeodesicErosion::~FilterGeodesicErosion() 00080 { 00081 delete erode; 00082 delete max; 00083 delete diff; 00084 free( isotropic_se ); 00085 } 00086 00087 00088 void 00089 FilterGeodesicErosion::apply() 00090 { 00091 if ( dst == NULL ) ERROR("dst == NULL"); 00092 if ( src[MASK] == NULL ) ERROR("src[MASK] == NULL"); 00093 if ( src[MARKER] == NULL ) ERROR("src[MARKER] == NULL"); 00094 if ( *(src_roi[MASK]) != *(src_roi[MARKER]) ) ERROR("marker and mask ROI differ"); 00095 00096 unsigned char *tmp = (unsigned char *)malloc(colorspace_buffer_size(YUV422_PLANAR, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height) ); 00097 memcpy( tmp, src[MARKER], colorspace_buffer_size(YUV422_PLANAR, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height) ); 00098 00099 diff->setBufferA( tmp, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height ); 00100 diff->setBufferB( dst, dst_roi->image_width, dst_roi->image_height ); 00101 00102 erode->set_src_buffer( tmp, src_roi[MARKER] ); 00103 00104 max->set_src_buffer( src[MASK], src_roi[MASK], 0 ); 00105 max->set_src_buffer( tmp, src_roi[MARKER], 1 ); 00106 max->set_dst_buffer( tmp, src_roi[MARKER] ); 00107 00108 00109 iterations = 0; 00110 do { 00111 memcpy(dst, tmp, colorspace_buffer_size(YUV422_PLANAR, dst_roi->image_width, dst_roi->image_height) ); 00112 erode->apply(); 00113 max->apply(); 00114 } while (diff->different() && ( ++iterations < 255) ); 00115 00116 // std::cout << i << " iterations done for geodesic erosion" << std::endl; 00117 00118 00119 free( tmp ); 00120 00121 } 00122 00123 00124 /** Get the number of iterations. 00125 * @return the number of iterations that were necessary to get a stable result in the 00126 * last call to apply(). 00127 */ 00128 unsigned int 00129 FilterGeodesicErosion::num_iterations() 00130 { 00131 return iterations; 00132 } 00133 00134 } // end namespace firevision