1.基本原理
图像的缩放一般使用插值算法,而本章将介绍两种常用插值算法:最临近插值法和双线性插值法
1.最临近插值法
将浮点数的位置坐标,进行四舍五入找到原图像的整型坐标即可,具体操作可见下面的公式,其中原图像坐标为(x, y),输出图像坐标为(i,j),比例系数为fx和fy。
2.双线性插值法
浮点数的位置坐标是由周围四个像素点来确定。具体公式可见下面,其中浮点数周围四个像素点的像素值分别为T1、T2、T3和T4,u和v分别表示浮点坐标距离左上角的横坐标差值和纵坐标差值。
2.代码实现(代码是我以前自学图像处理时写的,代码很粗糙没做任何优化,但很好理解)
/*图像的缩放函数(最临近插值法),fx为水平缩放系数,fy为垂直缩放系数*/
QImage* MainWindow::ZoomNormal(QImage* image,double fx,double fy)
{
unsigned int OutWidth = (unsigned int)(image->width() * fx + 0.5);
unsigned int OutHeight = (unsigned int)(image->height() * fy + 0.5);
QImage* newImage = new QImage(OutWidth, OutHeight ,QImage::Format_ARGB32);
unsigned char* copyPixel = NULL;
unsigned char* objPixel = NULL;
int x = 0;
int y = 0;
long tempY;
long tempJ;
for (unsigned int j = 0; j < OutHeight; j++)
{
y = (int) (j / fy + 0.5);
if (y >= image->height())
{
y --;
}
tempY = y * image->width() * 4;
tempJ = j * OutWidth * 4;
for(unsigned int i =0; i < OutWidth; i++)
{
x = (int)(i / fx + 0.5);
if (x >= image->width())
{
x --;
}
copyPixel = image->bits() + tempY + x * 4;
objPixel = newImage->bits() + tempJ + i *4;
memcpy(objPixel,copyPixel,4);
}
}
return newImage;
}
/*图像的缩放函数(双线性差值法),fx为水平缩放系数,fy为垂直缩放系数*/
QImage* MainWindow::ZooInterpolation(QImage* image,double fx,double fy)
{
unsigned int OutWidth = (unsigned int)(image->width() * fx +0.5);
unsigned int OutHeight = (unsigned int)(image->height() * fy +0.5 );
QImage* newImage = new QImage(OutWidth, OutHeight ,QImage::Format_ARGB32);
double x = 0;
double y = 0;
int r,g,b;
for (unsigned int j = 0; j < OutHeight- fy; j++) // 最后一行会溢出,所以去掉
{
y = j / fy ;
for(unsigned int i =0; i < OutWidth; i++)
{
x = i / fx ;
int x1, x2, y1, y2;
x1= ( int)x;
x2 = x1 + 1;
y1 = ( int)y;
y2 = y1 + 1;
QColor oldcolor1;
QColor oldcolor2;
QColor oldcolor3;
QColor oldcolor4;
double u, v;
u = x - x1;
v = y - y1;
if ((x >=image->width() - 1 ) && (y >=image->height() - 1 ))
{
oldcolor1 = QColor(image->pixel(x1,y1));
r = oldcolor1.red();
g = oldcolor1.green();
b = oldcolor1.blue();
}
else if (x >= image->width() - 1)
{
oldcolor1 = QColor(image->pixel(x1,y1));
oldcolor3 = QColor(image->pixel(x1,y2));
r = oldcolor1.red() * (1 - v) + oldcolor3.red() * v;
g = oldcolor1.green() * (1 - v) + oldcolor3.green() * v;
b = oldcolor1.blue() * (1 - v) + oldcolor3.blue() * v;
}
else if (x >=image->height() - 1)
{
oldcolor1 = QColor(image->pixel(x1,y1));
oldcolor2 = QColor(image->pixel(x2,y1));
r = oldcolor1.red() * (1 - u) + oldcolor2.red() * u;
g = oldcolor1.green() * (1 - u) + oldcolor2.green() * u;
b = oldcolor1.blue() * (1 - u) + oldcolor2.blue() * u;
}
else
{
oldcolor1 = QColor(image->pixel(x1,y1));
oldcolor2 = QColor(image->pixel(x2,y1));
oldcolor3 = QColor(image->pixel(x1,y2));
oldcolor4 = QColor(image->pixel(x2,y2));
int r1,g1,b1;
r = oldcolor1.red() * (1 - u) + oldcolor2.red() * u;
g = oldcolor1.green() * (1 - u) + oldcolor2.green() * u;
b = oldcolor1.blue() * (1 - u) + oldcolor2.blue() * u;
r1 = oldcolor3.red() * (1 - u) + oldcolor4.red() * u;
g1 = oldcolor3.green() * (1 - u) + oldcolor4.green() * u;
b1 = oldcolor3.blue() * (1 - u) + oldcolor4.blue() * u;
r = r * (1 - v) + r1 * v;
g = g * (1 - v) + g1 * v;
b = b * (1 - v) + b1 * v;
}
newImage->setPixel(i, j, qRgb(r, g, b));
}
}
return newImage;
}
3.项目源码下载:
整套算法系列:
https://blog.csdn.net/u013289254/category_12811658.html?spm=1001.2014.3001.5482https://blog.csdn.net/u013289254/category_12811658.html?spm=1001.2014.3001.5482项目源码下载地址:关注WX【AI街潜水的八角】,回复【qt图像算法】即可下载
整套项目源码内容包含
标签:QColor,缩放,int,image,unsigned,调包,oldcolor1,图像,y1 From: https://blog.csdn.net/u013289254/article/details/143079819[1].根据算法原理,编写纯c++源码,不调用外源库opencv 等;
[2].包括各种图像处理的基本算法,包含腐蚀膨胀,缩放,转置,镜像,平移,均衡变化,灰度拉升,灰度阈值,灰度非线性,转灰度,灰度线性,旋转,简单平滑,高斯平滑,轮廓跟踪,种子算法,hough直线检测,拉普拉斯,带方向边缘检测,常规边缘检测(梯度算子、Roberts算子和Sobel算子),中值滤波,反色操作等;
[3].程序中有完整的注释,便于大家很好理解代码。