图像处理之图像的缩放

图像的缩放常用的有最邻近插值法,双线性内插法,和三次内插法。在opencv中对应的都是cvResize只是参数不一样,就想自己实现这个算法过程。

首先介绍一下这三种方法的大致思路:

最邻近插值法:f(i+u,i+v)就是通过判断u,v取整后的结果(比如u>0.5,v<0.5 取f(i+1,j)算法比较简单,但是放大后图像效果比较差;

双线性内插法是对四邻域内的四个像素点进行两个方向上进行插值处理,最后推导出来的表达式为:f(i+u,j+v)=(1-u)(1-v)f(i,j)+(1-u)v*f(i,j+1)+u(1-v)f(i+1)v+

f(i+1)f(v+1)*u*v

三次内插法是利用三次多项式逼近sin(x)/x对16个像素点进行插值。

这里只是将前两种方法的代码分享一下

方法一

 int i,j,ni,nj;
IplImage *src;
IplImage *newimag;
CvSize n_size;
uchar **olddata;
   uchar **newdata;
   uchar *ptr_old;
   uchar *ptr_new;
src=cvLoadImage("F://vc_source//picture_opencv//filter//lena.bmp");


n_size.height=src->height*scale;
n_size.width=src->width*scale;
newimag=cvCreateImage(n_size,src->depth,src->nChannels);

for(j=0;j<newimag->height;j++)


{ nj=(int)(j/scale);
ptr_old=(uchar *)(src->imageData+nj*src->widthStep);
     ptr_new=(uchar *)(newimag->imageData+j*newimag->widthStep);
for(i=0;i<newimag->width;i++)


{ni=(int)(i/scale);
ptr_new[3*i]=ptr_old[3*ni];
        ptr_new[3*i+1]=ptr_old[3*ni+1];
ptr_new[3*i+2]=ptr_old[3*ni+2];
 
}
}
printf("width is %d,widthStep is %d,channel is %d",newimag->width,newimag->widthStep,src->nChannels);
cvNamedWindow("p1");
cvNamedWindow("p2");
cvShowImage("p1",src);
cvShowImage("p2",newimag);
cvSaveImage("F://vc_source//picture_opencv//filter//lena1.bmp",newimag);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&newimag);
cvDestroyWindow("p1");
cvDestroyWindow("p2");

方法二

 int i,j,oi,oj;
 float ni,nj;
 float u,v;
 float temp[4];
IplImage *src;
IplImage *newimag;
CvSize n_size;
uchar **olddata;
   uchar **newdata;
   uchar *ptr_old1,*ptr_old;
   uchar *ptr_new;
src=cvLoadImage("F://vc_source//picture_opencv//filter//lena.bmp");
n_size.height=src->height*scale;
n_size.width=src->width*scale;
newimag=cvCreateImage(n_size,src->depth,src->nChannels);

for(j=0;j<newimag->height;j++)


{ nj=(1.0*j)/scale;
oj=(int)nj;
v=fabs(nj-oj);
ptr_old=(uchar *)(src->imageData+oj*src->widthStep);
      ptr_old1=(uchar *)(src->imageData+(oj+1)*src->widthStep);
     ptr_new=(uchar *)(newimag->imageData+j*newimag->widthStep);
for(i=0;i<newimag->width;i++)


{ni=(1.0*i)/scale;
oi=(int)ni;
u=fabs(ni-oi);
         temp[0]=(1.0-u)*(1.0-v);
temp[1]=(1.0-u)*v;
temp[2]=u*(1.0-v);
temp[3]=u*v;
ptr_new[3*i]=(int)(ptr_old[3*oi]*temp[0]+ptr_old1[3*oi]*temp[1]+ptr_old[3*(oi+1)]*temp[2]+ptr_old1[3*(oi+1)]*temp[3]);
        ptr_new[3*i+1]= (int)(ptr_old[3*oi+1]*temp[0]+ptr_old1[3*oi+1]*temp[1]+ptr_old[3*(oi+1)+1]*temp[2]+ptr_old1[3*(oi+1)+1]*temp[3]);
ptr_new[3*i+2]= (int)(ptr_old[3*oi+2]*temp[0]+ptr_old1[3*oi+2]*temp[1]+ptr_old[3*(oi+1)+2]*temp[2]+ptr_old1[3*(oi+1)+2]*temp[3]);
//printf("B is %d,G is %d,R is %d\n",ptr_new[3*i],ptr_new[3*i+1],ptr_new[3*i+2]);
}
}
printf("width is %d,widthStep is %d,channel is %d",newimag->width,newimag->widthStep,src->nChannels);
cvNamedWindow("p1");
cvNamedWindow("p2");
cvShowImage("p1",src);
cvShowImage("p2",newimag);
cvSaveImage("F://vc_source//picture_opencv//filter//lena2.bmp",newimag);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&newimag);
cvDestroyWindow("p1");
cvDestroyWindow("p2");


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值