Fawkes API  Fawkes Development Version
erosion.cpp
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