现在的位置: 首页 > 综合 > 正文

图像双线性插值

2013年10月06日 ⁄ 综合 ⁄ 共 1390字 ⁄ 字号 评论关闭

在图像缩放中我们经常采用双线性插值的算法。要是针对缩放2倍这种特殊情况,实现起来就没有这么麻烦了,还可以直接抽取或者复制行和列。在复制行列的时候还有个实现的技巧,就是把目标图像的坐标除以2,得到原图像的坐标值,将源图像的像素值复制过来就行了。

//直接复制行列,将图像放大一倍
void PyrUp1( IplImage *orgImg, IplImage *destImg )
{
	const int widthStep = destImg->widthStep;
	for( int i = 0; i < destImg->height; ++i )
		for ( int j = 0; j < destImg->width; ++j )
		{
           int destImgPos = i * widthStep + j;
		   int orgImgPos = (i / 2 ) * (orgImg->widthStep) + j / 2;
		   destImg->imageData[destImgPos] = orgImg->imageData[orgImgPos];
		}
}

 对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v) (其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:

  f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)           
其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。

当图像放大两倍的时候,没有必要用这么复杂的公式了,下面的参考文献中有简化的计算方法。这里简单的贴下代码,没有考虑图像的边界值,直接跳过边界值。

//双线性插值,将orgImg图像放大一倍保存在destImg中
void PyrUp( IplImage *orgImg, IplImage *destImg )
{
	const int widthStep = destImg->widthStep;
	for( int i = 0; i < destImg->height -2; ++i )
		for ( int j = 0; j < destImg->width -2; ++j )
		{
			int destImgPos = i * widthStep + j;
			int orgImgPos = (i / 2 ) * (orgImg->widthStep) + j / 2;
			int count = orgImg->imageData[orgImgPos] + orgImg->imageData[orgImgPos +1 ]+
				        orgImg->imageData[orgImgPos+orgImg->widthStep]+orgImg->imageData[orgImgPos+orgImg->widthStep+1];
			destImg->imageData[destImgPos] = (uchar)(count/4);
		}

}

参考文献:

http://blog.csdn.net/qiqi5521/article/details/2207562

http://blog.csdn.net/jia20003/article/details/6915185

http://blog.csdn.net/Breathomn/article/details/3962711

抱歉!评论已关闭.