00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <iostream>
00026 #include <qvipp.h>
00027 #include <QVMatrix>
00028 #include <qvip/qvipp/macros.h>
00029
00030 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Cj_ROIOFFSET_BORDER3x3(FilterSharpen, uChar, 1, _8u_C1R);
00031 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Cj_ROIOFFSET_BORDER3x3(FilterSharpen, sFloat, 1, _32f_C1R);
00032 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_DESTIMAGE_Ti_Cj_ROIOFFSET(Copy, uChar, 3, _8u_P3C3R);
00033 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_DESTIMAGE_Ti_Cj_ROIOFFSET(Copy, uShort, 3, _16u_P3C3R);
00034 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_DESTIMAGE_Ti_Cj_ROIOFFSET(Copy, sShort, 3, _16s_P3C3R);
00035 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_DESTIMAGE_Ti_Cj_ROIOFFSET(Copy, sInt, 3, _32s_P3C3R);
00036 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_SRCIMAGE_Ti_C1_DESTIMAGE_Ti_Cj_ROIOFFSET(Copy, sFloat, 3, _32f_P3C3R);
00037 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_ROIOFFSET(Copy, uChar, 3, _8u_C3P3R);
00038 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_ROIOFFSET(Copy, uShort, 3, _16u_C3P3R);
00039 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_ROIOFFSET(Copy, sShort, 3, _16s_C3P3R);
00040 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_ROIOFFSET(Copy, sInt, 3, _32s_C3P3R);
00041 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_DESTIMAGE_Ti_C1_ROIOFFSET(Copy, sFloat, 3, _32f_C3P3R);
00042 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Ck_CHANNELNUM_ROIOFFSET(Copy, uChar, 3, 1, _8u_C3C1R);
00043 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Ck_CHANNELNUM_ROIOFFSET(Copy, uShort, 3, 1, _16u_C3C1R);
00044 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Ck_CHANNELNUM_ROIOFFSET(Copy, sShort, 3, 1, _16s_C3C1R);
00045 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Ck_CHANNELNUM_ROIOFFSET(Copy, sInt, 3, 1, _32s_C3C1R);
00046 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Ck_CHANNELNUM_ROIOFFSET(Copy, sFloat, 3, 1, _32f_C3C1R);
00047 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_SRCIMAGE_Ti_Cj_DESTIMAGE_C1_Tuchar_IPPCMPOP_ROIOFFSET(Compare, uChar, 3, _8u_C3R);
00048 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_SRCIMAGE_Ti_Cj_DESTIMAGE_C1_Tuchar_IPPCMPOP_ROIOFFSET(Compare, uShort, 3, _16u_C3R);
00049 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_SRCIMAGE_Ti_Cj_DESTIMAGE_C1_Tuchar_IPPCMPOP_ROIOFFSET(Compare, sShort, 3, _16s_C3R);
00050 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_SRCIMAGE_Ti_Cj_DESTIMAGE_C1_Tuchar_IPPCMPOP_ROIOFFSET(Compare, sFloat, 3, _32f_C3R);
00051 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Cj_BUFFERIMAGE_Ti_Cj_IPPMASKSIZE__ROIOFFSET(FilterSobelNegVertBorder, uChar, sShort, 1, _8u16s_C1R);
00052 DEFINE_IPP_FUNCTION_SRCIMAGE_Ti_Cj_DESTIMAGE_Ti_Cj_BUFFERIMAGE_Ti_Cj_IPPMASKSIZE__ROIOFFSET(FilterSobelHorizBorder, uChar, sShort, 1, _8u16s_C1R);
00053 DEFINE_IPP_FUNCTION_SRCGENERICIMAGE_DESTBUFFERIMAGE_Ti_Cj_IPPMASKSIZE__ROIOFFSET(FilterSobelNegVertGetBufferSize, uChar, sShort, 1, _8u16s_C1R);
00054 DEFINE_IPP_FUNCTION_SRCGENERICIMAGE_DESTBUFFERIMAGE_Ti_Cj_IPPMASKSIZE__ROIOFFSET(FilterSobelHorizGetBufferSize, uChar, sShort, 1, _8u16s_C1R);
00055
00056 #define DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_DOUBLE_DOUBLE_INTERPOLATION(NAME, TYPE, PLANES, SUBFIX) \
00057 void NAME(const QVImage<TYPE, PLANES> &src, QVImage<TYPE, PLANES> &dest, int interpolation) \
00058 { \
00059 double factorX = (double) dest.getROI().width() / (double) src.getROI().width(), \
00060 factorY = (double) dest.getROI().height() / (double) src.getROI().height(); \
00061 \
00062 IPP_DEBUG(NAME, ippi ## NAME ## SUBFIX, \
00063 src.getReadData(), IMAGE_SIZE(src), src.getStep(), IMAGE_ROIRECT(src), \
00064 PDATA_WRITE(dest), dest.getStep(), IMAGE_ROISIZE(dest), \
00065 factorX, factorY, interpolation); \
00066 }
00067
00068 DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_DOUBLE_DOUBLE_INTERPOLATION(Resize, uChar, 1, _8u_C1R);
00069 DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_DOUBLE_DOUBLE_INTERPOLATION(Resize, uChar, 3, _8u_C3R);
00070 DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_DOUBLE_DOUBLE_INTERPOLATION(Resize, uShort, 1, _16u_C1R);
00071 DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_DOUBLE_DOUBLE_INTERPOLATION(Resize, sFloat, 1, _32f_C1R);
00072
00073 #define DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_BUFFER_KERNELSIZE_SFLOAT_BORDERTYPE_BORDERVALUE(NAME, TYPE, C, SUBFIX) \
00074 void NAME(const QVImage<TYPE, C> &src, QVImage<TYPE, C> &dest, QVImage<uChar> &buffer, sInt kernelSize, \
00075 sFloat sfloat, IppiBorderType borderType, sFloat borderValue, const QPoint &destROIOffset) \
00076 { \
00077 dest.setROI(destROIOffset.x(), destROIOffset.y(), \
00078 src.getROI().width(), src.getROI().height()); \
00079 \
00080 IPP_DEBUG(NAME, ippi ## NAME ## SUBFIX, \
00081 PDATA_READ(src), src.getStep(), \
00082 PDATA_WRITE(dest), dest.getStep(), \
00083 IMAGE_ROISIZE(dest), \
00084 kernelSize, sfloat, borderType, borderValue, \
00085 buffer.getWriteData()); \
00086 }
00087
00088 DEFINE_IPP_FUNCTION_QVIMAGE_QVIMAGE_BUFFER_KERNELSIZE_SFLOAT_BORDERTYPE_BORDERVALUE(FilterGaussBorder, sFloat, 1, _32f_C1R);
00089
00090 #define DEFINE_IPP_FUNCTION_QVIMAGE_BUFFER_THRESHOLD_PIPPIPOINT_UINT_PUINT_IPPINORM_BORDER(NAME, TYPE, C, SUBFIX) \
00091 void NAME(const QVImage<TYPE, C> &img, QVImage<uChar> &buffer, QList<QPoint> &points, TYPE threshold, IppiNorm norm, uInt border, uInt maxPeakCount) \
00092 { \
00093 int pPeakCount; \
00094 IppiPoint *pPeak = new IppiPoint[maxPeakCount](); \
00095 \
00096 IPP_DEBUG(NAME, ippi ## NAME ## SUBFIX, \
00097 PDATA_READ(img), img.getStep(), IMAGE_ROISIZE(img), \
00098 threshold, pPeak, maxPeakCount, &pPeakCount, \
00099 norm, border, buffer.getWriteData()); \
00100 \
00101 for (int n = 0; n < pPeakCount; n++) \
00102 points.append(QPoint(pPeak[n].x, pPeak[n].y)); \
00103 \
00104 delete pPeak; \
00105 }
00106
00107 DEFINE_IPP_FUNCTION_QVIMAGE_BUFFER_THRESHOLD_PIPPIPOINT_UINT_PUINT_IPPINORM_BORDER(FindPeaks3x3, sInt, 1, _32s_C1R);
00108 DEFINE_IPP_FUNCTION_QVIMAGE_BUFFER_THRESHOLD_PIPPIPOINT_UINT_PUINT_IPPINORM_BORDER(FindPeaks3x3, sFloat, 1, _32f_C1R);
00109
00110 #define DEFINE_IPP_FUNCTION_QVIMAGE_BUFFER_ROIWIDTH(NAME, TYPE, C, SUBFIX) \
00111 void NAME(const QVImage<TYPE,C> &image, QVImage<uChar> &buffer) \
00112 { \
00113 int pBufferSize; \
00114 \
00115 IPP_DEBUG(Peaks3x3GetBufferSize, ippi ## NAME ## SUBFIX, \
00116 image.getROI().width(), &pBufferSize); \
00117 buffer = QVImage<uChar>(2*pBufferSize,1); \
00118 }
00119
00120 DEFINE_IPP_FUNCTION_QVIMAGE_BUFFER_ROIWIDTH(FindPeaks3x3GetBufferSize, sInt, 1, _32s_C1R);
00121 DEFINE_IPP_FUNCTION_QVIMAGE_BUFFER_ROIWIDTH(FindPeaks3x3GetBufferSize, sFloat, 1, _32f_C1R);
00122
00124 void YUV420ToRGB(const QVImage<uChar, 1> &src1, const QVImage<uChar, 1> &src2, const QVImage<uChar, 1> &src3,
00125 QVImage<uChar, 3> &dest, const QPoint &destROIOffset)
00126 {
00127 const uChar * pSrc[3] = { PDATA_READ(src1), PDATA_READ(src2), PDATA_READ(src3) };
00128 int srcStep[3] = { src1.getStep(), src2.getStep(), src3.getStep() };
00129
00130 dest.setROI(destROIOffset.x(), destROIOffset.y(), src1.getROI().width(), src1.getROI().height());
00131
00132 IPP_DEBUG("YUV420ToRGB", ippiYUV420ToRGB_8u_P3C3R,
00133 pSrc, srcStep,
00134 PDATA_WRITE(dest), dest.getStep(),
00135 IMAGE_ROISIZE(dest));
00136 }
00137
00139 void RGBToYUV420(const QVImage<uChar, 3> &src, QVImage<uChar, 1> &dst1, QVImage<uChar, 1> &dst2, QVImage<uChar, 1> &dst3, const QPoint &destROIOffset)
00140 {
00141 uChar * pDst[3] = { PDATA_WRITE(dst1), PDATA_WRITE(dst2), PDATA_WRITE(dst3) };
00142 int dstStep[3] = { dst1.getStep(), dst2.getStep(), dst3.getStep() };
00143
00144 dst1.setROI(destROIOffset.x(), destROIOffset.y(), src.getROI().width(), src.getROI().height());
00145 dst2.setROI(destROIOffset.x()/2, destROIOffset.y()/2, src.getROI().width()/2, src.getROI().height()/2);
00146 dst3.setROI(destROIOffset.x()/2, destROIOffset.y()/2, src.getROI().width()/2, src.getROI().height()/2);
00147
00148 IPP_DEBUG("RGBToTUV420", ippiRGBToYUV420_8u_C3P3R,
00149 PDATA_READ(src), src.getStep(),
00150 pDst, dstStep,
00151 IMAGE_ROISIZE(dst1));
00152 }
00153
00154 void FilterGaussGetBufferSize(const QVGenericImage &image, QVImage<uChar> &buffer, uInt kernelSize)
00155 {
00156 int pBufferSize;
00157 IPP_DEBUG(FilterGaussGetBufferSize, ippiFilterGaussGetBufferSize_32f_C1R, IMAGE_ROISIZE(image), kernelSize, &pBufferSize);
00158 buffer = QVImage<uChar>(pBufferSize,1);
00159 }
00160
00161 void MinEigenValGetBufferSize(const QVGenericImage &image, QVImage<uChar> &buffer, uInt apertureSize, uInt avgWindow)
00162 {
00163 int pBufferSize;
00164 IPP_DEBUG(MinEigenVal, ippiMinEigenValGetBufferSize_8u32f_C1R, IMAGE_ROISIZE(image), apertureSize, avgWindow, &pBufferSize);
00165 buffer = QVImage<uChar>(pBufferSize,1);
00166 }
00167
00168 void CannyGetSize(const QVGenericImage &src, QVImage<uChar> &buffer)
00169 {
00170 int cannyBufferSize;
00171 IPP_DEBUG(CannyGetSize, ippiCannyGetSize, IMAGE_ROISIZE(src),&cannyBufferSize);
00172 buffer = QVImage<uChar>(cannyBufferSize,1);
00173 }
00174
00175 void FastMarchingGetBufferSize(const QVGenericImage &image, QVImage<uChar> &buffer)
00176 {
00177 int bufferSize;
00178 IPP_DEBUG(CannyGetSize, ippiFastMarchingGetBufferSize_8u32f_C1R, IMAGE_ROISIZE(image),&bufferSize);
00179 buffer = QVImage<uChar>(bufferSize,1);
00180 }
00181
00182
00183 void InpaintInitAllocC3(IppiInpaintState_8u_C3R **pState, const QVImage<sFloat> &distances, const QVImage<uChar> &mask,
00184 const sFloat radius, const IppiInpaintFlag flag)
00185 {
00186 IPP_DEBUG( Inpaint, ippiInpaintInitAlloc_8u_C3R, pState, distances.getReadData(), distances.getStep(),
00187 mask.getReadData(), mask.getStep(), IMAGE_ROISIZE(mask), radius, flag);
00188 }
00189
00190 void InpaintFreeC3(IppiInpaintState_8u_C3R *pState)
00191 {
00192 IPP_DEBUG(Inpaint, ippiInpaintFree_8u_C3R,pState);
00193 }
00194
00195 void InpaintInitAllocC1(IppiInpaintState_8u_C1R **pState, const QVImage<sFloat> &distances, const QVImage<uChar> &mask,
00196 const sFloat radius, const IppiInpaintFlag flag)
00197 {
00198 IPP_DEBUG( Inpaint, ippiInpaintInitAlloc_8u_C1R, pState, distances.getReadData(), distances.getStep(),
00199 mask.getReadData(), mask.getStep(), IMAGE_ROISIZE(mask), radius, flag);
00200 }
00201
00202 void InpaintFreeC1(IppiInpaintState_8u_C1R *pState)
00203 {
00204 IPP_DEBUG(Inpaint, ippiInpaintFree_8u_C1R,pState);
00205 }
00206
00207
00208 QVector<int> HistogramRange(const QVImage<uChar, 1> &src)
00209 {
00210
00211 int nLevels = 257;
00212 sInt pLevels[nLevels];
00213 int pHist[nLevels];
00214
00215 for(sInt i=0; i<nLevels; i++)
00216 pLevels[i] = i;
00217
00218 IPP_DEBUG(HistogramRange, ippiHistogramRange_8u_C1R,
00219 PDATA_READ(src), src.getStep(), IMAGE_ROISIZE(src),
00220 pHist, pLevels, nLevels);
00221
00223
00224 QVector< int > result(256);
00225 for (int i=0; i<result.size(); i++)
00226 result[i] = pHist[i];
00227
00228 return result;
00229 }
00230
00231 QMap<sInt, int> HistogramRange(const QVImage<uChar, 1> &src, QList<uChar> values)
00232 {
00233
00234 int nLevels = values.size();
00235 sInt pLevels[nLevels];
00236 int pHist[nLevels];
00237
00238 Q_ASSERT_X(false, "QMap<sInt, int> HistogramRange(QVImage<uChar, 1> &src, QList<uChar> values)",
00239 "Tried an user defined values QList. Functionality not implemented yet.");
00240
00241 IPP_DEBUG(HistogramRange, ippiHistogramRange_8u_C1R,
00242 PDATA_READ(src), src.getStep(), IMAGE_ROISIZE(src),
00243 pHist, pLevels, nLevels);
00244
00246
00247 QMap<sInt, int> histogram;
00248 for (int i=0; i<nLevels; i++)
00249 histogram.insert(pLevels[i], pHist[i]);
00250
00251 return histogram;
00252 }
00253
00254
00255 void FloodFillGetSize(const QVGenericImage &src, QVImage<uChar> &buffer)
00256 {
00257 int floodFillBufferSize;
00258 IPP_DEBUG(FloodFillGetSize, ippiFloodFillGetSize, IMAGE_ROISIZE(src),&floodFillBufferSize);
00259 buffer = QVImage<uChar>(floodFillBufferSize,1);
00260 }
00261
00262 #define CREATE_IPP_FUNCTION_FLOOD_FILL(NAME, CONNECTIVITY, SUBFIX, TYPE) \
00263 void NAME(QVImage<TYPE> &img, QVImage<uChar> &buffer, \
00264 uInt seedX, uInt seedY, TYPE newVal, TYPE minDelta, TYPE maxDelta) \
00265 { \
00266 IppiConnectedComp pRegion; \
00267 IPP_DEBUG(NAME, ippiFloodFill ## CONNECTIVITY ## SUBFIX, \
00268 PDATA_WRITE(img), img.getStep(), IMAGE_ROISIZE(img), \
00269 IPP_POINT(seedX, seedY), newVal, minDelta, maxDelta, \
00270 &pRegion, buffer.getWriteData()); \
00271 }
00272
00273 CREATE_IPP_FUNCTION_FLOOD_FILL(FloodFillRange4Connected, _Range4Con, _8u_C1IR, uChar);
00274 CREATE_IPP_FUNCTION_FLOOD_FILL(FloodFillGradient4Connected, _Grad4Con, _8u_C1IR, uChar);
00275
00276 #define CREATE_IPP_FUNCTION_WARP_PERSPECTIVE(NAME, SUBFIX, C, TYPE) \
00277 void NAME(const QVImage<TYPE, C> &src, QVImage<TYPE, C> &dest, const QVMatrix &rectifyingHomography, int interpolation, const QPoint &) \
00278 { \
00279 double coeffs[3][3]; \
00280 for (int i = 0; i < 3; i++) \
00281 for (int j = 0; j < 3; j++) \
00282 coeffs[i][j] = rectifyingHomography(i,j); \
00283 \
00284 IPP_DEBUG(NAME, ippi ## NAME ## SUBFIX, \
00285 src.getReadData(), IMAGE_SIZE(src), src.getStep(), IMAGE_ROIRECT(src), \
00286 PDATA_WRITE(dest), dest.getStep(), IMAGE_ROIRECT(dest), \
00287 coeffs, interpolation); \
00288 }
00289
00290 CREATE_IPP_FUNCTION_WARP_PERSPECTIVE(WarpPerspective, _8u_C1R, 1, uChar);
00291 CREATE_IPP_FUNCTION_WARP_PERSPECTIVE(WarpPerspective, _8u_C3R, 3, uChar);
00292
00293 #include <qvmath/qvmatrix.h>
00294 void Filter(const QVImage<sFloat> &src, QVImage<sFloat> &dest, const QVMatrix kernel, const QPoint &destROIOffset)
00295 {
00296 Q_ASSERT(kernel.getCols() == kernel.getRows());
00297
00298 const int kernelSize = kernel.getCols();
00299 sFloat kernelValues[kernelSize*kernelSize];
00300 for(int i = 0; i < kernelSize; i++)
00301 for(int j = 0; j < kernelSize; j++)
00302 kernelValues[i+ kernelSize*j] = kernel(i,j);
00303
00304 dest.setROI(destROIOffset.x(), destROIOffset.y(),
00305 src.getROI().width()-kernelSize+1, src.getROI().height()-kernelSize+1);
00306
00309 IPP_DEBUG(NAME, ippiFilter_32f_C1R,
00310 PDATA_READ(src), src.getStep(),
00311 PDATA_WRITE(dest), dest.getStep(),
00312 IMAGE_ROISIZE(dest),
00313 kernelValues, IPP_SIZE(kernelSize, kernelSize), IPP_POINT(0,0)
00314 );
00315 }
00316
00318 void FilterColumn(const QVImage<sFloat> &src, QVImage<sFloat> &dest, const QVVector kernel, const QPoint &destROIOffset)
00319 {
00320 const int kernelSize = kernel.size();
00321 sFloat kernelValues[kernelSize];
00322 for(int i = 0; i < kernelSize; i++)
00323 kernelValues[i] = kernel[i];
00324
00325 dest.setROI(destROIOffset.x(), destROIOffset.y(),
00326 src.getROI().width(), src.getROI().height()-kernelSize+1);
00327
00328 IPP_DEBUG(NAME, ippiFilterColumn_32f_C1R,
00329 PDATA_READ(src), src.getStep(),
00330 PDATA_WRITE(dest), dest.getStep(),
00331 IMAGE_ROISIZE(dest),
00332 kernelValues, kernelSize, kernelSize-1
00333 );
00334 }
00335
00337 void FilterRow(const QVImage<sFloat> &src, QVImage<sFloat> &dest, const QVVector kernel, const QPoint &destROIOffset)
00338 {
00339 const int kernelSize = kernel.size();
00340
00341 sFloat kernelValues[kernelSize];
00342 for(int i = 0; i < kernelSize; i++)
00343 kernelValues[i] = kernel[i];
00344
00345 dest.setROI(destROIOffset.x(), destROIOffset.y(),
00346 src.getROI().width()-kernelSize+1, src.getROI().height());
00347
00348 IPP_DEBUG(NAME, ippiFilterRow_32f_C1R,
00349 PDATA_READ(src), src.getStep(),
00350 PDATA_WRITE(dest), dest.getStep(),
00351 IMAGE_ROISIZE(dest),
00352 kernelValues, kernelSize, kernelSize-1
00353 );
00354 }