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
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
00096
00097
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
00127 Q_ASSERT( (value <= minVal) || (value >= maxVal) );
00128 Q_ASSERT( minVal <= maxVal );
00129
00130
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 }