1. 程式人生 > >基於opencv的雙線性插值的實現(一)

基於opencv的雙線性插值的實現(一)

#include <cv.h>
#include <highgui.h>

#include <iostream>

using namespace std;

float Abs(float f);
void zoom(IplImage* src, IplImage* dst);

int main() {

	// read an image
	IplImage* src = cvLoadImage("E://pic//view.jpg");
    IplImage* dst = cvCreateImage(cvSize(1000,1000), src->depth, src->nChannels);
    zoom(src, dst);

	cvShowImage("src", src);
	cvShowImage("dst", dst);
	cvWaitKey(0);

	return 1;
}
/****************************
*返回絕對值
*****************************/
float Abs(float f)
{
    return f>=0 ? f : -f;
}
/****************************
*目標: 實現影象的縮放,
        使用了雙線性插值的演算法

*引數: src源影象
        dst生成影象

*返回值:無
*****************************/
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;

			f1.x = ((uchar*)(src->imageData + src->widthStep*iv))[iu*3+0] * (1-Abs(uv.x-iu))+
				((uchar*)(src->imageData + src->widthStep*iv))[(iu+1)*3+0] * (uv.x-iu);
			f1.y = ((uchar*)(src->imageData + src->widthStep*iv))[iu*3+1] * (1-Abs(uv.x-iu))+
				((uchar*)(src->imageData + src->widthStep*iv))[(iu+1)*3+1] * (uv.x-iu);
			f1.z = ((uchar*)(src->imageData + src->widthStep*iv))[iu*3+2] * (1-Abs(uv.x-iu))+
				((uchar*)(src->imageData + src->widthStep*iv))[(iu+1)*3+2] * (uv.x-iu);

			f2.x = ((uchar*)(src->imageData + src->widthStep*(iv+1)))[iu*3] * (1-Abs(uv.x-iu))
                    +((uchar*)(src->imageData + src->widthStep*(iv+1)))[(iu+1)*3] * (uv.x-iu);
			f2.y = ((uchar*)(src->imageData + src->widthStep*(iv+1)))[iu*3+1] * (1-Abs(uv.x-iu))+
				((uchar*)(src->imageData + src->widthStep*(iv+1)))[(iu+1)*3+1] * (uv.x-iu);
			f2.z = ((uchar*)(src->imageData + src->widthStep*(iv+1)))[iu*3+2] * (1-Abs(uv.x-iu))+
				((uchar*)(src->imageData + src->widthStep*(iv+1)))[(iu+1)*3+2] * (uv.x-iu);

            ((uchar*)(dst->imageData + dst->widthStep*j))[i*3] = f1.x*(1-Abs(uv.y-iv))+f2.x*(Abs(uv.y-iv));
			((uchar*)(dst->imageData + dst->widthStep*j))[i*3+1] = f1.y*(1-Abs(uv.y-iv))+f2.y*(Abs(uv.y-iv));
			((uchar*)(dst->imageData + dst->widthStep*j))[i*3+2] = f1.z*(1-Abs(uv.y-iv))+f2.z*(Abs(uv.y-iv));
         }
         //這裡新增上最後一列
         ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-1)*3] = ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-2)*3];
         ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-1)*3+1] = ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-2)*3+1];
         ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-1)*3+2] = ((uchar*)(dst->imageData + dst->widthStep*j))[(dstWidth-2)*3+2];
    }
    //這裡新增上最後一行
    for(int i=0; i<dstWidth*3; i++)
    {
        ((uchar*)(dst->imageData + dst->widthStep*(dstHeight-1)))[i] = ((uchar*)(dst->imageData + dst->widthStep*(dstHeight-2)))[i];
    }
}

效果圖: