OpenCV代码提取 resize函数的实现

                 之前在http://blog.csdn.net/fengbingchun/article/details/17335477 中有过对cv::resize函数五种插值算法的介绍。这里将Open
摘要由CSDN通过智能技术生成
               

 之前在http://blog.csdn.net/fengbingchun/article/details/17335477 中有过对cv::resize函数五种插值算法的介绍。这里将OpenCV3.1中五种插值算法的代码进行了提取调整。支持N通道uchar和float类型。经测试,与OpenCV3.1结果完全一致。

 实现代码resize.hpp:

// fbc_cv is free software and uses the same licence as OpenCV// Email: fengbingchun@163.com#ifndef FBC_CV_RESIZE_HPP_#define FBC_CV_RESIZE_HPP_/* reference: imgproc/include/opencv2/imgproc.hpp              imgproc/src/imgwarp.cpp*/#include "core/mat.hpp"#include "core/base.hpp"#include "core/saturate.hpp"#include "core/utility.hpp"#include "imgproc.hpp"namespace fbc {
   static const int MAX_ESIZE = 16;// interpolation formulas and tablesconst int INTER_RESIZE_COEF_BITS = 11;const int INTER_RESIZE_COEF_SCALE = 1 << INTER_RESIZE_COEF_BITS;template<typename _Tp, int chs> static int resize_nearest(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);template<typename _Tp, int chs> static int resize_linear(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);template<typename _Tp, int chs> static int resize_cubic(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);template<typename _Tp, int chs> static int resize_area(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);template<typename _Tp, int chs> static int resize_lanczos4(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst);// resize the image src down to or up to the specified size// support type: uchar/floattemplate<typename _Tp, int chs>int resize(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, int interpolation = NTER_LINEAR){ FBC_Assert((interpolation >= 0) && (interpolation < 5)); FBC_Assert((src.rows >= 4 && src.cols >= 4) && (dst.rows >= 4  && dst.cols >= 4)); FBC_Assert((sizeof(_Tp) == 1) || sizeof(_Tp) == 4); // uchar || float Size ssize = src.size(); Size dsize = dst.size(); if (dsize == ssize) {  // Source and destination are of same size. Use simple copy.  src.copyTo(dst);  return 0; } switch (interpolation) {  case 0: {   resize_nearest(src, dst);   break;  }  case 1: {   resize_linear(src, dst);   break;  }  case 2: {   resize_cubic(src, dst);   break;  }  case 3: {   resize_area(src, dst);   break;  }  case 4: {   resize_lanczos4(src, dst);   break;  }  default:   return -1; } return 0;}struct DecimateAlpha{
     int si, di; float alpha;};template<typename type>static int computeResizeAreaTab(int ssize, int dsize, int cn, double scale, DecimateAlpha* tab)int k = 0for (int dx = 0; dx < dsize; dx++) {  double fsx1 = dx * scale;  double fsx2 = fsx1 + scale;  double cellWidth = std::min(scale, ssize - fsx1);  int sx1 = fbcCeil(fsx1), sx2 = fbcFloor(fsx2);  sx2 = std::min(sx2, ssize - 1);  sx1 = std::min(sx1, sx2);  if (sx1 - fsx1 > 1e-3) {   assert(k < ssize * 2);   tab[k].di = dx * cn;   tab[k].si = (sx1 - 1) * cn;   tab[k++].alpha = (float)((sx1 - fsx1) / cellWidth);  }  for (int sx = sx1; sx < sx2; sx++) {   assert(k < ssize * 2);   tab[k].di = dx * cn;   tab[k].si = sx * cn;   tab[k++].alpha = float(1.0 / cellWidth);  }  if (fsx2 - sx2 > 1e-3) {   assert(k < ssize * 2);   tab[k].di = dx * cn;   tab[k].si = sx2 * cn;   tab[k++].alpha = (float)(std::min(std::min(fsx2 - sx2, 1.), cellWidth) / cellWidth);  } } return k;}template<typename ST, typename DT> struct Cast{
     typedef ST type1; typedef DT rtype; DT operator()(ST val) const { return saturate_cast<DT>(val); }};template<typename ST, typename DT, int bits> struct FixedPtCast{
     typedef ST type1; typedef DT rtype; enum { SHIFT = bits, DELTA = 1 << (bits - 1) }; DT operator()(ST val) const { return saturate_cast<DT>((val + DELTA) >> SHIFT); }};template<typename type>static type clip(type x, type a, type b)return x >= a ? (x < b ? x : b - 1) : a;}template<typename T, typename WT, typename AT>struct HResizeLinear{
     typedef T value_type; typedef WT buf_type; typedef AT alpha_type; void operator()(const T** src, WT** dst, int count,  const int* xofs, const AT* alpha,  int swidth, int dwidth, int cn, int xmin, int xmax, int ONE) const {  int dx, k;  int dx0 = 0;  for (k = 0; k <= count - 2; k++) {   const T *S0 = src[k], *S1 = src[k + 1];   WT *D0 = dst[k], *D1 = dst[k + 1];   for (dx = dx0; dx < xmax; dx++) {    int sx = xofs[dx];    WT a0 = alpha[dx * 2], a1 = alpha[dx * 2 + 1];    WT t0 = S0[sx] * a0 + S0[sx + cn] * a1;    WT t1 = S1[sx] * a0 + S1[sx + cn] * a1;    D0[dx] = t0; D1[dx] = t1;   }   for (; dx < dwidth; dx++) {    int sx = xofs[dx];    D0[dx] = WT(S0[sx] * ONE); D1[dx] = WT(S1[sx] * ONE);   }  }  for (; k < count; k++) {   const T *S = src[k];   WT *D = dst[k];   for (dx = 0; dx < xmax; dx++) {    int sx = xofs[dx];    D[dx] = S[sx] * alpha[dx * 2] + S[sx + cn] * alpha[dx * 2 + 1];   }   for (; dx < dwidth; dx++) {    D[dx] = WT(S[xofs[dx]] * ONE);   }  } }};template<typename T, typename WT, typename AT, class CastOp>struct VResizeLinear{
     typedef T value_type; typedef WT buf_type; typedef AT alpha_type; void operator()(const WT** src, T* dst, const AT* beta, int width) const {  WT b0 = beta[0], b1 = beta[1];  const WT *S0 = src[0], *S1 = src[1];  CastOp castOp;  int x = 0;  for (; x <= width - 4; x += 4) {   WT t0, t1;   t0 = S0[x] * b0 + S1[x] * b1;   t1 = S0[x + 1] * b0 + S1[x + 1] * b1;   dst[x] = castOp(t0); dst[x + 1] = castOp(t1);   t0 = S0[x + 2] * b0 + S1[x + 2] * b1;   t1 = S0[x + 3] * b0 + S1[x + 3] * b1;   dst[x + 2] = castOp(t0); dst[x + 3] = castOp(t1);  }  for (; x < width; x++) {   dst[x] = castOp(S0[x] * b0 + S1[x] * b1);  } }};template<>struct VResizeLinear<uchar, int, short, FixedPtCast<int, uchar, INTER_RESIZE_COEF_BITS * 2>>{
     typedef uchar value_type; typedef int buf_type; typedef short alpha_type; void operator()(const buf_type** src, value_type* dst, const alpha_type* beta, int width) const {  alpha_type b0 = beta[0], b1 = beta[1];  const buf_type *S0 = src[0], *S1 = src[1];  int x = 0;  for (; x <= width - 4; x += 4) {   dst[x + 0] = uchar((((b0 * (S0[x + 0] >> 4)) >> 16) + ((b1 * (S1[x + 0] >> 4)) >> 16) + 2) >> 2);   dst[x + 1] = uchar((((b0 * (S0[x + 1] >> 4)) >> 16) + ((b1 * (S1[x + 1] >> 4)) >> 16) + 2) >> 2);   dst[x + 2] = uchar((((b0 * (S0[x + 2] >> 4)) >> 16) + ((b1 * (S1[x + 2] >> 4)) >> 16) + 2) >> 2);   dst[x + 3] = uchar((((b0 * (S0[x + 3] >> 4)) >> 16) + ((b1 * (S1[x + 3] >> 4)) >> 16) + 2) >> 2);  }  for (; x < width; x++) {   dst[x] = uchar((((b0 * (S0[x] >> 4)) >> 16) + ((b1 * (S1[x] >> 4)) >> 16) + 2) >> 2);  } }};template<typename T, typename WT, typename AT>struct HResizeCubic{
     typedef T value_type; typedef WT buf_type; typedef AT alpha_type; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值