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

Generated on Thu Jul 17 17:23:27 2008 for QVision by  doxygen 1.5.3