opencv-resize()放缩函数简介

本文详细介绍了OpenCV中的图像缩放函数resize()及其参数设置,并通过实例演示了如何使用此函数进行图像的放大与缩小。此外,还深入探讨了三种不同的插值方法:最近邻插值、双线性插值和三次插值,对比了它们的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要介绍函数resize();

图像缩放的效果图如下:

主程序代码及函数解释如下所示:

  1. /************************************************************************/  
  2. /*  
  3. OpenCV图像缩放使用的函数是:resize 
  4. void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR ) 
  5. 参数含义: 
  6. InputArray src     -原图像 
  7. OutputArray dst    -输出图像 
  8. Size dsize         -目标图像的大小 
  9. double fx=0        -在x轴上的缩放比例 
  10. double fy=0        -在y轴上的缩放比例 
  11. int interpolation  -插值方式,有以下四种方式 
  12.  
  13. INTER_NEAREST      -最近邻插值 
  14. INTER_LINEAR  -双线性插值 (缺省使用) 
  15. INTER_AREA    -使用象素关系重采样,当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 INTER_NN 方法。 
  16. INTER_CUBIC   -立方插值。 
  17.  
  18. 说明:dsize与fx和fy必须不能同时为零 
  19. */  
  20. /************************************************************************/  
  21. #include <opencv2\opencv.hpp>  
  22. #include <opencv2\imgproc\imgproc.hpp>  
  23.   
  24. using namespace cv;  
  25.   
  26. int main()  
  27. {  
  28.     //读入图像  
  29.     Mat srcImage=imread("1.jpg");  
  30.     Mat temImage,dstImage1,dstImage2;  
  31.     temImage=srcImage;  
  32.   
  33.     //显示原图  
  34.     imshow("原图",srcImage);  
  35.   
  36.     //尺寸调整  
  37.     resize(temImage,dstImage1,Size(temImage.cols/2,temImage.rows/2),0,0,INTER_LINEAR);  
  38.     resize(temImage,dstImage2,Size(temImage.cols*2,temImage.rows*2),0,0,INTER_LINEAR);  
  39.   
  40.     imshow("缩小",dstImage1);  
  41.     imshow("放大",dstImage2);  
  42.   
  43.     waitKey();  
  44.     return 0;  
  45.   
  46. }                      


    1、最邻近元法

      这是最简单的一种插值方法,不需要计算,在待求象素的四邻象素中,将距离待求象素最近的邻象素灰度赋给待求象素。设i+u, j+v(i, j为正整数, u, v为大于零小于1的小数,下同)为待求象素坐标,则待求象素灰度的值 f(i+u, j+v) 如下图所示:

     

     

    如果(i+u, j+v)落在A区,即u<0.5, v<0.5,则将左上角象素的灰度值赋给待求象素,同理,落在B区则赋予右上角的象素灰度值,落在C区则赋予左下角象素的灰度值,落在D区则赋予右下角象素的灰度值。

    最邻近元法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。

     

    2、双线性内插法

    双线性内插法是利用待求象素四个邻象素的灰度在两个方向上作线性内插,如下图所示:

     

     

    对于 (i, j+v),f(i, j) 到 f(i, j+1) 的灰度变化为线性关系,则有:

          f(i, j+v) = [f(i, j+1) - f(i, j)] * v + f(i, j)

    同理对于 (i+1, j+v) 则有:

                      f(i+1, j+v) = [f(i+1, j+1) - f(i+1, j)] * v + f(i+1, j)

    从f(i, j+v) 到 f(i+1, j+v) 的灰度变化也为线性关系,由此可推导出待求象素灰度的计算式如下:

                      f(i+u, j+v) = (1-u) * (1-v) * f(i, j) + (1-u) * v * f(i, j+1) + u * (1-v) * f(i+1, j) + u * v * f(i+1, j+1)

    双线性内插法的计算比最邻近点法复杂,计算量较大,但没有灰度不连续的缺点,结果基本令人满意。它具有低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊。

     

    3、三次内插法

    该方法利用三次多项式S(x)求逼近理论上最佳插值函数sin(x)/x, 其数学表达式为:

    待求像素(x, y)的灰度值由其周围16个灰度值加权内插得到,如下图:

     

     

    待求像素的灰度计算式如下:

     

    f(x, y) = f(i+u, j+v) = ABC

     

    其中: 

     

    三次曲线插值方法计算量较大,但插值后的图像效果最好。

转载于:https://www.cnblogs.com/invisible2/p/9191119.html

OpenCV for Android中的OCL(OpenCL)模块中,使用`cv::resize`函数需要通过将其转换为OpenCL算子(kernel)来进行并行处理。以下是完整的过程: 1. **包括头文件**: 首先,在OpenCL支持的源代码中,包含必要的头文件,如`opencv2/core.hpp` 和 `opencv2/core/ocl.hpp`。 ```cpp #include <opencv2/core.hpp> #include <opencv2/core/ocl.hpp> ``` 2. **检查设备支持**: 使用`cv::ocl::haveOpenCL()`检查当前设备是否支持OpenCL,以及`cv::ocl::device::getDefaultDevice().useOpenCL()`确认设备是否启用OpenCL。 ```cpp if (cv::ocl::haveOpenCL() && cv::ocl::device::getDefaultDevice().useOpenCL()) { // 接下来的代码将在OCL上运行 } else { std::cerr << "OpenCL is not supported or disabled on this device." << std::endl; return; } ``` 3. **准备输入和输出缓冲区**: 创建OpenCL的输入和输出图像,它们应该是`cv::UMat`类型,因为它们可以直接映射到设备内存。 ```cpp cv::UMat srcImage = ...; // 输入图像 cv::UMat dstImage; // 输出图像,大小由resize参数确定 ``` 4. **创建Resize算子**: 在OpenCL代码中,你需要编写一个自定义的`resize` kernel。这通常涉及到声明、定义和设置这个kernel。例如: ```cpp const char* resizeKernel = "#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable\n" "__kernel void resize(__global uchar *src,\n" " __global uchar *dst,\n" " const int dW,\n" " const int dH,\n" " const int sW,\n" " const int sH)\n" "{\n" " int2 gid = get_global_id(0); // 获取线程ID // 这里会有一个根据gid计算目标位置和放缩因子的实际算法 "}"; ``` 5. **构建和加载kernel**: 使用`cv::ocl::Program`将上述kernel编译成程序,并获取`resize`函数的运行指针。 ```cpp cv::ocl::Program program = cv::ocl::Program(srcDevice, resizeKernel); program.compile(); auto resizeFunction = program.getFunction("resize"); ``` 6. **分配工作队列和执行**: 创建一个工作队列,指定要使用的线程数,然后执行resize kernel。 ```cpp cv::ocl::Context context = srcDevice.getDefaultContext(); cv::ocl::CommandQueue queue(context, srcDevice); queue.enqueueNDRangeKernel(resizeFunction, cv::Range(0, numThreads), // numThreads取决于分辨率等 cv::Size(), cv::Size(dst.cols, dst.rows)); ``` 7. **等待完成和结果复制**: 等待命令队列执行完毕,然后从设备内存复制结果到CPU可用的`cv::UMat`。 ```cpp queue.wait(); queue.copyBufferToHost(dstImage.data, srcImage); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值