Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * erosion.cpp - implementation of morphological erosion filter 00004 * 00005 * Created: Fri May 26 12:13:22 2006 00006 * Copyright 2005-2012 Tim Niemueller [www.niemueller.de] 00007 ****************************************************************************/ 00008 00009 /* This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. A runtime exception applies to 00013 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU Library General Public License for more details. 00019 * 00020 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00021 */ 00022 00023 #include <fvfilters/morphology/erosion.h> 00024 00025 #include <fvutils/color/yuv.h> 00026 #include <core/exception.h> 00027 00028 #include <cstddef> 00029 00030 #ifdef HAVE_IPP 00031 # include <ippi.h> 00032 #elif defined(HAVE_OPENCV) 00033 # include <cv.h> 00034 #else 00035 # error "Neither IPP nor OpenCV available" 00036 #endif 00037 00038 namespace firevision { 00039 #if 0 /* just to make Emacs auto-indent happy */ 00040 } 00041 #endif 00042 00043 /** @class FilterErosion <fvfilters/morphology/erosion.h> 00044 * Morphological erosion. 00045 * 00046 * @author Tim Niemueller 00047 */ 00048 00049 /** Constructor. */ 00050 FilterErosion::FilterErosion() 00051 : MorphologicalFilter("Morphological Erosion") 00052 { 00053 } 00054 00055 00056 void 00057 FilterErosion::apply() 00058 { 00059 #if defined(HAVE_IPP) 00060 IppStatus status; 00061 00062 if ( se == NULL ) { 00063 // standard 3x3 erosion 00064 00065 IppiSize size; 00066 size.width = src_roi[0]->width - 2; 00067 size.height = src_roi[0]->height - 2; 00068 00069 00070 if ( (dst == NULL) || (dst == src[0]) ) { 00071 // In-place 00072 status = ippiErode3x3_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), 00073 src_roi[0]->line_step, 00074 size); 00075 00076 } else { 00077 status = ippiErode3x3_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), 00078 src_roi[0]->line_step, 00079 dst + ((dst_roi->start.y + 1) * dst_roi->line_step) + ((dst_roi->start.x + 1) * dst_roi->pixel_step), 00080 dst_roi->line_step, 00081 size); 00082 00083 yuv422planar_copy_uv(src[0], dst, 00084 src_roi[0]->image_width, src_roi[0]->image_height, 00085 src_roi[0]->start.x, src_roi[0]->start.y, 00086 src_roi[0]->width, src_roi[0]->height ); 00087 } 00088 } else { 00089 // we have a custom SE 00090 00091 IppiSize size; 00092 size.width = src_roi[0]->width - se_width; 00093 size.height = src_roi[0]->height - se_height; 00094 00095 IppiSize mask_size = { se_width, se_height }; 00096 IppiPoint mask_anchor = { se_anchor_x, se_anchor_y }; 00097 00098 if ( (dst == NULL) || (dst == src[0]) ) { 00099 // In-place 00100 status = ippiErode_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), 00101 src_roi[0]->line_step, 00102 size, 00103 se, mask_size, mask_anchor); 00104 00105 //std::cout << "in-place operation ended with status " << status << std::endl; 00106 00107 } else { 00108 status = ippiErode_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), 00109 src_roi[0]->line_step, 00110 dst + ((dst_roi->start.y + (se_height / 2)) * dst_roi->line_step) + ((dst_roi->start.x + (se_width / 2)) * dst_roi->pixel_step), 00111 dst_roi->line_step, 00112 size, 00113 se, mask_size, mask_anchor); 00114 00115 // std::cout << "NOT in-place operation ended with status " << status << std::endl; 00116 00117 yuv422planar_copy_uv(src[0], dst, 00118 src_roi[0]->image_width, src_roi[0]->image_height, 00119 src_roi[0]->start.x, src_roi[0]->start.y, 00120 src_roi[0]->width, src_roi[0]->height ); 00121 } 00122 00123 } 00124 00125 if ( status != ippStsNoErr ) { 00126 throw fawkes::Exception("Morphological erosion failed with %i\n", status); 00127 } 00128 #elif defined(HAVE_OPENCV) 00129 cv::Mat srcm(src_roi[0]->height, src_roi[0]->width, CV_8UC1, 00130 src[0] + 00131 (src_roi[0]->start.y * src_roi[0]->line_step) + 00132 (src_roi[0]->start.x * src_roi[0]->pixel_step), 00133 src_roi[0]->line_step); 00134 00135 if (dst == NULL) { dst = src[0]; dst_roi = src_roi[0]; } 00136 00137 cv::Mat dstm(dst_roi->height, dst_roi->width, CV_8UC1, 00138 dst + 00139 (dst_roi->start.y * dst_roi->line_step) + 00140 (dst_roi->start.x * dst_roi->pixel_step), 00141 dst_roi->line_step); 00142 00143 if (se == NULL) { 00144 cv::erode(srcm, dstm, cv::Mat()); 00145 } else { 00146 cv::Mat sem(se_width, se_height, CV_8UC1); 00147 cv::Point sem_anchor(se_anchor_x, se_anchor_y); 00148 cv::erode(srcm, dstm, sem, sem_anchor); 00149 } 00150 #endif 00151 } 00152 00153 } // end namespace firevision