PARP Research Group University of Murcia, Spain


src/qvcuda/qvcudaip.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008, 2009. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <iostream>
00026 
00027 #include "qvcudaip.h"
00028 
00029 #include "qvcudaipD.h"
00030 
00031 bool QVCUDASubtract(const QVCUDAImage<float,1> &src1, const QVCUDAImage<float,1> &src2, QVCUDAImage<float,1> &dest)
00032         {
00033         if ( (src1.getCols() != src2.getCols()) or (src1.getRows() != src2.getRows()) or (src1.getStep() != src2.getStep()) ) {
00034                 std::cerr << "QVCUDAIP module: QVCUDASubtract function: src1 and src2 image sizes do not coincide.\n";
00035                 return FALSE;
00036         }
00037 
00038         int w = src1.getCols();
00039         int h = src1.getRows();
00040         int step = src1.getStep(); // We know here that src2's step is the same (as forced by QVCUDAImage resize method).
00041 
00042         dest.resize(w,h);
00043 
00044         Subtract_kernel(src1.getData(),src2.getData(),dest.getData(),w,h,step);
00045 
00046         CUT_CHECK_ERROR("QVCUDAIP module: QVCUDASubtract function: execution failed\n");
00047         CUDA_SAFE_CALL(cudaThreadSynchronize());
00048 
00049         return TRUE;
00050 
00051         }
00052 
00053 bool QVCUDAScaleDown(const QVCUDAImage<float,1> &src, QVCUDAImage<float,1> &dest, float sigma)
00054 {
00055         if ( (src.getCols() < 2) or (src.getRows() < 2) or (src.getCols()%2 != 0) or (src.getRows()%2 != 0)) {
00056                 std::cerr << "QVCUDAIP module: QVCUDAScaleDown function: src image is not even sized.\n";
00057                 return FALSE;
00058         }
00059 
00060         int w = src.getCols();
00061         int h = src.getRows();
00062         int step_s = src.getStep();
00063 
00064         dest.resize(w/2,h/2);
00065         int step_d = dest.getStep();
00066 
00067 
00068         float h_Kernel[5];
00069         float kernelSum = 0.0f;
00070         for (int j=0;j<5;j++) {
00071                 h_Kernel[j] = (float)expf(-(double)(j-2)*(j-2)/2.0/sigma/sigma);
00072                 kernelSum += h_Kernel[j];
00073         }
00074         for (int j=0;j<5;j++)
00075                 h_Kernel[j] /= kernelSum;
00076 
00077         ScaleDown_kernel(src.getData(),dest.getData(),h_Kernel,w,h,step_s,step_d);
00078 
00079         CUT_CHECK_ERROR("QVCUDAIP module: QVCUDAScaleDown() execution failed\n");
00080         CUDA_SAFE_CALL(cudaThreadSynchronize());
00081 
00082         return TRUE;
00083 
00084 }
00085 
00086 
00087 bool QVCUDAFilterGauss(const QVCUDAImage<float,1> &src, QVCUDAImage<float,1> &dest, int kernelSize, float sigma)
00088 {
00089         int w = src.getCols();
00090         int h = src.getRows();
00091         int step = src.getStep();
00092 
00093         dest.resize(w,h);
00094 
00095         if ( (src.getCols() < 1) or (src.getRows() < 1) ) {
00096                 std::cerr << "QVCUDAIP module: QVCUDAFilterGauss function: src image is not OK.\n";
00097                 return FALSE;
00098         }
00099 
00100         int RADIUS = static_cast<int>(round(2.5*sigma));
00101         std::cout << "USING RADIUS=" << RADIUS << ".\n";
00102 
00103         if(2*RADIUS+1>CUDA_MAX_MASK_SIZE) {
00104                 std::cerr << "QVCUDAIP module: QVCUDAFilterGauss function: 2*RADIUS+1 exceeds CUDA_MAX_MASK_SIZE.\n";
00105                 return FALSE;
00106         }
00107 
00108         QVCUDAImage<float,1> tempimg(w,h);
00109         
00110         // We know here that dest and temp steps are the same (as forced by QVCUDAImage resize method).
00111 
00112         float h_Kernel[CUDA_MAX_MASK_SIZE];
00113         float kernelSum = 0.0f;
00114         for (int j=-RADIUS;j<=RADIUS;j++) {
00115                 h_Kernel[j+RADIUS] = (float)expf(-(double)j*j/2.0/sigma/sigma);
00116                 kernelSum += h_Kernel[j+RADIUS];
00117         }
00118         for (int j=-RADIUS;j<=RADIUS;j++)
00119                 h_Kernel[j+RADIUS] /= kernelSum;
00120 
00121         SeparableFilter_kernel(src.getData(),dest.getData(),tempimg.getData(),h_Kernel,RADIUS,w,h,step);
00122 
00123         CUT_CHECK_ERROR("QVCUDAIP module: QVCUDAFilterGauss() execution failed\n");
00124         CUDA_SAFE_CALL(cudaThreadSynchronize());
00125 
00126         return TRUE;
00127 
00128 }
00129 
00130 bool QVCUDATest(const QVCUDAImage<float,1> &src, QVCUDAImage<float,1> &dest, int radius, int iters)
00131 {
00132         int w = src.getCols();
00133         int h = src.getRows();
00134         int step = src.getStep();
00135 
00136         dest.resize(w,h);
00137 
00138         if ( (src.getCols() < 1) or (src.getRows() < 1) ) {
00139                 std::cerr << "QVCUDAIP module: QVCUDATest function: src image is not OK.\n";
00140                 return FALSE;
00141         }
00142 
00143         Test_kernel(src.getData(),dest.getData(),radius,iters,w,h,step);
00144 
00145         CUT_CHECK_ERROR("QVCUDAIP module: QVCUDATest() execution failed\n");
00146         CUDA_SAFE_CALL(cudaThreadSynchronize());
00147 
00148         return TRUE;
00149 
00150 
00151 }



QVision framework. PARP research group, copyright 2007, 2008.