一:使用系统默认的插值法(双线性插值)
#include <cv.h>
#include <highgui.h>
#include <math.h>
int main(int argc, char* argv[])
{
IplImage *src = 0; //源图像指针
IplImage *dst = 0; //目标图像指针
float scale = 2.0; //缩放倍数为2倍
CvSize dst_cvsize; //目标图像尺寸
/* the first command line parameter must be image file name */
if ( argc == 2 && (src = cvLoadImage(argv[1], -1))!=0 )
{
//如果命令行传递了需要打开的图片就无须退出,所以注释掉下面一行!
//return -1;
}
else
{
src = cvLoadImage("src.jpg"); //载入工作目录下文件名为“src.jpg”的图片。
}
dst_cvsize.width = src->width * scale; //目标图像的宽为源图象宽的scale倍
dst_cvsize.height = src->height * scale; //目标图像的高为源图象高的scale倍
dst = cvCreateImage( dst_cvsize, src->depth, src->nChannels); //构造目标图象
cvResize(src, dst, CV_INTER_LINEAR); //放大源图像到目标图像,采用双线性法。
cvNamedWindow( "src", CV_WINDOW_AUTOSIZE ); //创建用于显示源图像的窗口
cvNamedWindow( "dst", CV_WINDOW_AUTOSIZE ); //创建用于显示目标图像的窗口
cvShowImage( "src", src ); //显示源图像
cvShowImage( "dst", dst ); //显示目标图像
cvSaveImage("Lenna_2scale.jpg", dst);
cvWaitKey(0); //等待用户响应
cvReleaseImage(&src); //释放源图像占用的内存
cvReleaseImage(&dst); //释放目标图像占用的内存
cvDestroyWindow( "src" ); //销毁窗口“src”
cvDestroyWindow( "dst" ); //销毁窗口“dst”
//void cvDestroyAllWindows(void);
return 0;
}
原图与放大结果
//设x0处的函数值为f(x0), x1处的函数值为f(x1), 设x0 < x < x1,对f(x)进行线性插值可得:
//
// f(x) = f(x0)*(x1-x)/(x1-x0) + f(x1)*(x-x0)/(x1-x0)
//opencv中默认的图像插值也是双线性插值
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
#define PI 3.14159265
void MyScale(Mat& src, Mat& dst, float TransMat[3][3]);
/**
* @function main
*/
int main( int argc, char** argv )
{
// load image
/*char* imageName = "images/Lenna_256.png"; */
Mat image;
image = imread(argv[1],1);
if(!image.data)
{
cout << "No image data" << endl;
return -1;
}
// show image
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", image);
Mat dst;
float transMat[3][3] = { {2.0, 0, 0}, {0, 2.0, 0}, {0, 0, 1} };
MyScale(image, dst, transMat);
namedWindow("out_image", CV_WINDOW_AUTOSIZE);
imshow("out_image", dst);
imwrite("Lenna_scale_bilinear.jpg", dst);
waitKey(0);
return 0;
}
void MyScale(Mat& src, Mat& dst, float TransMat[3][3])
{
CV_Assert(src.data);
CV_Assert(src.depth() != sizeof(uchar));
// calculate margin point of dst image
float left = 0;
float right = 0;
float top = 0;
float down = 0;
float x = src.cols * 1.0f;
float y = 0.0f;
float u1 = x * TransMat[0][0] + y * TransMat[0][1];
float v1 = x * TransMat[1][0] + y * TransMat[1][1];
x = src.cols * 1.0f;
y = src.rows * 1.0f;
float u2 = x * TransMat[0][0] + y * TransMat[0][1];
float v2 = x * TransMat[1][0] + y * TransMat[1][1];
x = 0.0f;
y = src.rows * 1.0f;
float u3 = x * TransMat[0][0] + y * TransMat[0][1];
float v3 = x * TransMat[1][0] + y * TransMat[1][1];
left = min( min( min(0.0f,u1), u2 ), u3);
right = max( max( max(0.0f,u1), u2 ), u3);
top = min( min( min(0.0f,v1), v2 ), v3);
down = max( max( max(0.0f,v1), v2 ), v3);
// create dst image
dst.create(int(abs(right-left)), int(abs(down-top)), src.type());
CV_Assert( dst.channels() == src.channels() );
int channels = dst.channels();
int i,j;
uchar* p;
uchar* q0;
uchar* q1;
for( i = 0; i < dst.rows; ++i)
{
p = dst.ptr<uchar>(i);
for ( j = 0; j < dst.cols; ++j)
{
//
x = (j+left)/TransMat[0][0] ; // NOTE: adverse rotation here!!!
y = (i+top)/TransMat[1][1] ;
int x0 = int(x);
int y0 = int(y);
int x1 = int(x) + 1;
int y1 = int(y) + 1;
if( (x0 >= 0) && (x0 < src.cols) && (y0 >= 0) && (y0 < src.rows) &&
(x1 >= 0) && (x1 < src.cols) && (y1 >= 0) && (y1 < src.rows) )
{
q0 = src.ptr<uchar>(y0);
q1 = src.ptr<uchar>(y1);
switch(channels)
{
case 1:
{
//p[j] = q[x];
break;
}
case 3:
{
float b0 = q0[3*x0] ;
float g0 = q0[3*x0+1];
float r0 = q0[3*x0+2];
float b1 = q0[3*x1] ;
float g1 = q0[3*x1+1];
float r1 = q0[3*x1+2];
float b2 = q1[3*x0] ;
float g2 = q1[3*x0+1];
float r2 = q1[3*x0+2];
float b3 = q1[3*x1] ;
float g3 = q1[3*x1+1];
float r3 = q1[3*x1+2];
float b4 = b0 * (x1-x) / (x1-x0) + b1 * (x-x0) / (x1-x0);
float g4 = g0 * (x1-x) / (x1-x0) + g1 * (x-x0) / (x1-x0);
float r4 = r0 * (x1-x) / (x1-x0) + r1 * (x-x0) / (x1-x0);
float b5 = b2 * (x1-x) / (x1-x0) + b3 * (x-x0) / (x1-x0);
float g5 = g2 * (x1-x) / (x1-x0) + g3 * (x-x0) / (x1-x0);
float r5 = r2 * (x1-x) / (x1-x0) + r3 * (x-x0) / (x1-x0);
p[3*j] = b4 * (y1-y) / (y1-y0) + b5 * (y-y0) / (y1-y0);
p[3*j+1] = g4 * (y1-y) / (y1-y0) + g5 * (y-y0) / (y1-y0);
p[3*j+2] = r4 * (y1-y) / (y1-y0) + r5 * (y-y0) / (y1-y0);
break;
}
}
}
}
}
}
原图与处理结果