Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法


系列文章
Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法
Python+OpenCV图像处理(二)——几何变换
Python+OpenCV图像处理(三)——彩色空间互换
Python+OpenCV图像处理(四)——图像滤波
Python+OpenCV图像处理(五)——图像阈值和二值化
Python+OpenCV图像处理(六)——边缘检测

目录

  • 图像处理
    • 一、OpenCV框架与图像插值算法
      • 1.1 OpenCV简介
      • 1.2 图像插值算法
        • 1.2.1 最近邻插值:
        • 1.2.2双线性插值:
      • 1.3 向前映射与向后映射
      • 1.4 resize函数
      • 1.5 代码实现


图像处理

图像处理(image processing),用计算机对图像进行分析,以达到所需结果的技术。数字图像是指用工业相机、摄像机、扫描仪等设备经过拍摄得到的一个大的二维数组,该数组的元素称为像素,其值称为灰度值。图像处理技术一般包括图像压缩,增强和复原,匹配、描述和识别3个部分。

一、OpenCV框架与图像插值算法

1.1 OpenCV简介

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

环境配置为:win7+python3.6+numpy1.14.2+opencv-python3.4.1

安装opencv-python3.4.1

首先去网站下载OpenCV对应的.whl版本压缩包,网址https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv本人下载的版本是:opencv_python‑3.4.1‑cp36‑cp36m‑win_amd64.whl 64位系统对应python3.6的

百度云链接:https://pan.baidu.com/s/10RefansrC4_0zsNehjyKTg

pip install opencv_python-3.4.1-cp36-cp36m-win_amd64.whl

导入OpenCV

import cv2

验证是否环境已配置好

print(cv2.__version__)

输出:3.4.1

1.2 图像插值算法

在图像经过空间位置变换之后,需要求取在新平面的新排列的各点像素的位置,其并不会改变映射前后的像素的像素值。这种空间位置变换通常包含缩放、平移与旋转等。

其中常见的图像插值算法有最近邻插值、双线性插值和三次样条插值。

ps:markdown格式的公式书写现在还不熟练,这里把重点放到利用opencv库对算法的调用实现上,只对算法进行简单地描述,算法原理暂时用图代替。


1.2.1 最近邻插值:

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

Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第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(dstWidthdstXsrcWidth,dstHeightdstYsrcHeight)

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)...

Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第2张图片

缺点:
用该方法作放大处理时,在图象中可能出现明显的块状效应,有点像打了马赛克一样。

Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第3张图片

1.2.2双线性插值:

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

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

Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第4张图片

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+(xx0)x1x0y1y0=y0+x1x0(xx0)y1(xx0)y0

对于图像来说,都是二维的,故只需做推广即可,即双线性插值就是线性插值在二维时的推广,在两个方向上做三次线性插值,具体操作如下图所示:

Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第5张图片

  令 f ( x , y ) f(x,y) f(xy)为两个变量的函数,其在单位正方形顶点的值已知。假设我们希望通过插值得到正方形内任意点的函数值。则可由双线性方程:
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.3 向前映射与向后映射

向前映射法:

这种方法是从输入图像计算输出图像的对应坐标。可以将几何运算想象成一次一个像素地转移到输出图象中。如果一个输入像素被映射到四个输出像素之间的位置,则其灰度值就按插值算法在4个输出像素之间进行分配,称为向前映射法,或像素移交映射。对于平移变换,由于不进行放缩和旋转,故这种方法就非常便捷。

向后映射法:

这种方法和向前映射相反,是从输出图像计算输入图像的对应坐标。向后映射法,也叫像素填充法,是输出像素一次一个地映射回到输入像素中,以便确定其灰度级。如果一个输出像素被映射到4个输入象素之间,则其灰度值插值决定,向后空间变换是向前变换的逆,即互为逆运算。

1.4 resize函数

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

参数说明:

src - 原图
desize - 输出的图像大小
fx - 沿水平轴的比例因子
fy - 沿垂直轴的比例因子
interpolation - 插值方式

插值方式:

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

一般,缩小用cv2.INTER_AREA ,放缩使用cv2.INTER_LINEAR(较快)和cv2.INTER_CUBIC(较慢)。默认使用cv2.INTER_LINEAR。

1.5 代码实现

#%%

import cv2


if __name__ == "__main__":
    img = cv2.imread('test_01.jpg', cv2.IMREAD_UNCHANGED)
     
    print('Original Dimensions : ',img.shape)

    scale_percent = 30       # percent of original size
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    # resize image
    resized = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)

    fx1 = 1.5
    fy1 = 1.5
    fx2 = 0.7
    fy2 = 0.7

    resized1 = cv2.resize(resized, dsize=None, fx=fx1, fy=fy1, interpolation = cv2.INTER_NEAREST)

    resized2 = cv2.resize(resized, dsize=None, fx=fx1, fy=fy1, interpolation = cv2.INTER_LINEAR)
    
    resized3 = cv2.resize(resized, dsize=None, fx=fx1, fy=fy1, interpolation = cv2.INTER_CUBIC)
    
    resized4 = cv2.resize(resized, dsize=None, fx=fx2, fy=fy2, interpolation = cv2.INTER_AREA)

    print('Resized Dimensions : ',resized.shape)
    
    #cv2.imshow("original image", img)
    cv2.imshow("Resized image", resized)
    cv2.imshow("INTER_NEAREST image", resized1)
    cv2.imshow("INTER_LINEAR image", resized2)
    cv2.imshow("INTER_CUBIC image", resized3)
    cv2.imshow("INTER_AREA image", resized4)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

Original Dimensions : (1600, 2560, 3)
Resized Dimensions : (480, 768, 3)

0.3倍缩小,双线性插值
Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第6张图片
1.5倍放大,最近邻插值

1.5倍放大,双线性插值

1.5倍放大,基于4x4像素邻域的3次插值法

0.7倍缩小,基于局部像素的重采样
Python+OpenCV图像处理(一)——OpenCV框架与图像插值算法_第7张图片

你可能感兴趣的:(cv,计算机视觉,opencv,python)