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