00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 QVector<int> histogram = qvipp::HistogramRange(image);
00034
00035 for (int k=0; k<256; k++)
00036 result[k].reserve(histogram[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 uInt cols = src.getCols(), rows = src.getRows();
00096 qvipp::Set(dest,0);
00097 sFloat actual;
00098
00099 QVIMAGE_INIT_READ(sFloat,src);
00100 QVIMAGE_INIT_WRITE(uChar,dest);
00101 for(uInt row = rowMaskSize; row < rows-rowMaskSize; row++)
00102 for(uInt col = colMaskSize; col < cols-colMaskSize; col++)
00103 {
00104 actual = QVIMAGE_PIXEL(src, col, row,0);
00105 if (actual < threshold)
00106 continue;
00107 QVIMAGE_PIXEL(dest, col, row, 0) = IPP_MAX_8U;
00108 for (uInt j = row-rowMaskSize; j < row+rowMaskSize; j++)
00109 for (uInt i = col-colMaskSize; i < col+colMaskSize; i++)
00110 if ( ((i != col) || (j != row)) &&
00111 (actual <= QVIMAGE_PIXEL(src, i, j, 0)) )
00112 {
00113 QVIMAGE_PIXEL(dest, col, row, 0) = 0;
00114 goto next;
00115 }
00116 next:
00117 continue;
00118 }
00119 }
00120
00121 int myFloodFill(QVImage<uChar> &image, uInt x, uInt y, uInt value, uInt minVal, uInt maxVal)
00122 {
00123
00124 Q_ASSERT( (value <= minVal) || (value >= maxVal) );
00125 Q_ASSERT( minVal <= maxVal );
00126
00127
00128 if ( (x >= image.getCols()) || (y >= image.getRows()))
00129 return 0;
00130
00131 if ( (image(x,y) < minVal) || (image(x,y) > maxVal) )
00132 return 0;
00133
00134 image(x,y) = value;
00135
00136 int val = 1;
00137 val += myFloodFill(image, x-1, y, value, minVal, maxVal);
00138 val += myFloodFill(image, x, y-1, value, minVal, maxVal);
00139 val += myFloodFill(image, x+1, y, value, minVal, maxVal);
00140 val += myFloodFill(image, x, y+1, value, minVal, maxVal);
00141
00142 val += myFloodFill(image, x-1, y-1, value, minVal, maxVal);
00143 val += myFloodFill(image, x-1, y+1, value, minVal, maxVal);
00144 val += myFloodFill(image, x+1, y-1, value, minVal, maxVal);
00145 val += myFloodFill(image, x+1, y+1, value, minVal, maxVal);
00146
00147 return val;
00148 }
00149
00150 #define DEFINE_QVDTA_FUNCTION_EQUALIZE_HISTOGRAM(TYPE, C) \
00151 void equalizeHistogram(const QVImage<TYPE,C> &image, QVImage<TYPE,C> &equalized) \
00152 { \
00153 uInt rows = image.getRows(), cols = image.getCols(); \
00154 TYPE maxVal, minVal; \
00155 \
00156 qvipp::Max(image,maxVal); \
00157 qvipp::Min(image,minVal); \
00158 \
00159 QVImage<TYPE,C> temp(cols, rows), result(cols, rows); \
00160 qvipp::SubC(image, temp, minVal); \
00161 qvipp::MulC(temp, result, 255/(maxVal-minVal)); \
00162 equalized = result; \
00163 }
00164
00165 DEFINE_QVDTA_FUNCTION_EQUALIZE_HISTOGRAM(uChar,1);
00166 DEFINE_QVDTA_FUNCTION_EQUALIZE_HISTOGRAM(sFloat,1);
00167 }