您的位置:首页 > 编程语言 > C语言/C++

图像旋转 双线性插值 c++

2015-12-08 14:38 555 查看
            前面详细介绍了最近邻插值实现图像的旋转,但是我们都知道,最近邻插值对于图像的旋转效果不是特别的好。所以在本文中,我们详细讨论一下双线性插值算法。

            首先,详细介绍一下什么事双线性插值,以及双线性插值为什么会比最近邻插值效果好一些。

            为什么图像的旋转一定要插值,因为在旋转过程中,由于三角函数的影响,导致旋转后的点,并不是每一个点都可以在原图像中找到对应点(如:计算出(3.5,4.4)将对应哪个点呢?),所以这些点的灰度值如何确定,就需要我们利用插值算法来进行处理,最近邻插值,想法比较简单,直接四舍五入,显然这种方法不是最理想的。那么双线性插值是什么呢?首先看图:



               如上图,假如,我们计算后得到的像素点为p,但是这个点并没有在图像中有点与之对应,因为它的值可能是小数的,那么,我们如何确定它的灰度值呢?

 双线性插值的想法也比较简单,双线性,顾名思义,利用了2次线性插值。那是哪两次呢?这时,我们便利用上了其周围的像素点O12   O22   O11   O 21 .通过O12  O22 计算出R2点的灰度值,然后通过O11   O21计算出R1点的灰度值,然后再根据R1  R2计算出P点的灰度值。这样相比最近邻方法,更加充分的利用了周围的像素点,可以取得较好的效果。

             那么我们编程如何计算呢?

             首先,对p点坐标进行取整,得到O21点坐标,然后像素值+1 便得到O22的坐标,然后利用比例计算,便可以得到R2的灰度值,同理可以得到R1灰度值,再根据比例计算,便可以得到p点的灰度值。

具体代码如下:

/*

双线性插值图像旋转函数 , 旋转之后 图像不改变大小  信息有些丢失

输入参数:

      img: 原图像  width:原图像的宽度  height:原图像的高度
 result:旋转后的图像
 sita:旋转角度(弧度制)
 xr,yr : 旋转中心
 BackGray:背景灰度值

*/

int TwinRotate(BYTE *img,int width,int height,BYTE *result,double sita,double xr,double yr,BYTE BackGray)

{

    double SinTheta = sin(sita);double CosTheta = cos(sita);
    if(result)
          delete []result;

    result = new BYTE[width*height];

  //  if(ResultTemp==NULL)

   //     return -1;

    memset( result, BackGray, width*height*sizeof(BYTE) );

    int    x, y, px, py; 

    double tx,ty,p1,p2,p3,p4,p1_2,p3_4;

    double ConstX= -xr*CosTheta + yr*SinTheta + xr ;
    double ConstY= -yr*CosTheta - xr*SinTheta + yr ;

    

    BYTE *pRes=result, *p;

    for(y=0;y<height;y++)

    {

        tx = - y*SinTheta - CosTheta + ConstX ; 

        ty =   y*CosTheta - SinTheta + ConstY ; 

        for(x=0;x<width;x++)

        { 

            tx += CosTheta; //x*CosTheta - y*SinTheta + ConstX; (x-xr)*CosTheta - (y-yr)*SinTheta + xr 

            ty += SinTheta; //y*CosTheta + x*SinTheta + ConstY; (y-yr)*CosTheta + (x-xr)*SinTheta + yr 

            px = (int)tx;

            py = (int)ty;

            if( px<0 || px>width-2 || py<0 || py>height-2 )

            {

                pRes++;

                continue;

            }

                  p1 = img[py*width+px];    //此处求出周围点的值
                  p2 = img[py*width+px+1];
                  p3 = img[(py+1)*width+px];
                  p4 = img[(py+1)*width+px+1];
             p1_2 = p1 + (tx-px)*(p2-p1);
             p3_4 = p3 + (tx-px)*(p4-p3);
           *pRes = p1_2 + (ty - py)*(p3_4 - p1_2); 

            pRes++;

         }

    }

    return true;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: