纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

OpenCV图像缩放resize OpenCV图像缩放resize各种插值方式的比较实现

pan_jinquan   2021-06-07 我要评论
想了解OpenCV图像缩放resize各种插值方式的比较实现的相关内容吗pan_jinquan在本文为您仔细讲解OpenCV图像缩放resize的相关知识和一些Code实例欢迎阅读和指正我们先划重点:OpenCV图像缩放resize,OpenCV,resize下面大家一起来学习吧

1. resize函数说明

    OpenCV提供了resize函数来改变图像的大小函数原型如下:

void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );

    参数说明:

src:输入原图像即待改变大小的图像dst:输出改变大小之后的图像这个图像和原图像具有相同的内容只是大小和原图像不一样而已dsize:输出图像的大小如果这个参数不为0那么就代表将原图像缩放到这个Size(widthheight)指定的大小如果这个参数为0那么原图像缩放之后的大小就要通过下面的公式来计算:

       dsize = Size(round(fx*src.cols), round(fy*src.rows))

       其中fx和fy就是下面要说的两个参数是图像width方向和height方向的缩放比例

fx:width方向的缩放比例如果它是0那么它就会按照(double)dsize.width/src.cols来计算fy:height方向的缩放比例如果它是0那么它就会按照(double)dsize.height/src.rows来计算interpolation:这个是指定插值的方式图像缩放之后肯定像素要进行重新计算的就靠这个参数来指定重新计算像素的方式有以下几种:

      INTER_NEAREST - 最邻近插值
      INTER_LINEAR - 双线性插值如果最后一个参数你不指定默认使用这种方法
      INTER_AREA -区域插值 resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
      INTER_CUBIC - 4x4像素邻域内的双立方插值
      INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值

使用注意事项:

   dsize和fx/fy不能同时为0要么你就指定好dsize的值让fx和fy空置直接使用默认值就像

resize(img, imgDst, Size(30,30));

要么你就让dsize为0指定好fx和fy的值比如fx=fy=0.5那么就相当于把原图两个方向缩小一倍!

OpenCV官方说明:注意红色方框那句话:https://docs.opencv.org/3.2.0/da/d54/group__imgproc__transform.html#ga47a974309e9102f5f08231edc7e7529d

To shrink an image, it will generally look best with cv::INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with cv::INTER_CUBIC (slow) or cv::INTER_LINEAR (faster but still looks OK).

2.各种插值方式的比较

    OpenCV的cv::resize函数支持多种插值方式这里主要比较下面四个常用的插值方式

    参考资料:《OpenCV中resize函数五种插值算法的实现过程》 

2.1 INTER_NEAREST(最近邻插值)

    最近邻插值是最简单的插值方法选取离目标点最近的点作为新的插入点计算公式表示如下:

插值后的边缘效果:由于是以最近的点作为新的插入点因此边缘不会出现缓慢的渐慢过度区域这也导致放大的图像容易出现锯齿的现象

2.2 INTER_CUBIC  (三次样条插值)

插值后的边缘效果:可以有效避免出现锯齿的现象

2.3 INTER_LINEAR(线性插值)

    线性插值是以距离为权重的一种插值方式

插值后的边缘效果:可以有效避免出现锯齿的现象

2.4 INTER_AREA  (区域插值)

   区域插值共分三种情况图像放大时类似于双线性插值图像缩小(x轴、y轴同时缩小)又分两种情况此情况下可以避免波纹出现因此对图像进行缩小时为了避免出现波纹现象推荐采用区域插值方法

  OpenGL说明文档有这么解释:To shrink an image, it will generally look best with #INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with #INTER_CUBIC (slow) or #INTER_LINEAR (faster but still looks OK).

    如果要缩小图像通常推荐使用INTER_AREA插值效果最好而要放大图像通常使用INTER_CUBIC(速度较慢但效果最好)或者使用INTER_LINEAR(速度较快效果还可以)

插值后的边缘效果:

测试代码:

#include <chrono>
#include <opencv2/opencv.hpp>
#define  millisecond 1000000
#define DEBUG_PRINT(...)  printf( __VA_ARGS__); printf("\n")
#define DEBUG_TIME(time_) auto time_ =std::chrono::high_resolution_clock::now()
#define RUN_TIME(time_)  (double)(time_).count()/millisecond
using namespace std;
 
cv::Mat image_resize(cv::Mat image, int width, int height, int interpolation, int num) {
    cv::Mat dest;
    for (int i = 0; i < num; ++i) {
        cv::resize(image, dest, cv::Size(width, height), 0, 0, interpolation);//最近邻插值
    }
    return dest;
}
 
 
int main() {
    string path = "../1.jpg";
    cv::Mat image = cv::imread(path);
    cv::resize(image, image, cv::Size(1000, 1000));
    int re_width = 900;
    int re_height = 900;
    int  num=10;
    cv::Mat image2X_INTER_NEAREST;
    cv::Mat image2X_INTER_LINEAR;
    cv::Mat image2X_INTER_AREA;
    cv::Mat image2X_INTER_CUBIC;
    cv::Mat initMat;
    DEBUG_PRINT("image input size:%dx%d", image.rows, image.cols);
    DEBUG_TIME(T0);
    image2X_INTER_NEAREST=image_resize(image, re_width, re_height, cv::INTER_NEAREST, num);
    DEBUG_TIME(T1);
    image2X_INTER_LINEAR=image_resize(image, re_width, re_height, cv::INTER_LINEAR, num);
    DEBUG_TIME(T2);
    image2X_INTER_AREA=image_resize(image, re_width, re_height, cv::INTER_AREA, num);
    DEBUG_TIME(T3);
    image2X_INTER_CUBIC=image_resize(image, re_width, re_height, cv::INTER_CUBIC, num);
    DEBUG_TIME(T4);
    DEBUG_PRINT("resize_image:%dx%d,INTER_NEAREST:%3.3fms",
            image2X_INTER_NEAREST.rows,
            image2X_INTER_NEAREST.cols,
            RUN_TIME(T1 - T0)/num);
    DEBUG_PRINT("resize_image:%dx%d,INTER_LINEAR :%3.3fms",
            image2X_INTER_LINEAR.rows,
            image2X_INTER_LINEAR.cols,
            RUN_TIME(T2 - T1)/num);
    DEBUG_PRINT("resize_image:%dx%d,INTER_AREA   :%3.3fms",
            image2X_INTER_AREA.rows,
            image2X_INTER_AREA.cols,
            RUN_TIME(T3 - T2)/num);
    DEBUG_PRINT("resize_image:%dx%d,INTER_CUBIC  :%3.3fms",
            image2X_INTER_CUBIC.rows,
            image2X_INTER_CUBIC.cols,
            RUN_TIME(T4 - T3)/num);
    return 0;
}

    运行结果:

image input size:1000x1000
resize_image:900x900,INTER_NEAREST:0.389ms
resize_image:900x900,INTER_LINEAR :0.605ms
resize_image:900x900,INTER_AREA   :2.611ms
resize_image:900x900,INTER_CUBIC  :1.920ms

3. 总结

    测试结果表明:

  •  速度比较:INTER_NEAREST(最近邻插值)>INTER_LINEAR(线性插值)>INTER_CUBIC(三次样条插值)>INTER_AREA  (区域插值)
  • 对图像进行缩小时为了避免出现波纹现象推荐采用INTER_AREA 区域插值方法
  • OpenCV推荐:如果要缩小图像通常推荐使用#INTER_AREA插值效果最好而要放大图像通常使用INTER_CUBIC(速度较慢但效果最好)或者使用INTER_LINEAR(速度较快效果还可以)至于最近邻插值INTER_NEAREST一般不推荐使用

相关文章

猜您喜欢

  • Java 分布式服务的调用链跟踪 Java 实现分布式服务的调用链跟踪

    想了解Java 实现分布式服务的调用链跟踪的相关内容吗果果果果果在本文为您仔细讲解Java 分布式服务的调用链跟踪的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java,分布式服务,分布式服务的调用链跟踪下面大家一起来学习吧..
  • Java中为什么String不可变 分析Java中为什么String不可变

    想了解分析Java中为什么String不可变的相关内容吗烟花散尽13141在本文为您仔细讲解Java中为什么String不可变的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java,String,String,不可变下面大家一起来学习吧..

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式