基于opencv的双线性插值的实现(二)

上篇博客用实现了基于双线性插值算法的图像缩放,主要函数zoom中大量使用了指针。采用指针来读取图像像素,优点是执行速度快,缺点是代码不易阅读。本篇采用opencv库中自带的cvGet2D()和cvSet2D()函数来读写图像像素,虽然执行速度较慢,但代码阅读性强,简单明了。

下面是主要函数zoom的实现,其他部分参考我的上一篇博客。

void zoom(IplImage* src, IplImage* dst)
{
    int srcWidth = src->width;
    int srcHeight = src->height;
    int dstWidth = dst->width;
    int dstHeight = dst->height;

    //源图像与目标图像的宽高比例,这里减1很重要,否则有时报错,有时不报错。这点困扰了我很久
    const float tx = (srcWidth-1.0f)/(dstWidth-1.0f);
    const float ty = (srcHeight-1.0f)/(dstHeight-1.0f);

    CvPoint2D32f uv;//存储源图像的浮点坐标
    CvPoint3D32f f1;
    CvPoint3D32f f2;

    for (int j=0; j<dstHeight-1; j++)
     {
         for (int i=0; i<dstWidth-1; i++)
         {
			uv.x = i*tx;
			uv.y = j*ty;

			int iu = (int)uv.x;
            int iv = (int)uv.y;

            CvScalar p1, p2, p3, p4, s;
            p1=cvGet2D(src, iv, iu);
            p2=cvGet2D(src, iv, iu+1);
            p3=cvGet2D(src, iv+1, iu);
            p4=cvGet2D(src, iv+1, iu+1);

            f1.x = p1.val[0]*(1-Abs(uv.x-iu))+p2.val[0]*(uv.x-iu);
            f1.y = p1.val[1]*(1-Abs(uv.x-iu))+p2.val[1]*(uv.x-iu);
            f1.z = p1.val[2]*(1-Abs(uv.x-iu))+p2.val[2]*(uv.x-iu);

            f2.x = p3.val[0]*(1-Abs(uv.x-iu))+p4.val[0]*(uv.x-iu);
            f2.y = p3.val[1]*(1-Abs(uv.x-iu))+p4.val[1]*(uv.x-iu);
            f2.z = p3.val[2]*(1-Abs(uv.x-iu))+p4.val[2]*(uv.x-iu);

            s.val[0] = f1.x*(1-Abs(uv.y-iv))+f2.x*(Abs(uv.y-iv));
            s.val[1] = f1.y*(1-Abs(uv.y-iv))+f2.y*(Abs(uv.y-iv));
            s.val[2] = f1.z*(1-Abs(uv.y-iv))+f2.z*(Abs(uv.y-iv));
            cvSet2D(dst, j, i, s);
     
         }
         //这里添加上最后一列
         cvSet2D(dst, j, dstWidth-1, cvGet2D(dst, j, dstWidth-2));
    }
    //这里添加上最后一行
    for(int i=0; i<dstWidth; i++)
    {
        cvSet2D(dst, dstHeight-1, i, cvGet2D(dst, dstHeight-2, i));
    }
}



你可能感兴趣的:(算法,opencv,双线性插值)