Fawkes API  Fawkes Development Version
threshold.cpp
00001 
00002 /***************************************************************************
00003  *  threshold.cpp - Implementation for threshold filter, this filter will
00004  *                  luminance values below a given threshold to the given
00005  *                  min_replace value, values above a given max threshold
00006  *                  will be set to the max_replace value
00007  *
00008  *  Created: Tue Jun 07 14:30:10 2005
00009  *  Copyright  2005-2012  Tim Niemueller [www.niemueller.de]
00010  ****************************************************************************/
00011 
00012 /*  This program is free software; you can redistribute it and/or modify
00013  *  it under the terms of the GNU General Public License as published by
00014  *  the Free Software Foundation; either version 2 of the License, or
00015  *  (at your option) any later version. A runtime exception applies to
00016  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00017  *
00018  *  This program is distributed in the hope that it will be useful,
00019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  *  GNU Library General Public License for more details.
00022  *
00023  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00024  */
00025 
00026 #include <fvfilters/threshold.h>
00027 
00028 #include <core/exception.h>
00029 
00030 #include <cstddef>
00031 
00032 #ifdef HAVE_IPP
00033 #  include <ippi.h>
00034 #elif defined(HAVE_OPENCV)
00035 #  include <cv.h>
00036 #else
00037 #  error "Neither IPP nor OpenCV available"
00038 #endif
00039 
00040 namespace firevision {
00041 #if 0 /* just to make Emacs auto-indent happy */
00042 }
00043 #endif
00044 
00045 /** @class FilterThreshold <fvfilters/threshold.h>
00046  * Threshold filter.
00047  * Implementation for threshold filter, this filter will luminance
00048  * values below a given threshold to the given min_replace value,
00049  * values above a given max threshold will be set to the max_replace
00050  * value
00051  */
00052 
00053 /** Constructor.
00054  * @param min minimum value
00055  * @param min_replace values below min are replaced with this value
00056  * @param max maximum value
00057  * @param max_replace values above max are replaced with this value
00058  */
00059 FilterThreshold::FilterThreshold(unsigned char min, unsigned char min_replace,
00060                                  unsigned char max, unsigned char max_replace)
00061   : Filter("FilterThreshold")
00062 {
00063   this->min = min;
00064   this->max = max;
00065   this->min_replace = min_replace;
00066   this->max_replace = max_replace;
00067 #if defined(HAVE_OPENCV)
00068   if (min_replace != 0) {
00069     throw fawkes::Exception("OpenCV-based threshold filter only allows min_replace=0");
00070   }
00071 #endif
00072 
00073 }
00074 
00075 
00076 /** Set new thresholds.
00077  * @param min minimum value
00078  * @param min_replace values below min are replaced with this value
00079  * @param max maximum value
00080  * @param max_replace values above max are replaced with this value
00081  */
00082 void
00083 FilterThreshold::set_thresholds(unsigned char min, unsigned char min_replace,
00084                                 unsigned char max, unsigned char max_replace)
00085 {
00086   this->min = min;
00087   this->max = max;
00088   this->min_replace = min_replace;
00089   this->max_replace = max_replace;
00090 }
00091 
00092 
00093 void
00094 FilterThreshold::apply()
00095 {
00096 #if defined(HAVE_IPP)
00097   IppiSize size;
00098   size.width = src_roi[0]->width;
00099   size.height = src_roi[0]->height;
00100 
00101   IppStatus status;
00102 
00103   if ((dst == NULL) || (dst == src[0])) {
00104     // In-place
00105     status = ippiThreshold_GTVal_8u_C1IR( src[0] + (src_roi[0]->start.y * src_roi[0]->line_step) + (src_roi[0]->start.x * src_roi[0]->pixel_step), src_roi[0]->line_step,
00106                                           size, max, max_replace );
00107     if ( status == ippStsNoErr ) {
00108       status = ippiThreshold_LTVal_8u_C1IR( src[0] + (src_roi[0]->start.y * src_roi[0]->line_step) + (src_roi[0]->start.x * src_roi[0]->pixel_step), src_roi[0]->line_step,
00109                                             size, min, min_replace );
00110     }
00111   } else {
00112     //                                base + number of bytes to line y              + pixel bytes
00113     status = ippiThreshold_GTVal_8u_C1R( src[0] + (src_roi[0]->start.y * src_roi[0]->line_step) + (src_roi[0]->start.x * src_roi[0]->pixel_step), src_roi[0]->line_step,
00114                                          dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step), dst_roi->line_step,
00115                                          size, max, max_replace );
00116 
00117     if ( status == ippStsNoErr ) {
00118       status = ippiThreshold_LTVal_8u_C1R( src[0] + (src_roi[0]->start.y * src_roi[0]->line_step) + (src_roi[0]->start.x * src_roi[0]->pixel_step), src_roi[0]->line_step,
00119                                            dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step), dst_roi->line_step,
00120                                            size, min, min_replace );
00121     }
00122   }
00123 
00124   if ( status != ippStsNoErr ) {
00125     throw fawkes::Exception("Threshold filter failed with %i\n", status);
00126   }
00127 
00128 #elif defined(HAVE_OPENCV)
00129   if ((dst == NULL) || (dst == src[0])) {
00130     throw fawkes::Exception("OpenCV-based threshold filter cannot be in-place");
00131   }
00132 
00133   cv::Mat srcm(src_roi[0]->height, src_roi[0]->width, CV_8UC1,
00134                src[0] +
00135                  (src_roi[0]->start.y * src_roi[0]->line_step) +
00136                  (src_roi[0]->start.x * src_roi[0]->pixel_step),
00137                src_roi[0]->line_step);
00138 
00139   cv::Mat dstm(dst_roi->height, dst_roi->width, CV_8UC1,
00140                dst +
00141                  (dst_roi->start.y * dst_roi->line_step) +
00142                  (dst_roi->start.x * dst_roi->pixel_step),
00143                dst_roi->line_step);
00144 
00145   cv::threshold(srcm, dstm, max, max_replace, cv::THRESH_BINARY);
00146   cv::threshold(srcm, dstm, min, 0, cv::THRESH_TOZERO);
00147 
00148 #endif
00149 
00150 }
00151 
00152 } // end namespace firevision