Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * dilation.cpp - implementation of morphological dilation filter 00004 * 00005 * Created: Thu May 25 15:47:01 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 <fvfilters/morphology/dilation.h> 00025 00026 #include <fvutils/color/yuv.h> 00027 #include <core/exception.h> 00028 00029 #include <cstddef> 00030 00031 #ifdef HAVE_IPP 00032 # include <ippi.h> 00033 #elif defined(HAVE_OPENCV) 00034 # include <cv.h> 00035 #else 00036 # error "Neither IPP nor OpenCV available" 00037 #endif 00038 00039 namespace firevision { 00040 #if 0 /* just to make Emacs auto-indent happy */ 00041 } 00042 #endif 00043 00044 /** @class FilterDilation <fvfilters/morphology/dilation.h> 00045 * Morphological dilation. 00046 * 00047 * @author Tim Niemueller 00048 */ 00049 00050 /** Constructor. */ 00051 FilterDilation::FilterDilation() 00052 : MorphologicalFilter("Morphological Dilation") 00053 { 00054 } 00055 00056 00057 /** Constructor with parameters. 00058 * @param se structuring element buffer. This is just a line-wise concatenated array 00059 * of values. A value of zero means ignore, any other value means to consider this 00060 * value. 00061 * @param se_width width of structuring element 00062 * @param se_height height of structuring element 00063 * @param se_anchor_x x coordinate of anchor in structuring element 00064 * @param se_anchor_y y coordinate of anchor in structuring element 00065 */ 00066 FilterDilation::FilterDilation(unsigned char *se, 00067 unsigned int se_width, unsigned int se_height, 00068 unsigned int se_anchor_x, unsigned int se_anchor_y) 00069 : MorphologicalFilter("Morphological Dilation") 00070 { 00071 this->se = se; 00072 this->se_width = se_width; 00073 this->se_height = se_height; 00074 this->se_anchor_x = se_anchor_x; 00075 this->se_anchor_y = se_anchor_y; 00076 } 00077 00078 00079 void 00080 FilterDilation::apply() 00081 { 00082 #if defined(HAVE_IPP) 00083 IppStatus status; 00084 00085 if ( se == NULL ) { 00086 // standard 3x3 dilation 00087 00088 IppiSize size; 00089 size.width = src_roi[0]->width - 2; 00090 size.height = src_roi[0]->height - 2; 00091 00092 00093 if ( (dst == NULL) || (dst == src[0]) ) { 00094 // In-place 00095 00096 // std::cout << "Running in-place with standard SE" << std::endl; 00097 00098 status = ippiDilate3x3_8u_C1IR(src[0] + ((src_roi[0]->start.y + 1) * src_roi[0]->line_step) + ((src_roi[0]->start.x + 1) * src_roi[0]->pixel_step), 00099 src_roi[0]->line_step, 00100 size); 00101 00102 } else { 00103 // std::cout << "Running not in-place dilation with standard SE" << std::endl; 00104 00105 status = ippiDilate3x3_8u_C1R(src[0] + ((src_roi[0]->start.y + 1) * src_roi[0]->line_step) + ((src_roi[0]->start.x + 1) * src_roi[0]->pixel_step), 00106 src_roi[0]->line_step, 00107 dst + ((dst_roi->start.y + 1) * dst_roi->line_step) + ((dst_roi->start.x + 1) * dst_roi->pixel_step), 00108 dst_roi->line_step, 00109 size); 00110 00111 yuv422planar_copy_uv(src[0], dst, 00112 src_roi[0]->image_width, src_roi[0]->image_height, 00113 src_roi[0]->start.x, src_roi[0]->start.y, 00114 src_roi[0]->width, src_roi[0]->height ); 00115 } 00116 } else { 00117 // we have a custom SE 00118 00119 IppiSize size; 00120 size.width = src_roi[0]->width - se_width; 00121 size.height = src_roi[0]->height - se_width; 00122 00123 IppiSize mask_size = { se_width, se_height }; 00124 IppiPoint mask_anchor = { se_anchor_x, se_anchor_y }; 00125 00126 /* 00127 std::cout << "Dilation filter is running with the following parameters:" << std::endl 00128 << " ROI size: " << size.width << " x " << size.height << std::endl 00129 << " mask size: " << mask_size.width << " x " << mask_size.height << std::endl 00130 << " mask anchor: (" << mask_anchor.x << "," << mask_anchor.y << ")" << std::endl 00131 << std::endl; 00132 00133 printf(" src buf: 0x%x\n", (unsigned int)src ); 00134 printf(" dst buf: 0x%x\n", (unsigned int)dst ); 00135 */ 00136 00137 if ( (dst == NULL) || (dst == src[0]) ) { 00138 // In-place 00139 00140 status = ippiDilate_8u_C1IR(src[0] + ((src_roi[0]->start.y + (se_height / 2)) * src_roi[0]->line_step) + ((src_roi[0]->start.x + (se_width / 2)) * src_roi[0]->pixel_step), 00141 src_roi[0]->line_step, 00142 size, 00143 se, mask_size, mask_anchor); 00144 00145 } else { 00146 //std::cout << "Running NOT in-place" << std::endl; 00147 00148 status = ippiDilate_8u_C1R(src[0] + ((src_roi[0]->start.y + (se_height / 2)) * src_roi[0]->line_step) + ((src_roi[0]->start.x + (se_width / 2)) * src_roi[0]->pixel_step), 00149 src_roi[0]->line_step, 00150 dst + ((dst_roi->start.y + (se_height / 2)) * dst_roi->line_step) + ((dst_roi->start.x + (se_width / 2)) * dst_roi->pixel_step), 00151 dst_roi->line_step, 00152 size, 00153 se, mask_size, mask_anchor); 00154 00155 yuv422planar_copy_uv(src[0], dst, 00156 src_roi[0]->image_width, src_roi[0]->image_height, 00157 src_roi[0]->start.x, src_roi[0]->start.y, 00158 src_roi[0]->width, src_roi[0]->height ); 00159 00160 } 00161 } 00162 00163 if ( status != ippStsNoErr ) { 00164 throw fawkes::Exception("Morphological dilation failed with %i\n", status); 00165 } 00166 #elif defined(HAVE_OPENCV) 00167 cv::Mat srcm(src_roi[0]->height, src_roi[0]->width, CV_8UC1, 00168 src[0] + 00169 (src_roi[0]->start.y * src_roi[0]->line_step) + 00170 (src_roi[0]->start.x * src_roi[0]->pixel_step), 00171 src_roi[0]->line_step); 00172 00173 if (dst == NULL) { dst = src[0]; dst_roi = src_roi[0]; } 00174 00175 cv::Mat dstm(dst_roi->height, dst_roi->width, CV_8UC1, 00176 dst + 00177 (dst_roi->start.y * dst_roi->line_step) + 00178 (dst_roi->start.x * dst_roi->pixel_step), 00179 dst_roi->line_step); 00180 00181 if (se == NULL) { 00182 cv::dilate(srcm, dstm, cv::Mat()); 00183 } else { 00184 cv::Mat sem(se_width, se_height, CV_8UC1); 00185 cv::Point sem_anchor(se_anchor_x, se_anchor_y); 00186 cv::dilate(srcm, dstm, sem, sem_anchor); 00187 } 00188 #endif 00189 00190 } 00191 00192 } // end namespace firevision