D:\opencv\modules\imgproc\src\resize.cpp
4044: void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
4045: double inv_scale_x, double inv_scale_y, int interpolation )
4046: {
4047: CV_INSTRUMENT_REGION();
4048:
4049: Size ssize = _src.size();
4050:
4051: CV_Assert( !ssize.empty() );
4052: if( dsize.empty() )
4053: {
4054: CV_Assert(inv_scale_x > 0); CV_Assert(inv_scale_y > 0);
4055: dsize = Size(saturate_cast<int>(ssize.width*inv_scale_x),
4056: saturate_cast<int>(ssize.height*inv_scale_y));
4057: CV_Assert( !dsize.empty() );
4058: }
4059: else
4060: {
4061: inv_scale_x = (double)dsize.width/ssize.width;
4062: inv_scale_y = (double)dsize.height/ssize.height;
4063: CV_Assert(inv_scale_x > 0); CV_Assert(inv_scale_y > 0);
4064: }
4065:
4066: if (interpolation == INTER_LINEAR_EXACT && (_src.depth() == CV_32F || _src.depth() == CV_64F))
4067: interpolation = INTER_LINEAR; // If depth isn't supported fallback to generic resize
4068:
4069: CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat() && _src.cols() > 10 && _src.rows() > 10,
4070: ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))
4071:
4072: // Fake reference to source. Resolves issue 13577 in case of src == dst.
4073: UMat srcUMat;
4074: if (_src.isUMat())
4075: srcUMat = _src.getUMat();
4076:
4077: Mat src = _src.getMat();
4078: _dst.create(dsize, src.type());
4079: Mat dst = _dst.getMat();
4080:
4081: if (dsize == ssize)
4082: {
4083: // Source and destination are of same size. Use simple copy.
4084: src.copyTo(dst);
4085: return;
4086: }
4087:
4088: hal::resize(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, inv_scale_x, inv_scale_y, interpolation);
4089: }
在reasize上点鼠标右键,选转到定义,或选转到声明,如果没安装opencv源代码,先安装opencv源代码,然后把opencv的resize函数拷贝到自己的源代码中,改名为myresize
D:\opencv\modules\imgproc\src\resize.cpp
3258: static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
3259: double fx, double fy, int interpolation)
3260: {
3261: int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
3262:
3263: double inv_fx = 1.0 / fx, inv_fy = 1.0 / fy;
3264: float inv_fxf = (float)inv_fx, inv_fyf = (float)inv_fy;
3265: int iscale_x = saturate_cast<int>(inv_fx), iscale_y = saturate_cast<int>(inv_fx);
3266: bool is_area_fast = std::abs(inv_fx - iscale_x) < DBL_EPSILON &&
3267: std::abs(inv_fy - iscale_y) < DBL_EPSILON;
3268:
3269: // in case of scale_x && scale_y is equal to 2
3270: // INTER_AREA (fast) also is equal to INTER_LINEAR
3271: if( interpolation == INTER_LINEAR && is_area_fast && iscale_x == 2 && iscale_y == 2 )
3272: /*interpolation = INTER_AREA*/CV_UNUSED(0); // INTER_AREA is slower
3273:
3274: if( !(cn <= 4 &&
3275: (interpolation == INTER_NEAREST || interpolation == INTER_LINEAR ||
3276: (interpolation == INTER_AREA && inv_fx >= 1 && inv_fy >= 1) )) )
3277: return false;
3278:
3279: UMat src = _src.getUMat();
3280: _dst.create(dsize, type);
3281: UMat dst = _dst.getUMat();
3282:
3283: Size ssize = src.size();
3284: ocl::Kernel k;
3285: size_t globalsize[] = { (size_t)dst.cols, (size_t)dst.rows };
3286:
3287: ocl::Image2D srcImage;
3288:
3289: // See if this could be done with a sampler. We stick with integer
3290: // datatypes because the observed error is low.
3291: bool useSampler = (interpolation == INTER_LINEAR && ocl::Device::getDefault().imageSupport() &&
3292: ocl::Image2D::canCreateAlias(src) && depth <= 4 &&
3293: ocl::Image2D::isFormatSupported(depth, cn, true) &&
3294: src.offset==0);
3295: if (useSampler)
3296: {
3297: int wdepth = std::max(depth, CV_32S);
3298: char buf[2][32];
3299: cv::String compileOpts = format("-D USE_SAMPLER -D depth=%d -D T=%s -D T1=%s "
3300: "-D convertToDT=%s -D cn=%d",
3301: depth, ocl::typeToStr(type), ocl::typeToStr(depth),
3302: ocl::convertTypeStr(wdepth, depth, cn, buf[1]),
3303: cn);
3304: k.create("resizeSampler", ocl::imgproc::resize_oclsrc, compileOpts);
3305:
3306: if (k.empty())
3307: useSampler = false;
3308: else
3309: {
3310: // Convert the input into an OpenCL image type, using normalized channel data types
3311: // and aliasing the UMat.
3312: srcImage = ocl::Image2D(src, true, true);
3313: k.args(srcImage, ocl::KernelArg::WriteOnly(dst),
3314: (float)inv_fx, (float)inv_fy);
3315: }
3316: }
3317:
3318: if (interpolation == INTER_LINEAR && !useSampler)
3319: {
3320: char buf[2][32];
3321:
3322: // integer path is slower because of CPU part, so it's disabled
3323: if (depth == CV_8U && ((void)0, 0))
3324: {
3325: AutoBuffer<uchar> _buffer((dsize.width + dsize.height)*(sizeof(int) + sizeof(short)*2));
3326: int* xofs = (int*)_buffer.data(), * yofs = xofs + dsize.width;
3327: short* ialpha = (short*)(yofs + dsize.height), * ibeta = ialpha + dsize.width*2;
3328: float fxx, fyy;
3329: int sx, sy;
3330:
3331: for (int dx = 0; dx < dsize.width; dx++)
3332: {
3333: fxx = (float)((dx+0.5)*inv_fx - 0.5);
3334: sx = cvFloor(fxx);
3335: fxx -= sx;
3336:
3337: if (sx < 0)
3338: fxx = 0, sx = 0;
3339:
3340: if (sx >= ssize.width-1)
3341: fxx = 0, sx = ssize.width-1;
3342:
3343: xofs[dx] = sx;
3344: ialpha[dx*2 + 0] = saturate_cast<short>((1.f - fxx) * INTER_RESIZE_COEF_SCALE);
3345: ialpha[dx*2 + 1] = saturate_cast<short>(fxx * INTER_RESIZE_COEF_SCALE);
3346: }
3347:
3348: for (int dy = 0; dy < dsize.height; dy++)
3349: {
3350: fyy = (float)((dy+0.5)*inv_fy - 0.5);
3351: sy = cvFloor(fyy);
3352: fyy -= sy;
3353:
3354: yofs[dy] = sy;
3355: ibeta[dy*2 + 0] = saturate_cast<short>((1.f - fyy) * INTER_RESIZE_COEF_SCALE);
3356: ibeta[dy*2 + 1] = saturate_cast<short>(fyy * INTER_RESIZE_COEF_SCALE);
3357: }
3358:
3359: int wdepth = std::max(depth, CV_32S), wtype = CV_MAKETYPE(wdepth, cn);
3360: UMat coeffs;
3361: Mat(1, static_cast<int>(_buffer.size()), CV_8UC1, _buffer.data()).copyTo(coeffs);
3362:
3363: k.create("resizeLN", ocl::imgproc::resize_oclsrc,
3364: format("-D INTER_LINEAR_INTEGER -D depth=%d -D T=%s -D T1=%s "
3365: "-D WT=%s -D convertToWT=%s -D convertToDT=%s -D cn=%d "
3366: "-D INTER_RESIZE_COEF_BITS=%d",
3367: depth, ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype),
3368: ocl::convertTypeStr(depth, wdepth, cn, buf[0]),
3369: ocl::convertTypeStr(wdepth, depth, cn, buf[1]),
3370: cn, INTER_RESIZE_COEF_BITS));
3371: if (k.empty())
3372: return false;
3373:
3374: k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
3375: ocl::KernelArg::PtrReadOnly(coeffs));
3376: }
3377: else
3378: {
3379: int wdepth = std::max(depth, CV_32S), wtype = CV_MAKETYPE(wdepth, cn);
3380: k.create("resizeLN", ocl::imgproc::resize_oclsrc,
3381: format("-D INTER_LINEAR -D depth=%d -D T=%s -D T1=%s "
3382: "-D WT=%s -D convertToWT=%s -D convertToDT=%s -D cn=%d "
3383: "-D INTER_RESIZE_COEF_BITS=%d",
3384: depth, ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype),
3385: ocl::convertTypeStr(depth, wdepth, cn, buf[0]),
3386: ocl::convertTypeStr(wdepth, depth, cn, buf[1]),
3387: cn, INTER_RESIZE_COEF_BITS));
3388: if (k.empty())
3389: return false;
3390:
3391: k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
3392: (float)inv_fx, (float)inv_fy);
3393: }
3394: }
3395: else if (interpolation == INTER_NEAREST)
3396: {
3397: k.create("resizeNN", ocl::imgproc::resize_oclsrc,
3398: format("-D INTER_NEAREST -D T=%s -D T1=%s -D cn=%d",
3399: ocl::vecopTypeToStr(type), ocl::vecopTypeToStr(depth), cn));
3400: if (k.empty())
3401: return false;
3402:
3403: k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
3404: (float)inv_fx, (float)inv_fy);
3405: }
3406: else if (interpolation == INTER_AREA)
3407: {
3408: int wdepth = std::max(depth, is_area_fast ? CV_32S : CV_32F);
3409: int wtype = CV_MAKE_TYPE(wdepth, cn);
3410:
3411: char cvt[2][40];
3412: String buildOption = format("-D INTER_AREA -D T=%s -D T1=%s -D WTV=%s -D convertToWTV=%s -D cn=%d",
3413: ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype),
3414: ocl::convertTypeStr(depth, wdepth, cn, cvt[0]), cn);
3415:
3416: UMat alphaOcl, tabofsOcl, mapOcl;
3417: UMat dmap, smap;
3418:
3419: if (is_area_fast)
3420: {
3421: int wdepth2 = std::max(CV_32F, depth), wtype2 = CV_MAKE_TYPE(wdepth2, cn);
3422: buildOption = buildOption + format(" -D convertToT=%s -D WT2V=%s -D convertToWT2V=%s -D INTER_AREA_FAST"
3423: " -D XSCALE=%d -D YSCALE=%d -D SCALE=%ff",
3424: ocl::convertTypeStr(wdepth2, depth, cn, cvt[0]),
3425: ocl::typeToStr(wtype2), ocl::convertTypeStr(wdepth, wdepth2, cn, cvt[1]),
3426: iscale_x, iscale_y, 1.0f / (iscale_x * iscale_y));
3427:
3428: k.create("resizeAREA_FAST", ocl::imgproc::resize_oclsrc, buildOption);
3429: if (k.empty())
3430: return false;
3431: }
3432: else
3433: {
3434: buildOption = buildOption + format(" -D convertToT=%s", ocl::convertTypeStr(wdepth, depth, cn, cvt[0]));
3435: k.create("resizeAREA", ocl::imgproc::resize_oclsrc, buildOption);
3436: if (k.empty())
3437: return false;
3438:
3439: int xytab_size = (ssize.width + ssize.height) << 1;
3440: int tabofs_size = dsize.height + dsize.width + 2;
3441:
3442: AutoBuffer<int> _xymap_tab(xytab_size), _xyofs_tab(tabofs_size);
3443: AutoBuffer<float> _xyalpha_tab(xytab_size);
3444: int * xmap_tab = _xymap_tab.data(), * ymap_tab = _xymap_tab.data() + (ssize.width << 1);
3445: float * xalpha_tab = _xyalpha_tab.data(), * yalpha_tab = _xyalpha_tab.data() + (ssize.width << 1);
3446: int * xofs_tab = _xyofs_tab.data(), * yofs_tab = _xyofs_tab.data() + dsize.width + 1;
3447:
3448: ocl_computeResizeAreaTabs(ssize.width, dsize.width, inv_fx, xmap_tab, xalpha_tab, xofs_tab);
3449: ocl_computeResizeAreaTabs(ssize.height, dsize.height, inv_fy, ymap_tab, yalpha_tab, yofs_tab);
3450:
3451: // loading precomputed arrays to GPU
3452: Mat(1, xytab_size, CV_32FC1, _xyalpha_tab.data()).copyTo(alphaOcl);
3453: Mat(1, xytab_size, CV_32SC1, _xymap_tab.data()).copyTo(mapOcl);
3454: Mat(1, tabofs_size, CV_32SC1, _xyofs_tab.data()).copyTo(tabofsOcl);
3455: }
3456:
3457: ocl::KernelArg srcarg = ocl::KernelArg::ReadOnly(src), dstarg = ocl::KernelArg::WriteOnly(dst);
3458:
3459: if (is_area_fast)
3460: k.args(srcarg, dstarg);
3461: else
3462: k.args(srcarg, dstarg, inv_fxf, inv_fyf, ocl::KernelArg::PtrReadOnly(tabofsOcl),
3463: ocl::KernelArg::PtrReadOnly(mapOcl), ocl::KernelArg::PtrReadOnly(alphaOcl));
3464:
3465: return k.run(2, globalsize, NULL, false);
3466: }
3467:
3468: return k.run(2, globalsize, 0, false);
3469: }