#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;
}