src/qvdta/qvdta.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. 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 <qvipp/qvipp.h>
00026 #include <qvdta/qvdta.h>
00027 
00028 namespace qvdta
00029 {
00030 QVector< QVector< QPoint > > CountingSort(const QVImage<uChar, 1> &image)
00031         {
00032         QVector< QVector <QPoint> > result(256);
00033 
00034         QMap<sInt, int> histogram = qvipp::HistogramRange(image);
00035         for (int k=0; k<256; k++)
00036                 result[k].reserve(histogram.value(k));
00037 
00038         QVIMAGE_INIT_READ(uChar,image);
00039         for(uInt row = 0; row < image.getRows(); row++)
00040                 for(uInt col = 0; col < image.getCols(); col++)
00041                         result[QVIMAGE_PIXEL(image, col, row,0)].append(QPoint(col, row));
00042         
00043         return result;
00044         }
00045 
00046 void HarrisCornerResponseImage(const QVImage<uChar> &image, QVImage<sFloat> &result)
00047         {
00048         uInt    rows = image.getRows(), cols = image.getCols();
00049         QVImage<uChar> buffer;
00050         qvipp::MinEigenValGetBufferSize(image, buffer);
00051         QVImage<sFloat> eigval(cols, rows);
00052 
00053         qvipp::MinEigenVal(image, eigval, buffer);
00054 
00055         result = eigval;
00056         }
00057 
00058 void SobelCornerResponseImage(const QVImage<uChar> &image, QVImage<sFloat> &result)
00059         {
00060         uInt    cols = image.getCols(), rows = image.getRows();
00061         QVImage<sFloat> imageSFloat = image;
00062 
00063         QVImage<sFloat> Gx(cols, rows), Gy(cols, rows), Gxx(cols, rows),
00064                         Gxy(cols, rows), Gyx(cols, rows), Gyy(cols, rows);
00065 
00066         qvipp::FilterSobelHorizMask(imageSFloat,Gx);
00067         qvipp::FilterSobelVertMask(imageSFloat,Gy);
00068 
00069         qvipp::FilterSobelHorizMask(Gx,Gxx);
00070         qvipp::FilterSobelVertMask(Gy,Gyy);
00071 
00072         qvipp::FilterSobelHorizMask(Gy,Gyx);
00073         qvipp::FilterSobelVertMask(Gx,Gxy);
00074 
00075         QVImage<sFloat> GxyGyx(cols, rows), GxxGyy(cols, rows);
00076 
00077         qvipp::Mul(Gxy, Gyx, GxyGyx);
00078         qvipp::Mul(Gxx, Gyy, GxxGyy);
00079 
00080         QVImage<sFloat> diffGxyGyx_GxxGyy(cols, rows);
00081 
00082         qvipp::Sub(GxyGyx, GxxGyy, diffGxyGyx_GxxGyy);
00083 
00084         for (uInt col = 0; col < cols; col++)
00085                 for(uInt row = 0; row < rows; row++)
00086                         if (diffGxyGyx_GxxGyy(col, row) <= 0)
00087                                 diffGxyGyx_GxxGyy(col, row) = 0;
00088 
00089         result = diffGxyGyx_GxxGyy;
00090         }
00091 
00092 
00093 void FilterLocalMax(const QVImage<sFloat> &src, QVImage<uChar> &dest, uInt colMaskSize, uInt rowMaskSize, sFloat threshold)
00094         {
00095         // TODO:
00096         //      - Fix resulting image ROI, obtain maximums restricted to the ROI.
00097         //      - Use IPP functions to obtain the result.
00098         uInt cols = src.getCols(), rows = src.getRows();
00099         qvipp::Set(dest,0);
00100         sFloat actual;
00101 
00102         QVIMAGE_INIT_READ(sFloat,src);
00103         QVIMAGE_INIT_WRITE(uChar,dest);
00104         for(uInt row = rowMaskSize; row < rows-rowMaskSize; row++)
00105                 for(uInt col = colMaskSize; col < cols-colMaskSize; col++)
00106                         {
00107                         actual = QVIMAGE_PIXEL(src, col, row,0);
00108                         if (actual < threshold)
00109                                 continue;
00110                         QVIMAGE_PIXEL(dest, col, row, 0) = IPP_MAX_8U;
00111                         for (uInt j = row-rowMaskSize; j < row+rowMaskSize; j++)
00112                                 for (uInt i = col-colMaskSize; i < col+colMaskSize; i++)
00113                                         if (    ((i != col) || (j != row)) &&
00114                                                 (actual <= QVIMAGE_PIXEL(src, i, j, 0)) )
00115                                                 {
00116                                                 QVIMAGE_PIXEL(dest, col, row, 0) = 0;
00117                                                 goto next;
00118                                                 }
00119                         next:
00120                         continue;
00121                         }
00122         }
00123 
00124 int myFloodFill(QVImage<uChar> &image, uInt x, uInt y, uInt value, uInt minVal, uInt maxVal)
00125         {
00126         // Value should be inside range [minVal, maxVal]
00127         Q_ASSERT( (value <= minVal) || (value >= maxVal) );
00128         Q_ASSERT( minVal <= maxVal );
00129 
00130         // Coordinates should be inside the image.
00131         if ( (x >= image.getCols()) || (y >= image.getRows()))
00132                 return 0;
00133 
00134         if ( (image(x,y) < minVal) || (image(x,y) > maxVal) )
00135                 return 0;
00136 
00137         image(x,y) = value;
00138 
00139         int val = 1;
00140         val += myFloodFill(image, x-1, y, value, minVal, maxVal);
00141         val += myFloodFill(image, x, y-1, value, minVal, maxVal);
00142         val += myFloodFill(image, x+1, y, value, minVal, maxVal);
00143         val += myFloodFill(image, x, y+1, value, minVal, maxVal);
00144 
00145         val += myFloodFill(image, x-1, y-1, value, minVal, maxVal);
00146         val += myFloodFill(image, x-1, y+1, value, minVal, maxVal);
00147         val += myFloodFill(image, x+1, y-1, value, minVal, maxVal);
00148         val += myFloodFill(image, x+1, y+1, value, minVal, maxVal);
00149 
00150         return val;
00151         }
00152 
00153 #define DEFINE_QVDTA_FUNCTION_EQUALIZE_HISTOGRAM(TYPE, C)                               \
00154 void equalizeHistogram(const QVImage<TYPE,C> &image, QVImage<TYPE,C> &equalized)        \
00155         {                                                                               \
00156         uInt    rows = image.getRows(), cols = image.getCols();                         \
00157         TYPE    maxVal, minVal;                                                         \
00158                                                                                         \
00159         qvipp::Max(image,maxVal);                                                       \
00160         qvipp::Min(image,minVal);                                                       \
00161                                                                                         \
00162         QVImage<TYPE,C> temp(cols, rows), result(cols, rows);                           \
00163         qvipp::SubC(image, temp, minVal);                                               \
00164         qvipp::MulC(temp, result, 255/(maxVal-minVal));                                 \
00165         equalized = result;                                                             \
00166         }
00167 
00168 DEFINE_QVDTA_FUNCTION_EQUALIZE_HISTOGRAM(uChar,1);
00169 DEFINE_QVDTA_FUNCTION_EQUALIZE_HISTOGRAM(sFloat,1);
00170 }

Generated on Thu Dec 13 13:06:26 2007 for QVision by  doxygen 1.5.3