src/qvdta/qvdta.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. 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 <stdio.h>
00026 #include <stdlib.h>
00027 #include <iostream>
00028 
00029 #include <qvipp.h>
00030 #include <qvdta.h>
00031 
00032 QVector< QVector< QPoint > > CountingSort(const QVImage<uChar, 1> &image)
00033         {
00034         QVector< QVector <QPoint> > result(256);
00035         const QVector<int> histogram = HistogramRange(image);
00036 
00037         for (int k=0; k<256; k++)
00038                 result[k].reserve(histogram[k]);
00039 
00040         QVIMAGE_INIT_READ(uChar,image);
00041         for(uInt row = 0; row < image.getRows(); row++)
00042                 for(uInt col = 0; col < image.getCols(); col++)
00043                         result[QVIMAGE_PIXEL(image, col, row,0)].append(QPoint(col, row));
00044         
00045         return result;
00046         }
00047 
00048 
00049 #include <qvmath/qvdisjointset.h>
00050 #include <qvmath/qvvector.h>
00051 
00052 QList<QPointF> GetMaximalResponsePoints1(const QVImage<sFloat> &cornerResponseImage, const double threshold)
00053         {
00054         const int sizeMax = 2;
00055         const int cols = cornerResponseImage.getCols(), rows = cornerResponseImage.getRows();
00056         QVImage<uChar> binaryResponseImage(cols, rows);
00057         QVIMAGE_INIT_READ(sFloat,cornerResponseImage);
00058         QVIMAGE_INIT_WRITE(uChar,binaryResponseImage);
00059 
00060         // 1. Get image with local maximums
00061         Set(0, binaryResponseImage);
00062 
00063         // Recorremos la imagen
00064         for(int row = sizeMax; row < rows-sizeMax; row++)
00065                 for(int col = sizeMax; col < cols-sizeMax; col++)
00066                         {
00067                         sFloat actual = QVIMAGE_PIXEL(cornerResponseImage, col, row,0);
00068                         if (actual >= threshold)
00069                                 {
00070                                 QVIMAGE_PIXEL(binaryResponseImage, col, row, 0) = IPP_MAX_8U;
00071                                 for (int j = row-sizeMax; (j < row+sizeMax) && (QVIMAGE_PIXEL(binaryResponseImage, col, row, 0) > 0); j++)
00072                                         for (int i = col-sizeMax; i < col+sizeMax; i++)
00073                                                 if ( ((i != col) || (j != row)) && (actual <= QVIMAGE_PIXEL(cornerResponseImage, i, j, 0)) )
00074                                                         {
00075                                                         QVIMAGE_PIXEL(binaryResponseImage, col, row, 0) = 0;
00076                                                         break;
00077                                                         }
00078                                 }
00079                         }
00080 
00081         // 2. Get sorted list of points
00082         QMap<sFloat, QPointF> sortedPoints;
00083         for(uInt row = 0; row < binaryResponseImage.getRows(); row++)
00084                 for(uInt col = 0; col < binaryResponseImage.getCols(); col++)
00085                         if (QVIMAGE_PIXEL(binaryResponseImage, col, row,0))
00086                                 sortedPoints.insertMulti(QVIMAGE_PIXEL(cornerResponseImage, col, row,0), QPointF(col+2, row+2));
00087 
00088         QList<QPointF> result;
00089         foreach(sFloat key, sortedPoints.uniqueKeys())
00090                 result += sortedPoints.values(key);
00091 
00092         return result;
00093         }
00094 
00095 QList< QPair<sFloat, QPointF> > GetMaximalResponsePoints1bis(const QVImage<sFloat> &cornerResponseImage, const double threshold)
00096         {
00097         const int sizeMax = 2;
00098         const int cols = cornerResponseImage.getCols(), rows = cornerResponseImage.getRows();
00099         QVImage<uChar> binaryResponseImage(cols, rows);
00100         QVIMAGE_INIT_READ(sFloat,cornerResponseImage);
00101         QVIMAGE_INIT_WRITE(uChar,binaryResponseImage);
00102 
00103         // 1. Get image with local maximums
00104         Set(0, binaryResponseImage);
00105         sFloat actual;
00106         for(int row = sizeMax; row < rows-sizeMax; row++)
00107                 for(int col = sizeMax; col < cols-sizeMax; col++)
00108                         {
00109                         actual = QVIMAGE_PIXEL(cornerResponseImage, col, row,0);
00110                         if (actual >= threshold)
00111                                 {
00112                                 QVIMAGE_PIXEL(binaryResponseImage, col, row, 0) = IPP_MAX_8U;
00113                                 for (int j = row-sizeMax; (j < row+sizeMax) && (QVIMAGE_PIXEL(binaryResponseImage, col, row, 0) > 0); j++)
00114                                         for (int i = col-sizeMax; i < col+sizeMax; i++)
00115                                                 if ( ((i != col) || (j != row)) && (actual <= QVIMAGE_PIXEL(cornerResponseImage, i, j, 0)) )
00116                                                         {
00117                                                         QVIMAGE_PIXEL(binaryResponseImage, col, row, 0) = 0;
00118                                                         break;
00119                                                         }
00120                                 }
00121                         }
00122 
00123         // 2. Get sorted list of points
00124         QMap<sFloat, QPointF> sortedPoints;
00125         for(uInt row = 0; row < binaryResponseImage.getRows(); row++)
00126                 for(uInt col = 0; col < binaryResponseImage.getCols(); col++)
00127                         if (QVIMAGE_PIXEL(binaryResponseImage, col, row,0))
00128                                 sortedPoints.insertMulti(QVIMAGE_PIXEL(cornerResponseImage, col, row,0), QPointF(col+2, row+2));
00129 
00130         QList< QPair<sFloat, QPointF> > result;
00131         foreach(const sFloat key, sortedPoints.uniqueKeys())
00132                 foreach (const QPointF point, sortedPoints.values(key))
00133                         result.append(QPair<sFloat, QPointF>(key,point));
00134 
00135         return result;
00136         }
00137 QList<QPointF> GetMaximalResponsePoints3(const QVImage<sFloat> &cornerResponseImage, const double threshold)
00138         {
00139         static const int        xD[4] = { -1, +0, +1, +0 },
00140                                 yD[4] = { +0, -1, +0, +1 };
00141 
00142         const int rows = cornerResponseImage.getRows(), cols = cornerResponseImage.getCols();
00143         QVDisjointSet disjointSet(cornerResponseImage);
00144         QVIMAGE_INIT_READ(sFloat,cornerResponseImage);
00145 
00146         // 1. Join in the disjoint set all the neighbour pixels
00147         for(int row = 1; row < rows-1; row++)
00148                 for(int col = 1; col < cols-1; col++)
00149                         if (QVIMAGE_PIXEL(cornerResponseImage, col, row,0) >= threshold)
00150                                 {
00151                                 // a. Look for the maximum neighbour for the actual pixel.
00152                                 int maxDir = -1;
00153                                 sFloat maxVal = QVIMAGE_PIXEL(cornerResponseImage, col, row, 0);
00154 
00155                                 for (int d = 0; d < 4; d++)
00156                                         if ( maxVal < QVIMAGE_PIXEL(cornerResponseImage, col + xD[d], row + yD[d], 0) )
00157                                                 {
00158                                                 maxDir = d;
00159                                                 maxVal = QVIMAGE_PIXEL(cornerResponseImage, col + xD[maxDir], row + yD[maxDir], 0);
00160                                                 }
00161         
00162                                 // b. If found, join actual pixel to its group.
00163                                 if (maxDir > -1)
00164                                         disjointSet.unify(col, row, col + xD[maxDir], row + yD[maxDir]);
00165                                 }
00166 
00167         // 2. Create sets for all the sets of pixels with more than one element.
00168         QMap<int, QVVector> hotPoints;
00169         for(int row = 1; row < rows-1; row++)
00170                 for(int col = 1; col < cols-1; col++)
00171                         {
00172                         const sFloat pixelValue = QVIMAGE_PIXEL(cornerResponseImage, col, row, 0);
00173                         if (QVIMAGE_PIXEL(cornerResponseImage, col, row, 0) >= threshold)
00174                                 {
00175                                 QVVector v(3);
00176                                 v[0] = pixelValue * col;
00177                                 v[1] = pixelValue * row;
00178                                 v[2] = pixelValue;
00179                                 const int setIndex = disjointSet.find(col, row);
00180                                 if (hotPoints.contains(setIndex))
00181                                         hotPoints[setIndex] += v;
00182                                 else
00183                                         hotPoints.insert(setIndex, v);
00184                                 }
00185                         }
00186 
00187         // 3. Get sorted list of points
00188         QMap<sFloat, QPointF> sortedPoints;
00189         foreach(int index, hotPoints.keys())
00190                 {
00191                 QVVector v = hotPoints[index];
00192                 sortedPoints.insertMulti(v[2], QPointF(v[0]/v[2]+2, v[1]/v[2]+2));
00193                 }
00194 
00195         QList<QPointF> result;
00196         foreach(sFloat key, sortedPoints.uniqueKeys())
00197                 foreach (QPointF point, sortedPoints.values(key))
00198                 result.append(point);
00199 
00200         return result;
00201         }
00202 
00203 
00204 
00205 QList< QPair<sFloat, QPointF> > GetMaximalResponsePoints3bis(const QVImage<sFloat> &cornerResponseImage, const double threshold)
00206         {
00207         static const int        xD[4] = { -1, +0, +1, +0 },
00208                                 yD[4] = { +0, -1, +0, +1 };
00209 
00210         const int rows = cornerResponseImage.getRows(), cols = cornerResponseImage.getCols();
00211         QVDisjointSet disjointSet(cornerResponseImage);
00212         QVIMAGE_INIT_READ(sFloat,cornerResponseImage);
00213 
00214         // 1. Join in the disjoint set all the neighbour pixels
00215         for(int row = 1; row < rows-1; row++)
00216                 for(int col = 1; col < cols-1; col++)
00217                         if (QVIMAGE_PIXEL(cornerResponseImage, col, row,0) >= threshold)
00218                                 {
00219                                 // a. Look for the maximum neighbour for the actual pixel.
00220                                 int maxDir = -1;
00221                                 sFloat maxVal = QVIMAGE_PIXEL(cornerResponseImage, col, row, 0);
00222 
00223                                 for (int d = 0; d < 4; d++)
00224                                         if ( maxVal < QVIMAGE_PIXEL(cornerResponseImage, col + xD[d], row + yD[d], 0) )
00225                                                 {
00226                                                 maxDir = d;
00227                                                 maxVal = QVIMAGE_PIXEL(cornerResponseImage, col + xD[maxDir], row + yD[maxDir], 0);
00228                                                 }
00229         
00230                                 // b. If found, join actual pixel to its group.
00231                                 if (maxDir > -1)
00232                                         disjointSet.unify(col, row, col + xD[maxDir], row + yD[maxDir]);
00233                                 }
00234 
00235         // 2. Create sets for all the sets of pixels with more than one element.
00236         QMap<int, QVVector> hotPoints;
00237         for(int row = 1; row < rows-1; row++)
00238                 for(int col = 1; col < cols-1; col++)
00239                         {
00240                         const sFloat pixelValue = QVIMAGE_PIXEL(cornerResponseImage, col, row, 0);
00241                         if (QVIMAGE_PIXEL(cornerResponseImage, col, row, 0) >= threshold)
00242                                 {
00243                                 QVVector v(3);
00244                                 v[0] = pixelValue * col;
00245                                 v[1] = pixelValue * row;
00246                                 v[2] = pixelValue;
00247                                 const int setIndex = disjointSet.find(col, row);
00248                                 if (hotPoints.contains(setIndex))
00249                                         hotPoints[setIndex] += v;
00250                                 else
00251                                         hotPoints.insert(setIndex, v);
00252                                 }
00253                         }
00254 
00255         // 3. Get sorted list of points
00256         QMap<sFloat, QPointF> sortedPoints;
00257         foreach(int index, hotPoints.keys())
00258                 {
00259                 QVVector v = hotPoints[index];
00260                 sortedPoints.insertMulti(v[2], QPointF(v[0]/v[2]+2, v[1]/v[2]+2));
00261                 }
00262 
00263         QList< QPair<sFloat, QPointF> > result;
00264         foreach(const sFloat key, sortedPoints.uniqueKeys())
00265                 foreach (const QPointF point, sortedPoints.values(key))
00266                         result.append(QPair<sFloat, QPointF>(key,point));
00267 
00268         return result;
00269         }
00270 
00271