基于opencv的任意大小的图片的双线性缩放(每次缩放大小一样)

#include "highgui.h"    
#include"cv.h"  

int main()   
{   
 IplImage *src = cvLoadImage("111.jpg",1);//CV_LOAD_IMAGE_GRAYSCALE
 if(!src)
  return 0;
 cvNamedWindow("source",0); 
 cvNamedWindow("result1",1);
 cvShowImage("source",src); 
 int w = src->width;
 int h = src->height;
 IplImage *src1 = cvCreateImage(cvSize(w+500, h+400), 8, src->nChannels);
 IplImage *src2 = cvCreateImage(cvSize(w, h), 8, src->nChannels);
 //cvResize(src, src2, CV_INTER_LINEAR);
 //cvNamedWindow("cvResize",0);  
 //cvShowImage("cvResize",src2); 
 char* srcData = src->imageData;
 char* srcData1 = src1->imageData;
 int w1 = src1->width;
 int h1 = src1->height;
 int endX = w1;//放大后显示图像的尾列
 int endY = h1;
 int channel = src->nChannels;//数据的通道数
 int startX = 0;//放大的起始列
 int startY = 0;//放大的起始行

 int LargeStepWidth = (w>>5)/2;//行方向放大缩小的步长
 int LargeStepHeigh = (h>>5)/2;
 struct LargeIndex
 {
  int startLocation;//放大的点
  float LRate;//左或者上点的比例
  float RRate;//右或者下点的比例
 };

 for(int n = 1; n < (1<<6); n++)
 {
  float xrate = (float)(w1)/(w-LargeStepWidth*2*n);//行放大比例
  float yrate = (float)(h1)/(h-LargeStepHeigh*2*n);//列放大比例
  if(xrate<=0.0 || yrate<=0.0)
   break;
  startX = LargeStepWidth*n;
  startY = LargeStepHeigh*n;
  endX = w - startX;
  endY = h - startY;
  LargeIndex *rowIndexTable = (LargeIndex *)calloc(w1, sizeof(LargeIndex));//行方向点放大前行值以及比例索引
  LargeIndex *colIndexTable = (LargeIndex *)calloc(h1, sizeof(LargeIndex));//列方向点放大前列值以及比例索引
  LargeIndex *rowIndex = rowIndexTable;
  LargeIndex *colIndex = colIndexTable;

  //利用放大后的点查找放大前的位置和该位置的插值比例
  for(int i = 0; i < w1; i++)//行方向索引的计算
  {
   float xLocation = i/xrate+startX;
   int x = (int)(xLocation);   
   float rightRate = xLocation-x;
   float leftRate = 1.0f-rightRate;
   rowIndex->startLocation = x;
   rowIndex->LRate = leftRate;
   rowIndex->RRate = rightRate;
   rowIndex++;
  }
  for(int j = 0; j < h1; j++)//列方向索引的计算
  {
   float yLocation = j/xrate+startY;
   int y = (int)(yLocation);   
   float downRate = yLocation-y;
   float upRate = 1.0f-downRate;
   colIndex->startLocation = y;
   colIndex->LRate = upRate;
   colIndex->RRate = downRate;
   colIndex++;
  }

  //利用放大后的点查找放大前的位置,并在原图对该位置进行插值
  //rowIndex = rowIndexTable;
  colIndex = colIndexTable;
  unsigned char temp = 0;
  char *src1Data = src1->imageData;
  for(int j = 0; j < h1; j++)//
  {
   int py = colIndex->startLocation;//索引
   int by = py+1;
   float dy1 = colIndex->LRate;
   float dy2 = colIndex->RRate;
   rowIndex = rowIndexTable;
   for(int i = 0; i < w1; i++)
   {
    int px = rowIndex->startLocation;
    int bx = px+1;
    if(channel > 1)
    {
     px = px*3;
     bx = bx*3;
    }
    float dx1 = rowIndex->LRate;
    float dx2 = rowIndex->RRate;
    char *upPoint = src->imageData + py*src->widthStep;//上一行
    char *downPoint = src->imageData + by*src->widthStep;//下一行
    float left = (uchar)(*(upPoint + px));//上左
    float right = (uchar)(*(upPoint + bx));//上右
    float left1 = (uchar)(*(downPoint + px));//下左
    float right1 = (uchar)(*(downPoint + bx));//下右

    //双线性插值
    float up = dx1*left+dx2*right;
    float down = dx1*left1+dx2*right1;
    temp = (unsigned char)(up*dy1+down*dy2);
    if(temp < 0)
     temp = 0;
    if(temp > 255)
     temp = 255;
    *src1Data = (unsigned char)temp;
    src1Data++;

    if(channel > 1)
    {
     upPoint = src->imageData + py*src->widthStep;//上一行
     downPoint = src->imageData + by*src->widthStep;//下一行
     left = (uchar)(*(upPoint + px+1));//上左
     right = (uchar)(*(upPoint + bx+1));//上右
     left1 = (uchar)(*(downPoint + px+1));//下左
     right1 = (uchar)(*(downPoint + bx+1));//下右

     //双线性插值
     up = dx1*left+dx2*right;
     down = dx1*left1+dx2*right1;
     temp = (unsigned char)(up*dy1+down*dy2);
     if(temp < 0)
      temp = 0;
     if(temp > 255)
      temp = 255;
     *src1Data = (unsigned char)temp;
     src1Data++;

     upPoint = src->imageData + py*src->widthStep;//上一行
     downPoint = src->imageData + by*src->widthStep;//下一行
     left = (uchar)(*(upPoint + px+2));//上左
     right = (uchar)(*(upPoint + bx+2));//上右
     left1 = (uchar)(*(downPoint + px+2));//下左
     right1 = (uchar)(*(downPoint + bx+2));//下右

     //双线性插值
     up = dx1*left+dx2*right;
     down = dx1*left1+dx2*right1;
     temp = (unsigned char)(up*dy1+down*dy2);
     if(temp < 0)
      temp = 0;
     if(temp > 255)
      temp = 255;
     *src1Data = (unsigned char)temp;
     src1Data++;
    }
    rowIndex++;
   }
   colIndex++;
  }

  cvShowImage("result1",src1);
  cvWaitKey(0);
 }

 cvReleaseImage(&src);  
 cvReleaseImage(&src1);
 cvReleaseImage(&src2);
 cvDestroyAllWindows();   
 return 0;   
}   

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值