Fawkes API  Fawkes Development Version
median.cpp
00001 
00002 /***************************************************************************
00003  *  median.cpp - Implementation of a median filter
00004  *
00005  *  Created: Mon Jun 05 15:02:36 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/median.h>
00024 
00025 #include <core/exception.h>
00026 
00027 #ifdef HAVE_IPP
00028 #  include <ippi.h>
00029 #elif defined(HAVE_OPENCV)
00030 #  include <cv.h>
00031 #else
00032 #  error "Neither IPP nor OpenCV available"
00033 #endif
00034 
00035 namespace firevision {
00036 #if 0 /* just to make Emacs auto-indent happy */
00037 }
00038 #endif
00039 
00040 /** @class FilterMedian <fvfilters/median.h>
00041  * Median filter.
00042  * @author Tim Niemueller
00043  */
00044 
00045 /** Constructor.
00046  * @param mask_size size of median mask
00047  */
00048 FilterMedian::FilterMedian(unsigned int mask_size)
00049   : Filter("FilterMedian")
00050 {
00051   this->mask_size = mask_size;
00052 }
00053 
00054 
00055 void
00056 FilterMedian::apply()
00057 {
00058 #if defined(HAVE_IPP)
00059   IppiSize size;
00060   size.width = src_roi[0]->width - mask_size;
00061   size.height = src_roi[0]->height - mask_size;
00062 
00063   IppiSize mask = { mask_size, mask_size };
00064   IppiPoint anchor = { (mask_size + 1) / 2, (mask_size + 1) / 2 };
00065 
00066   IppStatus status;
00067 
00068   //                                  base + number of bytes to line y              + pixel bytes
00069   status = ippiFilterMedian_8u_C1R( src[0] + ((src_roi[0]->start.y + (mask_size + 1) / 2) * src_roi[0]->line_step) + ((src_roi[0]->start.x + ( mask_size + 1) / 2) * src_roi[0]->pixel_step), src_roi[0]->line_step,
00070                                     dst + ((dst_roi->start.y + (mask_size + 1) / 2) * dst_roi->line_step) + ((dst_roi->start.x + ( mask_size + 1) / 2) * dst_roi->pixel_step), dst_roi->line_step,
00071                                     size, mask, anchor );
00072 
00073   if ( status != ippStsNoErr ) {
00074     throw fawkes::Exception("Median filter failed with %i\n", status);
00075   }
00076 #elif defined(HAVE_OPENCV)
00077   cv::Mat srcm(src_roi[0]->height, src_roi[0]->width, CV_8UC1,
00078                src[0] +
00079                  (src_roi[0]->start.y * src_roi[0]->line_step) +
00080                  (src_roi[0]->start.x * src_roi[0]->pixel_step),
00081                src_roi[0]->line_step);
00082 
00083   if (dst == NULL) { dst = src[0]; dst_roi = src_roi[0]; }
00084 
00085   cv::Mat dstm(dst_roi->height, dst_roi->width, CV_8UC1,
00086                dst +
00087                  (dst_roi->start.y * dst_roi->line_step) +
00088                  (dst_roi->start.x * dst_roi->pixel_step),
00089                dst_roi->line_step);
00090 
00091   cv::medianBlur(srcm, dstm, mask_size);
00092 #endif
00093 }
00094 
00095 } // end namespace firevision