图像的缩放之c++实现(qt + 不调包)

1.基本原理

   图像的缩放一般使用插值算法,而本章将介绍两种常用插值算法:最临近插值法和双线性插值法

   1.最临近插值法

    将浮点数的位置坐标,进行四舍五入找到原图像的整型坐标即可,具体操作可见下面的公式,其中原图像坐标为(x, y),输出图像坐标为(i,j),比例系数为fx和fy。

图像的缩放之c++实现(qt + 不调包)_第1张图片

图像的缩放之c++实现(qt + 不调包)_第2张图片

    2.双线性插值法

     浮点数的位置坐标是由周围四个像素点来确定。具体公式可见下面,其中浮点数周围四个像素点的像素值分别为T1、T2、T3和T4,u和v分别表示浮点坐标距离左上角的横坐标差值和纵坐标差值。

图像的缩放之c++实现(qt + 不调包)_第3张图片

图像的缩放之c++实现(qt + 不调包)_第4张图片

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.参考资料

    数字图像处理——技术详解与Visual C++实践(左飞等著),写代码与写博客的时间相差两年,至于还参考其他的资料不,我已经忘记了,如若需要,我可以补上去

你可能感兴趣的:(基于qt图像算法处理,c++,qt,开发语言)