sobel.cpp

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

Generated on 1 Mar 2011 for Fawkes API by  doxygen 1.6.1