OpenCV + CPP 系列(十三)插值算法 与 图像缩放

一、插值算法

由于图片存储的时候其实就是一个矩阵,所以在对图像进行缩放操作的时候,也就是在对矩阵进行操作。如果想要将图片放大,这里我们就需要用到过采样算法来扩大矩阵,利用欠采样来缩小图像。

opencv 官网关于插值算法介绍:InterpolationFlags
https://docs.opencv.org/master/d7/da8/tutorial_table_of_content_imgproc.html
在这里插入图片描述

最近邻插值(Nearest Interpolation)

黑色的×表示需要插入的值,它会选择距离它最近的 P ( x + 1 , y ) P_{(x+1,y)} P(x+1,y)的值来作为它的值。当插入的值距离四个点都相等时,会选择距离最近的左上角的值。

在这里插入图片描述

线性插值(Linear interpolation)

这里的线性插值其实是指双线性插值,这种插值算法也是resize函数中默认使用的插值算法。
假设我们已知坐标 ( x 0 , y 0 ) (x_0 , y_0) (x0,y0) ( x 1 , y 1 ) ( x_1 , y_1 ) (x1,y1),我们想要得到在区间 [ x 0 , x 1 ] [x_0,x_1] [x0,x1] 上任意位置 x 所对应y的值,如下图所示

其实 P 点的值等于周围四个点( Q 12 , Q 22 , Q 11 , Q 21 Q_{12}, Q_{22}, Q_{11}, Q_{21} Q12,Q22,Q11,Q21)与P点所构成的四个对角矩形面积的加权平均。
在这里插入图片描述

在这里插入图片描述

双三次插值(Bicubic interpolation)

双三次插值是一种更加复杂的插值算法,是二维空间中最常用的插值算法,相对双线性插值的图像边缘更加平滑,函数 f f f 在点 ( x , y ) (x,y) (x,y)的值可以通过矩形网格中最近的十六个采样点的加权平均得到,这里需要使用两个多项式插值三次函数,每个方向使用一个。

双三次插值常用的BiCubic函数如下图
在这里插入图片描述

区域插值(Area interpolation)

区域插值算法主要分两种情况,缩小图像和放大图像的工作原理并不相同。

  • 缩小图像
    如果图像缩小的比例是整数倍,在调用INTER_LINEAR_EXACT插值算法时,
    如果图像的宽和高的缩小比例都是2,而且图像的通道数不是2,实际上会调用INTER_AREA。在调用INTER_LINEAR时,如果图像的宽和高的缩小比例都是2,实际上是会调用INTER_AREA。
    INTER_AREA实际上是个box filter,类似于均值滤波器。
  • 放大图像
    如果放大图像的比例是整数倍,与最近邻插值相似。
    如果放大的比例不是整数倍,则会采用线性插值。
Lanczos插值

Lanczos插值属于一种模板算法,需要通过计算模板中的权重信息来计算 x对应的值。
对于一维信息,假如我们输入的点集为 X,那么,Lanczos对应有个窗口模板Window,窗口中每个位置的权重计算如下:
在这里插入图片描述

插值算法耗时比较

在这里插入图片描述

二、图像缩放

头文件 quick_opencv.h:声明类与公共函数

#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
	...
	void resize_Demo(Mat& image);
};

主函数调用该类的公共成员函数

#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
	Mat src = imread("D:\\Desktop\\pandas.jpg");
	if (src.empty()) {
		printf("Could not load images...\n");
		return -1;
	}
	namedWindow("input", WINDOW_NORMAL);
	imshow("input", src);

	QuickDemo qk;

	...
	//qk.polyline_drawing_Demo();
	qk.resize_Demo(src);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

源文件 quick_demo.cpp:实现类与公共函数

void QuickDemo::resize_Demo(Mat& image) {
	Mat zoomin , zoomout;
	int h = image.rows;
	int w = image.cols;
	resize(image, zoomin, Size(w / 2, h / 2), 0, 0, INTER_LINEAR);        //缩小1倍
	resize(image, zoomout, Size(w * 1.5, h * 1.5), 0, 0, INTER_LINEAR);   //放大1.5倍
	imshow("zoomin", zoomin);
	imshow("zoomout", zoomout);
}

从左至右:缩小、原图、放大
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongpingWang

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值