2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 数字图像缩放之最近邻插值与双线性插值处理效果对比

数字图像缩放之最近邻插值与双线性插值处理效果对比

时间:2021-03-26 03:01:40

相关推荐

数字图像缩放之最近邻插值与双线性插值处理效果对比

基本原理:

1、最近邻插值:变换后的目标图像某点像素值等于源图像中与变换前相应点最近的点的像素值。具体操作为,设水平方向和垂直方向缩放的比例分别为w和h,那么目标图像中的点des(x,y)对应的源图像中的点src的坐标为(x0,y0)=(x/w,y/h)。其中,x0,y0可能为小数,故对其四舍五入,即(x0,y0)=int(x0+0.5,y0+0.5),因此点des(x,y)的像素值就是点src(x0,y0)的像素值。

2、双线性插值:由1中最近邻插值中的四舍五入前的点src(x0,y0)得到它的2*2区域4个邻域像素点的坐标,即(x1,y1)=(int(x0),int(y0)),(x1,y2)=int(x1,y1+1),(x2,y1)=(x1+1,y1),(x2,y2)=(x1+1,y1+1),然后计算权重q1=(x0-x1)*(y0-y1),q2=(1.0-(x0-x1))*(y0-y1),q4=(x0-x1)*(1.0-(y0-y1)),q3=(1.0-(x0-x1))*(1.0-(y0-y1),用value(x,y)表示点(x,y)处的像素值,则目标图像中的点des(x,y)对应像素值value(x,y)=value(x2,y2)*q1+value(x1,y2)*q2+value(x1,y1)*q3+value(x2,y1)*q4,

c/c++实现及处理效果:

1、最近邻插值

voidGeometryTrans::Zoom(floatratioX,floatratioY){//释放旧的输出图像缓冲区if(m_pImgDataOut!=NULL){delete[]m_pImgDataOut;m_pImgDataOut=NULL;}//输出图像的宽和高m_imgWidthOut=int(m_imgWidth*ratioX+0.5);m_imgHeightOut=int(m_imgHeight*ratioY+0.5);//输入图像每行像素字节数intlineByteIn=(m_imgWidth*m_nBitCount/8+3)/4*4;//输出图像每行像素字节数intlineByteOut=(m_imgWidthOut*m_nBitCount/8+3)/4*4;//申请缓冲区,存放输出结果m_pImgDataOut=newunsignedchar[lineByteOut*m_imgHeightOut];//每像素字节数,输入图像与输出图像相同intpixelByte=m_nBitCount/8;//输出图像在输入图像中待插值的位置坐标intcoordinateX,coordinateY;//循环变量,输出图像的坐标inti,j;//循环变量,像素的每个通道intk;//近邻插值for(i=0;i<m_imgHeightOut;i++){for(j=0;j<m_imgWidthOut;j++){//输出图像坐标为(j,i)的像素映射到原图中的坐标值,即插值位置coordinateX=j/ratioX+0.5;coordinateY=i/ratioY+0.5;//若插值位置在输入图像范围内,则近邻插值if(0<=coordinateX&&coordinateX<m_imgWidth&&coordinateY>=0&&coordinateY<m_imgHeight){for(k=0;k<pixelByte;k++)*(m_pImgDataOut+i*lineByteOut+j*pixelByte+k)=*(m_pImgData+coordinateY*lineByteIn+coordinateX*pixelByte+k);}else//若不在输入图像范围内,则置255{for(k=0;k<pixelByte;k++)*(m_pImgDataOut+i*lineByteOut+j*pixelByte+k)=255;}}}}

2、双线性插值

voidGeometryTrans::Zoom(floatratioX,floatratioY){//释放旧的输出图像缓冲区if(m_pImgDataOut!=NULL){delete[]m_pImgDataOut;m_pImgDataOut=NULL;}//输出图像的宽和高m_imgWidthOut=int(m_imgWidth*ratioX+0.5);m_imgHeightOut=int(m_imgHeight*ratioY+0.5);//输入图像每行像素字节数intlineByteIn=(m_imgWidth*m_nBitCount/8+3)/4*4;//输出图像每行像素字节数intlineByteOut=(m_imgWidthOut*m_nBitCount/8+3)/4*4;//申请缓冲区,存放输出结果m_pImgDataOut=newunsignedchar[lineByteOut*m_imgHeightOut];//每像素字节数,输入图像与输出图像相同intpixelByte=m_nBitCount/8;//输出图像在输入图像中待插值的位置坐标floatcoordinateX,coordinateY;//循环变量,输出图像的坐标inti,j;//循环变量,像素的每个通道intk;inty1,y2,x1,x2;floatfx1,fx2,fy1,fy2;//双线性插值for(i=0;i<m_imgHeightOut;i++){coordinateY=i/ratioY;y1=(int)coordinateY;if(y1==m_imgHeightOut-1)y2=y1;elsey2=y1+1;fy1=coordinateY-y1;fy2=(float)1.0-fy1;for(j=0;j<m_imgWidthOut;j++){coordinateX=j/ratioX;x1=(int)coordinateX;if(x1==m_imgWidthOut-1)x2=x1;elsex2=x1+1;fx1=coordinateX-x1;fx2=(float)1.0-fx1;//所求的源图像中的2*2区域4个邻近象素点坐标为(x1,y1)(x1,y2)(x2,y1)(x2,y2)//计算4个权重floats1=fx1*fy1;floats2=fx2*fy1;floats3=fx2*fy2;floats4=fx1*fy2;//输出图像坐标为(j,i)的像素映射到原图中的坐标值,即插值位置//若插值位置在输入图像范围内,则双线性插值if(0<=coordinateX&&coordinateX<m_imgWidth&&coordinateY>=0&&coordinateY<m_imgHeight){for(k=0;k<pixelByte;k++)*(m_pImgDataOut+i*lineByteOut+j*pixelByte+k)=(int)((*(m_pImgData+y2*lineByteIn+x2*pixelByte+k))*s1+(*(m_pImgData+y2*lineByteIn+x1*pixelByte+k))*s2+(*(m_pImgData+y1*lineByteIn+x1*pixelByte+k))*s3+(*(m_pImgData+y1*lineByteIn+x2*pixelByte+k))*s4);}else//若不在输入图像范围内,则置255{for(k=0;k<pixelByte;k++)*(m_pImgDataOut+i*lineByteOut+j*pixelByte+k)=255;}}}}

总结:由处理效果可知,最近邻插值有锯齿现象,灰度值不连续,而双线性插值灰度值连续,图像比较平滑。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。