Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * sobel.cpp - Implementation of a Sobel filter 00004 * 00005 * Created: Thu May 12 13:20:43 2005 00006 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <filters/sobel.h> 00025 00026 #include <core/exception.h> 00027 00028 #include <ippi.h> 00029 00030 00031 namespace firevision { 00032 #if 0 /* just to make Emacs auto-indent happy */ 00033 } 00034 #endif 00035 00036 /** @class FilterSobel <filters/sobel.h> 00037 * Sobel filter. 00038 * @author Tim Niemueller 00039 */ 00040 00041 /** Constructor. 00042 * @param ori edge orientation 00043 */ 00044 FilterSobel::FilterSobel(orientation_t ori) 00045 : Filter("FilterSobel") 00046 { 00047 } 00048 00049 00050 /** Generate a sobel kernel for the given orientation. 00051 * @param k matrix for the kernel of size 3x3, contains three 00052 * lines concatenated into an one dimensional array. 00053 * @param ori requested orientation of the filter 00054 */ 00055 void 00056 FilterSobel::generate_kernel(int *k, orientation_t ori) 00057 { 00058 // k is the kernel 00059 switch (ori) { 00060 case ORI_DEG_0: 00061 case ORI_DEG_360: 00062 k[0] = 1; k[1] = 2; k[2] = 1; 00063 k[3] = 0; k[4] = 0; k[5] = 0; 00064 k[6] = -1; k[7] = -2; k[8] = -1; 00065 break; 00066 case ORI_DEG_45: 00067 k[0] = 2; k[1] = 1; k[2] = 0; 00068 k[3] = 1; k[4] = 0; k[5] = -1; 00069 k[6] = 0; k[7] = -1; k[8] = -2; 00070 break; 00071 case ORI_DEG_90: 00072 k[0] = 1; k[1] = 0; k[2] = -1; 00073 k[3] = 2; k[4] = 0; k[5] = -2; 00074 k[6] = 1; k[7] = 0; k[8] = -1; 00075 break; 00076 case ORI_DEG_135: 00077 k[0] = 0; k[1] = -1; k[2] = -2; 00078 k[3] = 1; k[4] = 0; k[5] = -1; 00079 k[6] = 2; k[7] = 1; k[8] = 0; 00080 break; 00081 case ORI_DEG_180: 00082 k[0] = -1; k[1] = -2; k[2] = -1; 00083 k[3] = 0; k[4] = 0; k[5] = 0; 00084 k[6] = 1; k[7] = 2; k[8] = 1; 00085 break; 00086 case ORI_DEG_225: 00087 k[0] = -2; k[1] = -1; k[2] = 0; 00088 k[3] = -1; k[4] = 0; k[5] = 1; 00089 k[6] = 0; k[7] = 1; k[8] = 2; 00090 break; 00091 case ORI_DEG_270: 00092 k[0] = -1; k[1] = 0; k[2] = 1; 00093 k[3] = -2; k[4] = 0; k[5] = 2; 00094 k[6] = -1; k[7] = 0; k[8] = 1; 00095 break; 00096 case ORI_DEG_315: 00097 k[0] = 0; k[1] = 1; k[2] = 2; 00098 k[3] = -1; k[4] = 0; k[5] = 1; 00099 k[6] = -2; k[7] = -1; k[8] = 0; 00100 break; 00101 default: 00102 // cout << "FilterSobel: Cannote generate kernel for the given orientation." << endl; 00103 break; 00104 } 00105 } 00106 00107 00108 void 00109 FilterSobel::apply() 00110 { 00111 shrink_region(src_roi[0], 3); 00112 shrink_region(dst_roi, 3); 00113 00114 IppiSize size; 00115 size.width = src_roi[0]->width; 00116 size.height = src_roi[0]->height; 00117 00118 IppStatus status; 00119 00120 if (ori[0] == ORI_HORIZONTAL) { 00121 // base + number of bytes to line y + pixel bytes 00122 status = ippiFilterSobelHoriz_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, 00123 dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step), dst_roi->line_step, 00124 size ); 00125 } else if (ori[0] == ORI_VERTICAL) { 00126 status = ippiFilterSobelHoriz_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, 00127 dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step), dst_roi->line_step, 00128 size ); 00129 00130 } else if ( (ori[0] == ORI_DEG_0) || 00131 (ori[0] == ORI_DEG_45) || 00132 (ori[0] == ORI_DEG_90) || 00133 (ori[0] == ORI_DEG_135) || 00134 (ori[0] == ORI_DEG_180) || 00135 (ori[0] == ORI_DEG_225) || 00136 (ori[0] == ORI_DEG_270) || 00137 (ori[0] == ORI_DEG_315) || 00138 (ori[0] == ORI_DEG_360) 00139 ) { 00140 00141 Ipp32s kernel[9]; 00142 generate_kernel(kernel, ori[0]); 00143 00144 IppiSize kernel_size; 00145 kernel_size.width = kernel_size.height = 3; 00146 00147 IppiPoint anchor; 00148 anchor.x = anchor.y = 1; 00149 00150 status = ippiFilter_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, 00151 dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step), dst_roi->line_step, 00152 size, 00153 kernel, kernel_size, 00154 anchor, 00155 /* divisor */ 1 ); 00156 00157 } else { 00158 // cout << "FilterSobel: Unsupported direction" << endl; 00159 status = ippStsNullPtrErr; 00160 } 00161 00162 if ( status != ippStsNoErr ) { 00163 throw fawkes::Exception("Sobel filter failed with %i\n", status); 00164 } 00165 00166 } 00167 00168 } // end namespace firevision