IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> OpenCV图像缩放插值之BiCubic双三次插值 -> 正文阅读

[人工智能]OpenCV图像缩放插值之BiCubic双三次插值

图像缩放算法简介

????????在图像的仿射变换中,很多地方需要用到插值运算,常见的插值运算包括最邻近插值,双线性插值,双三次插值(立体插值),兰索思插值等方法,OpenCV提供了很多方法,其中,双线性插值由于折中的插值效果和运算速度,运用比较广泛。双三次插值效果最好,但速度较慢。
????????OpenCV中实现图像缩放的函数为

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

????????参数说明:

  1. src:输入,原图像,即待改变大小的图像;

  2. dst:输出,改变大小之后的图像,这个图像和原图像具有相同的内容,只是大小和原图像不一样而已;

  3. dsize:输出图像的大小。如果这个参数不为0,那么就代表将原图像缩放到这个Size(width,height)指定的大小;如果这个参数为0,那么原图像缩放之后的大小就要通过下面的公式来计算:
    dsize = Size(round(fxsrc.cols), round(fysrc.rows))
    其中,fx和fy就是下面要说的两个参数,是图像width方向和height方向的缩放比例。
    fx:width方向的缩放比例,如果它是0,那么它就会按(double)dsize.width/src.cols来计算;
    fy:height方向的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算;

  4. interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:

    	INTER_NEAREST - 最邻近插值
    	INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
    	INTER_AREA - 区域插值
    		resampling using pixel area relation.It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
    	INTER_CUBIC - 双三次插值,4x4像素邻域内的双立方插值
    	INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值
    

OpenCV中INTER_CUBIC算法原理

????????接下来讲一下INTER_CUBIC - 双三次插值的算法原理。
????????双三次插值算法是基于周围的4*4=16个像素点,通过计算16个像素点的权重,累积得到增加点的像素值。
????????算法流程如下:

  1. 假设源图像A大小为m * n,缩放K倍后的目标图像B的大小为M*N,即K=M/m;
  2. A的每一个像素点是已知的,B是未知的,我们想要求出目标图像B中每一像素点(X,Y)的值,必须先找出像素(X,Y)在源图像A中对应的像素(x,y);
  3. 再根据源图像A距离像素(x,y)最近的16个像素点作为计算目标图像B(X,Y)处像素值的参数;
  4. 利用BiCubic基函数求出16个像素点的权重,图B像素(x,y)的值就等于16个像素点的加权叠加。

????????根据比例关系x/X=m/M=1/K,我们可以得到B(X,Y)在A上的对应坐标为

					A(x,y)=A(X*(m/M),Y*(n/N))=A(X/K,Y/K)。

????????如图所示P点就是目标图像B在(X,Y)处对应于源图像A中的位置,P的坐标位置会出现小数部分,所以我们假设 P的坐标为P(x+u,y+v),其中x,y分别表示整数部分,u,v分别表示小数部分(蓝点P1到a11方格中红点的距离)。那么我们就可以得到如图所示的最近16个像素的位置,在这里用a(i,j)(i,j=0,1,2,3)来表示,如下图,图中方格为单个像素的尺寸,红点为像素中心。
图1
????????双立方插值的目的就是通过找到一种关系,或者说系数,可以把这 16 个像素对于 P 处像素值的影响因子找出来,从而根据这个影响因子来获得目标图像对应点的像素值,达到图像缩放的目的。
????????BiCubic基函数形式如下
图2
????????BiCubic函数图像如下
图3
????????我们要做的就是求出BiCubic函数中的参数x,从而获得上面所说的16个像素所对应的权重W(x)
????????BiCubic基函数是一维的,而像素是二维的,所以我们将像素点的行与列分开计算。
????????BiCubic函数中的参数x表示该像素点到P点的距离.
????????例如a00距离P(x+u,y+v)的距离为(1+u,1+v),因此a00的纵坐标权重i_0=W(1+v),横坐标权重j_0=W(1+u),a00对B(X,Y)的贡献值为:

				(a00像素值)* i_0* j_0。

因此,a0X的横坐标权重分别为W(1+u),W(u),W(1-u),W(2-u);ay0的纵坐标权重分别为W(1+v),W(v),W(1-v),W(2-v);B(X,Y)像素值为:
图4

CUBIC算法C语言实现

// im-原图指针	w-原图宽		h-原图高
// s_im-目标图像指针		w-目标图像宽		h-目标图像高
const int ErrorCode_imdataProc =-1000000;
int vcImageSimpleSamplingRoi(unsigned char * im, int w, int h, 
	unsigned char * s_im, int s_w, int s_h)
{
	int ret = 0;

	float fWStep = 0.0f, fHStep = 0.0f;

	int ii = 0, jj = 0;

	unsigned char * pCurr = 0;
	unsigned char * pSamp = 0;
	
	const float A = -0.75f;
	float coeffsX[4], coeffsY[4];
	float fx = 0.0f, fy = 0.0f;
	int sx = 0, sy = 0, iscale_x = 0, iscale_y = 0;
	short cbufX[4], cbufY[4];
	int sum = 0;
	int mm = 0, nn = 0;
	
	if (NULL == im || w <= 0 || h <= 0 ||
		NULL == s_im || s_w <= 0 || s_h <= 0) {
		ret = ErrorCode_imdataProc - 4;
		goto nExit;
	}

	fWStep = 1.0f * roi.width / s_w;
	fHStep = 1.0f * roi.height / s_h;
	pSamp = s_im;

	for (ii = 0; ii < s_h; ++ii)
	{
		fy = (float)((ii + 0.5)*fHStep - 0.5);
		sy = vcFloor(fy);
		fy -= sy;

		if (sy < 1){
			fy = 0, sy = 1;
		}

		if (sy >= s_h - 3){
			fy = 0, sy = s_h - 3;
		}

		coeffsY[0] = ((A*(fy + 1) - 5*A)*(fy + 1) + 8 * A)*(fy + 1) - 4 * A;
		coeffsY[1] = ((A + 2)*fy - (A + 3))*fy*fy + 1;
		coeffsY[2] = ((A + 2)*(1 - fy) - (A + 3))*(1 - fy)*(1 - fy) + 1;
		coeffsY[3] = 1.f - coeffsY[0] - coeffsY[1] - coeffsY[2];

		cbufY[0] = (short)(coeffsY[0] * 2048);
		cbufY[1] = (short)(coeffsY[1] * 2048);
		cbufY[2] = (short)(coeffsY[2] * 2048);
		cbufY[3] = (short)(coeffsY[3] * 2048);

		for (jj = 0; jj < s_w; ++jj)
		{
			fx = (float)((jj + 0.5)*fWStep - 0.5);
			sx = vcFloor(fx);
			fx -= sx;

			if (sx < 1){
				fx = 0, sx = 1;
			}

			if (sx >= s_w - 3){
				fx = 0, sx = s_w - 3;
			}
			
			coeffsX[0] = ((A*(fx + 1) - 5*A)*(fx + 1) + 8*A)*(fx + 1) - 4*A;
			coeffsX[1] = ((A + 2)*fx - (A + 3))*fx*fx + 1;
			coeffsX[2] = ((A + 2)*(1 - fx) - (A + 3))*(1 - fx)*(1 - fx) + 1;
			coeffsX[3] = 1.f - coeffsX[0] - coeffsX[1] - coeffsX[2];
			
			cbufX[0] = (short)(coeffsX[0] * 2048);
			cbufX[1] = (short)(coeffsX[1] * 2048);
			cbufX[2] = (short)(coeffsX[2] * 2048);
			cbufX[3] = (short)(coeffsX[3] * 2048);

			sum = 0;
			for (mm = 0; mm < 4; ++mm)//rows
			{
				pCurr = im + (roi.y + sy + mm - 1) * w + roi.x;
				for (nn = 0; nn < 4; ++nn)//cols
				{
					sum += pCurr[sx + nn - 1] * cbufY[mm]*cbufX[nn];
				}
			}
			pSamp[jj] = sum >> 22;
		}
		pSamp += s_w;
	}

	ret = 1;
nExit:
	return ret;
}

结语

????????以上为OpenCV图像缩放插值之BiCubic双三次插值的原理及实现。如还有不懂,可参考下面的参考链接,都是很不错的文章。
参考链接:

  1. OpenCV中resize函数五种插值算法的实现过程
  2. OpenCV ——双线性插值(Bilinear interpolation)
  3. C++ OpenCV实现图像双三次插值算法详解
  4. 双三次插值(BiCubic插值)
  5. 图像插值算法之双三次插值
  6. BiCubic Interpolation
  7. OpenCV图像缩放resize各种插值方式的比较
  8. aitken插值方法的c++代码_双三次插值算法的C++实现与SSE指令优化

????????如果觉得本文写的不错的,欢迎点赞、收藏、评论哦~

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:02:58  更:2022-04-01 00:03:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:49:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码