@(Aaron) [图像处理, 图像插值算法]

1.1 简介

  在图像处理中,平移变换、旋转变换以及放缩变换是一些基础且常用的操作。这些几何变换并不改变图象的象素值,只是在图象平面上进行象素的重新排列。在一幅输入图象 [ u , v ] [u,v] [u,v]中,灰度值仅在整数位置上有定义。然而,输出图象[x,y]的灰度值一般由处在非整数坐标上的 ( u , v ) (u,v) (u,v)值来决定。这就需要插值算法来进行处理,常见的插值算法有最近邻插值、双线性插值和三次样条插值。

1.2 学习目标

  • 了解插值算法与常见几何变换之间的关系
  • 理解插值算法的原理
  • 掌握OpenCV框架下插值算法API的使用

1.3 内容介绍

  1. 插值算法原理介绍

    • 最近邻插值算法
    • 双线性插值算法
  2. OpenCV代码实践
    • cv.resize()各项参数及含义
  3. 动手实现(由读者自己完成)

1.4 算法理论介绍与推荐

1.4.1 最近邻插值算法原理

  最近邻插值,是指将目标图像中的点,对应到源图像中后,找到最相邻的整数点,作为插值后的输出。

  如上图所示,目标图像中的某点投影到原图像中的位置为点P,此时易知, f ( P ) = f ( Q 11 ) f(P) = f(Q11) f(P)=f(Q11).

一个例子:

  如下图所示,将一幅3X3的图像放大到4X4,用 f ( x , y ) f(x, y) f(x,y)表示目标图像, h ( x , y ) h(x, y) h(x,y)表示原图像,我们有如下公式:

f ( d s t X , d s t Y ) = h ( d s t X s r c W i d t h d s t W i d t h , d s t Y s r c H e i g h t d s t H e i g h t ) \begin{array}{c} f(dst_{X}, dst_{Y}) = h(\frac{dst_{X}src_{Width}} {dst_{Width}}, \frac{dst_{Y}src_{Height}} {dst_{Height}}) \end{array} f(dstX​,dstY​)=h(dstWidth​dstX​srcWidth​​,dstHeight​dstY​srcHeight​​)​

f ( 0 , 0 ) = h ( 0 , 0 ) f ( 0 , 1 ) = h ( 0 , 0.75 ) = h ( 0 , 1 ) f ( 0 , 2 ) = h ( 0 , 1.50 ) = h ( 0 , 2 ) f ( 0 , 3 ) = h ( 0 , 2.25 ) = h ( 0 , 2 ) . . . \begin{array}{c} f(0,0)=h(0,0) \\ f(0,1)=h(0,0.75)=h(0,1) \\ f(0,2)=h(0,1.50)=h(0,2) \\ f(0,3)=h(0,2.25)=h(0,2) \\ ...\\ \end{array} f(0,0)=h(0,0)f(0,1)=h(0,0.75)=h(0,1)f(0,2)=h(0,1.50)=h(0,2)f(0,3)=h(0,2.25)=h(0,2)...​

缺点:
用该方法作放大处理时,在图象中可能出现明显的块状效应

1.4.2 双线性插值

  在讲双线性插值之前先看以一下线性插值,线性插值多项式为:

f ( x ) = a 1 x + a 0 f(x)=a_{1} x+a_{0} f(x)=a1​x+a0​

y = y 0 + ( x − x 0 ) y 1 − y 0 x 1 − x 0 = y 0 + ( x − x 0 ) y 1 − ( x − x 0 ) y 0 x 1 − x 0 y=y_{0}+\left(x-x_{0}\right) \frac{y_{1}-y_{0}}{x_{1}-x_{0}}=y_{0}+\frac{\left(x-x_{0}\right) y_{1}-\left(x-x_{0}\right) y_{0}}{x_{1}-x_{0}} y=y0​+(x−x0​)x1​−x0​y1​−y0​​=y0​+x1​−x0​(x−x0​)y1​−(x−x0​)y0​​

  双线性插值就是线性插值在二维时的推广,在两个方向上做三次线性插值,具体操作如下图所示:

  令 f ( x , y ) f(x,y) f(x,y)为两个变量的函数,其在单位正方形顶点的值已知。假设我们希望通过插值得到正方形内任意点的函数值。则可由双线性方程:
f ( x , y ) = a x + b y + c x y + d f(x, y)=a x+b y+c x y+d f(x,y)=ax+by+cxy+d

  来定义的一个双曲抛物面与四个已知点拟合。

  首先对上端的两个顶点进行线性插值得:

f ( x , 0 ) = f ( 0 , 0 ) + x [ f ( 1 , 0 ) − f ( 0 , 0 ) ] f(x, 0)=f(0,0)+x[f(1,0)-f(0,0)] f(x,0)=f(0,0)+x[f(1,0)−f(0,0)]

  类似地,再对底端的两个顶点进行线性插值有:
f ( x , 1 ) = f ( 0 , 1 ) + x [ f ( 1 , 1 ) − f ( 0 , 1 ) ] f(x, 1)=f(0,1)+x[f(1,1)-f(0,1)] f(x,1)=f(0,1)+x[f(1,1)−f(0,1)]

  最后,做垂直方向的线性插值,以确定:

f ( x , y ) = f ( x , 0 ) + y [ f ( x , 1 ) − f ( x , 0 ) ] f(x, y)=f(x, 0)+y[f(x, 1)-f(x, 0)] f(x,y)=f(x,0)+y[f(x,1)−f(x,0)]

  整理得:

f ( x , y ) = [ f ( 1 , 0 ) − f ( 0 , 0 ) ] x + [ f ( 0 , 1 ) − f ( 0 , 0 ) ] y + [ f ( 1 , 1 ) + f ( 0 , 0 ) − f ( 0 , 1 ) − f ( 1 , 0 ) ] x y + f ( 0 , 0 ) \begin{array}{l} f(x, y)=[f(1,0)-f(0,0)] x+[f(0,1)-f(0,0)] y \\ +[f(1,1)+f(0,0)-f(0,1)-f(1,0)] x y+f(0,0) \end{array} f(x,y)=[f(1,0)−f(0,0)]x+[f(0,1)−f(0,0)]y+[f(1,1)+f(0,0)−f(0,1)−f(1,0)]xy+f(0,0)​

1.4.3 映射方法

向前映射法

  可以将几何运算想象成一次一个象素地转移到输出图象中。如果一个输入象素被映射到四个输出象素之间的位置,则其灰度值就按插值算法在4个输出象素之间进行分配。称为向前映射法,或象素移交影射。

注:从原图象坐标计算出目标图象坐标镜像、平移变换使用这种计算方法

向后映射法

  向后映射法(或象素填充算法)是输出象素一次一个地映射回到输入象素中,以便确定其灰度级。如果一个输出象素被映射到4个输入象素之间,则其灰度值插值决定,向后空间变换是向前变换的逆。

注:从结果图象的坐标计算原图象的坐标

  • 旋转、拉伸、放缩可以使用
  • 解决了漏点的问题,出现了马赛克

1.5 基于OpenCV的实现

1.5.1 C++

函数原型:

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

src:输入图像
dst:输出图像
dsize:输出图像尺寸
fx、fy:x,y方向上的缩放因子
INTER_LINEAR:插值方法,总共五种1. INTER_NEAREST - 最近邻插值法2. INTER_LINEAR - 双线性插值法(默认)3. INTER_AREA - 基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。4. INTER_CUBIC - 基于4x4像素邻域的3次插值法5. INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos插值

代码实践:

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;int main(int argc, char* argv[])
{Mat img = imread("D:/image/yuner.jpg");if (img.empty()){cout << "无法读取图像" << endl;return 0;}int height = img.rows;int width = img.cols;// 缩小图像,比例为(0.2, 0.2)Size dsize = Size(round(0.2 * width), round(0.2 * height));Mat shrink;//使用双线性插值resize(img, shrink, dsize, 0, 0, INTER_LINEAR);// 在缩小图像的基础上,放大图像,比例为(1.5, 1.5)float fx = 1.5;float fy = 1.5;Mat enlarge1, enlarge2;resize(shrink, enlarge1, Size(), fx, fy, INTER_NEAREST);resize(shrink, enlarge2, Size(), fx, fy, INTER_LINEAR);// 显示imshow("src", img);imshow("shrink", shrink);imshow("INTER_NEAREST", enlarge1);imshow("INTER_LINEAR", enlarge2);waitKey(0);return 0;
}

原图

0.2倍缩小,双线性插值

1.5倍放大,最近邻插值

1.5倍放大,双线性插值

1.5.2 Python

函数原型:

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

参数:

参数 描述
src 【必需】原图像
dsize 【必需】输出图像所需大小
fx 【可选】沿水平轴的比例因子
fy 【可选】沿垂直轴的比例因子
interpolation 【可选】插值方式

插值方式:

cv.INTER_NEAREST 最近邻插值
cv.INTER_LINEAR 双线性插值
cv.INTER_CUBIC 基于4x4像素邻域的3次插值法
cv.INTER_AREA 基于局部像素的重采样

通常,缩小使用cv.INTER_AREA,放缩使用cv.INTER_CUBIC(较慢)和cv.INTER_LINEAR(较快效果也不错)。默认情况下,所有的放缩都使用cv.INTER_LINEAR。

代码实践:

import cv2if __name__ == "__main__":img = cv2.imread('D:/image/yuner.jpg', cv2.IMREAD_UNCHANGED)print('Original Dimensions : ',img.shape)scale_percent = 30       # percent of original sizewidth = int(img.shape[1] * scale_percent / 100)height = int(img.shape[0] * scale_percent / 100)dim = (width, height)# resize imageresized = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)fx = 1.5fy = 1.5resized1 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_NEAREST)resized2 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_LINEAR)print('Resized Dimensions : ',resized.shape)cv2.imshow("Resized image", resized)cv2.imshow("INTER_NEAREST image", resized1)cv2.imshow("INTER_LINEAR image", resized2)cv2.waitKey(0)cv2.destroyAllWindows()

0.3倍缩小,双线性插值

1.5倍放大,最近邻插值

1.5倍放大,双线性插值

  • 推荐书籍:学习OpenCV中文版
  • 推荐博客:https://blog.csdn.net/hongbin_xu/category_6936122.html

1.6 总结

  插值算法是很多几何变换的基础和前置条件,对插值算法细节的掌握有助于对其他算法的理解,为自己的学习打下坚实的基础。


Task01 OpenCV框架与图像插值算法 END.

By: Aaron

博客:https://sandy1230.github.io/

博客:https://blog.csdn.net/weixin_39940512

关于Datawhale

Datawhale是一个专注于数据科学与AI领域的开源组织,汇集了众多领域院校和知名企业的优秀学习者,聚合了一群有开源精神和探索精神的团队成员。Datawhale以“for the learner,和学习者一起成长”为愿景,鼓励真实地展现自我、开放包容、互信互助、敢于试错和勇于担当。同时Datawhale 用开源的理念去探索开源内容、开源学习和开源方案,赋能人才培养,助力人才成长,建立起人与人,人与知识,人与企业和人与未来的联结。

OpenCV框架与图像插值算法相关推荐

  1. 计算机视觉基础---OpenCV框架与图像插值算法(图像伸缩)cpp+python

    1.1 简介 在图像处理中,平移变换.旋转变换以及放缩变换是一些基础且常用的操作.这些几何变换并不改变图象的象素值,只是在图象平面上进行象素的重新排列.在一幅输入图象[u,v]中,灰度值仅在整数位置上 ...

  2. Datawhale 计算机视觉基础-图像处理(上)-Task01 OpenCV框架与图像插值算法

    简介 在图像处理中,平移变换.旋转变换以及放缩变换是一些基础且常用的操作.这些几何变换并不改变图象的象素值,只是在图象平面上进行象素的重新排列.在一幅输入图象 [ u , v ] [u,v] [u,v ...

  3. 一文讲解图像插值算法原理!附Python实现

    Datawhale学习 作者:姚童,Datawhale优秀学习者 寄语:本文梳理了最近邻插值法.双线性插值法和三次样条插值法的原理,并以图像缩放为例,对原理进行了C++及Python实现. 在图像处理 ...

  4. 转载:一文讲解图像插值算法原理

    最近在研究插值算法,看到这篇CSDN博主Datawhale学习介绍的博文,觉得介绍得挺不错,转载过来.原文地址:https://blog.csdn.net/Datawhale/article/deta ...

  5. opencv高效遍历图像

    初次接触OpenCV的开发者,必须过的第一道坎就是学会如何遍历访问Mat对象中每个像素,实现像素级别的图像操作,这个是最级别的编程技能,但是不同的像素遍历方法效率有云泥之别,相差特别大,甚至可能成为算 ...

  6. opencv学习(part1)--OpenCv框架介绍

    学习笔记,仅供参考,有错必究 文章目录 opencv学习 OpenCv框架介绍 二值图像分析 二值图像定义与说明 图像二值化介绍 常见的二分类分割方法 opencv学习 OpenCv框架介绍 Open ...

  7. OpenCV——高效遍历图像(C++版本)

    OpenCV遍历图像像素是很常见的事情,比较下面的三种遍历方式哪个是最高效的. 前言 在OpenCV C++中Mat对象的内存管理由OpenCV框架自动负责内存分配与回收,基于智能指针实现内存管理.M ...

  8. OpenCV——几种图像滤波总结(python实现和c++实现)

    OpenCV--图像滤波原理及实现 4.1 简介 图像的实质是一种二维信号,滤波是信号处理中的一个重要概念.在图像处理中,滤波是一种非常常见的技术,它们的原理非常简单,但是其思想却十分值得借鉴,滤波是 ...

  9. python贝塞尔插值公式_贝塞尔函数、Jinc函数与图像插值算法

    Jinc函数插值是一种传统的图像插值算法,可以用来进行图像缩放(即Jinc Resize).在传统的非机器学习图像超分辨率/放大算法中,Jinc Resize是效果较为出众的算法.虽然在传统神经网络和 ...

最新文章

  1. 我去!一周内,在闲鱼上被疯狂转了2.6万次的架构课程,现在免费!(限时领)...
  2. 5.11 程序示例--垃圾邮件检测-机器学习笔记-斯坦福吴恩达教授
  3. 133. Leetcode 477. 汉明距离总和 (位运算-汉明距离相关题目)
  4. jQuery入口函数的四种写法【1分钟掌握】
  5. javaScript学习笔记之break 和 continue 语句对比
  6. ajax post 提交无法进入controller 请求200
  7. WCDMA,CDMA2000,TD_SCDMA
  8. php禁用错误提示,php开启与关闭错误提示详解
  9. 知乎高赞:为什么许多原本的 Java 项目都试图用 go 进行重写开源?
  10. Python语音基础操作--2.4语音信号生成
  11. 《R数据科学》学习笔记|Note2:使用ggplot2进行数据可视化(上)
  12. 【技术公开课】iOS App研发的最后冲刺:内测与部署
  13. BeagleBone Black 从零到一 (2 MLO、U-Boot)_spl
  14. 谷医堂与日俱进!谷医堂优化产品和提升服务两不误
  15. 理解Session State模式+FAQ [翻译]
  16. 解决 React Hooks 的闭包陷阱
  17. UI设计:使用PS绘制拟物化图标
  18. d3.js读书笔记-2
  19. 人物素描如何把握尺寸大小_素描fu复制粘贴位置大小
  20. Dockerfile搭建wordpress论坛

热门文章

  1. 融云及时通讯 加入群聊
  2. 智能音箱 功放与喇叭选型 参考
  3. 整理一些简历制作、工作、面试、招聘网站资源分享
  4. NFA转变为DFA的子集构造法
  5. 华为产品总监谈投身互联网:要避免与腾讯竞争
  6. Latex数学公式方程格式总结
  7. 转:理想主义终结年代的七种兵器
  8. java assert int_java中的assert(转载)2
  9. matlab 三分之一倍频程,三分之一倍频程谱
  10. mac os 13 通过网线共享mac的(wifi)网络