2018-11-16 21:46:42 qq_40961463 阅读数 325
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20576 人正在学习 去看看 夏曹俊

数字图像处理之双线性插值

MASK R-CNN中很重要的一个改进是ROIAlign,ROIAlign使用了双线性插值运算避免了之前ROI运算的两次量化操作,从而提高对检测框的预测。这里就对双线性插值做一个简单的介绍。

线性插值

讲双线性插值之前先介绍一下线性插值。已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反之亦然):
yy0xx0=y1y0x1x0 \frac{y - y_0}{x - x_0} = \frac{y_1 - y_0}{x_1 - x_0}
由此得
y=x1xx1x0y0+xx0x1x0y1y = \frac{x_1 - x}{x_1 - x_0}y_0 +\frac{x - x_0}{x_1 - x_0}y_1
线性插值的几何意义:用过两插值节点的直线近似原函数,通过近似代替原函数、插值得到数值。

双线性插值

双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。
在这里插入图片描述
已知的红色数据点与待插值得到的绿色点,我们把这些点上的值看作是图像上的像素点,假如我们想得到未知函数 f 在点P= (x,y) 的值,假设我们已知函数f在Q11 = (x1,y1),Q12 = (x1,y2), Q21 = (x2,y1) 以及Q22 = (x2,y2) 四个点的值。首先在x方向进行线性插值,得到R1和R2.
在这里插入图片描述
在这里插入图片描述
然后在y方向进行线性插值,得到P.
在这里插入图片描述
这样就得到所要的结果f(x,y).

2019-05-08 18:51:08 zhiwei121 阅读数 174
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20576 人正在学习 去看看 夏曹俊

引用的文章:http://blog.csdn.net/xjz18298268521/article/details/51220576
https://blog.csdn.net/qq_37577735/article/details/80041586

双线性插值,又称为双线性内插。在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值。

示例:已知的红色数据点与待插值得到的绿色点
假如我们想得到未知函数f在点P= (x,y) 的值,假设我们已知函数f在Q11 = (x1,y1)、Q12 = (x1,y2),Q21 = (x2,y1) 以及Q22 = (x2,y2) 四个点的值。

在这里插入图片描述

首先在x方向进行线性插值,得到R1和R2,

在这里插入图片描述
然后在y方向进行线性插值,得到P.

在这里插入图片描述

这样就得到所要的结果f(x,y).

在这里插入图片描述

其中红色点Q11,Q12,Q21,Q22为已知的4个像素点.

第一步:X方向的线性插值,在Q12,Q22中插入蓝色点R2,Q11,Q21中插入蓝色点R1;
第二步 :Y方向的线性插值 ,通过第一步计算出的R1与R2在y方向上插值计算出P点。

线性插值的结果与插值的顺序无关。首先进行y方向的插值,然后进行x方向的插值,所得到的结果是一样的。双线性插值的结果与先进行哪个方向的插值无关。

由于图像双线性插值只会用相邻的4个点,因此上述公式的分母都是1。

如果选择一个坐标系统使得 的四个已知点坐标分别为 (0, 0)、(0, 1)、(1, 0) 和 (1, 1),那么插值公式就可以化简为
f(x,y)=f(0,0)(1-x)(1-y)+f(1,0)x(1-y)+f(0,1)(1-x)y+f(1,1)xy。

写成矩阵形式就是

			1-x           x
	1-y    f(0,0)      f(1,0)
	y      f(0,1)       f(1,1)
				
例如,I(1.2,4.5)就是非整数的像素值,它的二维线性插值就是

               1-xx       xx
       1-yy   I(1,4)    I(1,5)
       yy     I(2,4)    I(2,5)

其中,xx为小数部分,此例中,xx=0.2, I(x,y)表示(y,x)处的像素值

2019-06-06 18:04:52 weixin_44650248 阅读数 360
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20576 人正在学习 去看看 夏曹俊

函数用法:cv2.resize( img, size, interpolation=… )

插值法是图像处理中最常用的图像缩放方法,插值法中最常用的是双线性插值(即INTER_LINEAR ),其缩放原理就不一一论述了。涉及较多的图像处理知识,有兴趣的可以多多查阅文献。

interpolation 选项 所用的插值方法
INTER_NEAREST 最近邻插值
INTER_LINEAR 双线性插值(默认设置)
INTER_AREA 使用像素区域关系进行重采样。 它可能是图像抽取的首选方法,因为它会产生无云纹理的结果。 但是当图像缩放时,它类似于INTER_NEAREST方法
INTER_CUBIC 4x4像素邻域的双三次插值
INTER_LANCZOS4 8x8像素邻域的Lanczos插值
2020-03-04 14:16:43 qq_41140138 阅读数 193
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20576 人正在学习 去看看 夏曹俊

一、插值与图像缩放

  首先举个例子说明插值过程,先看看matlab的插值函数 interp() 吧:

x = -2 : 1 : 2;
y = -2 : 1 : 2;
[X, Y] = meshgrid(x, y);
Z = -X.^2 - Y.^2;

p = -2 : 0.33 : 2;
q = -2 : 0.33 : 2;
[P, Q] = meshgrid(p, q);
V1 = interp2(X, Y, Z, P, Q, 'nearest'); % 最邻近插值
V2 = interp2(X, Y, Z, P, Q, 'linear'); % 双线性插值
V3 = interp2(X, Y, Z, P, Q, 'spline'); % 球面插值

figure
subplot(221)
surf(X, Y, Z);
colormap('autumn')
title('z = x^2 + y^2')

subplot(222)
surf(P, Q, V1);
colormap('autumn')
title('z = x^2 + y^2,最邻近插值')

subplot(223)
surf(P, Q, V2);
colormap('autumn')
title('z = x^2 + y^2,是双线性插值')

subplot(224)
surf(P, Q, V3);
colormap('autumn')
title('z = x^2 + y^2,球面插值')

我们先绘制一个粗糙的曲面,然后通过不同的方式插入一些点,得到的图像如下:
在这里插入图片描述
  可见,不同的插值效果不一样,图一很粗糙,绘图点数少,图二为最邻近插值,得到类似 ‘阶跃’ 的效果,而图三图四的曲面过去看起来更加圆滑。类比到图像,使用最邻近插值得到的图像相当于把像素点放大了,而使用双线性插值和球面插值相当于让图像像素点之间过度更加平滑。



二、最近邻插值

1、原理

最近邻插值,是将距离目标点最近的像素点的值作为插值的值
在这里插入图片描述
  如图为将一张MxN的图像src放大到PxQ的图像dst,我们要创建一个新的PXQ的数组,像素点中随便取一个点A(i, j),假设我们使用的灰度图,那么A点的灰度值应该是多少呢?
  首先我们把P点的坐标映射到原图像中(不知道说映射贴不贴切 😂),假设是B点,那么我们可以类比相似三角形的相似性质计算出B点的坐标(x, y):(x, y) = (M/P*i, N/Q*j)
由于数组的索引只能是整数,所以需要将x和y化为整数,使用最近邻插值时,我们可以四舍五入:

x = round(M/P*i);
y = round(N/Q*j));
dst(i, j) = src(x, y);

  于是我们得到了计算新图像每个像素点灰度值的方法,来一个循环就可以构建新图像。(对于rgb类型的图像,我们可以使用矩阵运算,一次性对rgb三个分量进行插值)


2、代码实现

话不多说,我们看看代码效果吧~
注意: 代码的第十行 dst = zeros(row, col, color, class(src)); 创建了一个row*col的彩色图像,类型是uint8

clear all
src = imread('lena_color_256.tif');

ratio = 3;
[row, col, color] = size(src);
row = round(ratio * row);
col = round(ratio * col);

% 生成新的图片
dst = zeros(row, col, color, class(src));

for i = 1 : row
    for j = 1 : col
        x = round(i / ratio);
        y = round(j / ratio);
        if x == 0
            x = x + 1;
        end
        if y == 0
            y = y + 1;
        end
        dst(i, j, : ) = src(x, y, :);
    end
end

figure
imshow(src)
figure
imshow(dst)

原图像为256x256的彩色图像:
在这里插入图片描述
使用最邻近插值后变成大小为768x768的彩色图(建议点击放大观察):
在这里插入图片描述



三、双线性插值

1、原理

  双线性插值不是只考虑距离最近的像素点,而是考虑周围四个像素点的加权值
在这里插入图片描述
  如图,假设ABCD均为相邻的像素点,而(x, y)落在中间
  插值时考虑距离的影响,离像素点越远,则权值越小,比如说图中的A点,考虑到ABCD为边长为1的正方形,可以用(1-dx)(1-dy)表示A点灰度值的权值(详细的证明可以参考大佬的博客),其中dx和dy分别表示x和y方向的距离
  假设ABCD处的灰度分别是a, b, c和d,于是我们可以得到(x, y)处的灰度应该是:
intensity=(1dx)(1dy)a+(1dx)dyb+dx(1dy)c+dxdyd) intensity = (1-dx)(1-dy)a + (1-dx)dy b + dx(1-dy) c + dxdy d)
  在matlab中,ABCD的坐标可以勇敢取整函数来获得,注意在matlab中,图像的数组从1开始,应该用向上取整,并且考虑数组越界

设 A(x1, y1), B(x1, y2), C(x2, y1), D(x2, y2)

x1 = ceil(M/P*i);
y1 = ceil(N/Q*j);
x2 = ceil(M/P*i) + 1;
y2 = ceil(N/Q*j) + 1;

2、代码实现

原图像为256x256的彩色,使用双线性插值:
需要注意的点

  • 数组越界判断
  • 图像下标是从1开始的,所以直接使用向上取整
clear all
src = imread('lena_color_256.tif');

ratio = 3;
[row, col, color] = size(src);
row = round(ratio * row);
col = round(ratio * col);

% 生成新的图片
dst = zeros(row, col, color, class(src));

for i = 1 : row
    for j = 1 : col
        x = i / ratio;
        y = j / ratio;
        x1 = ceil(x);         % 向上取整
        y1 = ceil(y);
        x2 = ceil(x) + 1;
        y2 = ceil(y) + 1;
        if x2 >= size(src, 1)           % 溢出检查
            x2 = x2 - 1;
        end
        if y2 >= size(src, 2)
            y2 = x2 - 1;
        end
        du = (x+1) - x1;
        dv = (y+1) - y1;
        dst(i, j, :) = (1-du)*(1-dv)*src(x1, y1, :) + (1-du)*dv*src(x1, y2, :) + du*(1-dv)*src(x2, y1, :) + du*dv*src(x2, y2, :);
    end
end

figure
imshow(src)
figure
imshow(dst)

结果为768x768的图像(建议点击放大观察):
在这里插入图片描述

注意对比两种插值方式的差别

  • 使用最近邻插值得到的图像由于相邻像素点的值可能一样,所以图像类似加上了马赛克,可以类比函数interp2对曲面的插值效果
  • 使用双线性插值法得到的图像看起来更光滑,但是由于双线性插值后,图像失去了部分高频成分,所以图像看起来有点模糊

完结 🍻~
发现数字图像处理还是很有趣的 ( ̄︶ ̄)↗

没有更多推荐了,返回首页