简体   繁体   English

下采样图像

[英]Downsample an Image

I'm trying to downsample an image by 2, the image i assumed that it is greyscale, so I will work only with one channel, I tried to average 4 pixels, then put the resultant in the destImage. 我试图将图像下采样2,图像我假设它是灰度的,所以我只使用一个通道,我试图平均4个像素,然后将结果放在destImage中。 I don't know how to fill the destImage correctly. 我不知道如何正确填充destImage。 Kindly find the code here: 请在这里找到代码:

void downsizeRow(unsigned char *srcImage, unsigned char *dstImage, int srcWidth )
{

    unsigned char *srcPtr = srcImage;
    unsigned char *dstPtr = dstImage;

    int stride = srcWidth;
    int b;
    for (int i = 0; i< 4; i++)
    {

        b  = srcPtr[0]+srcPtr[1] + srcPtr[stride + 0] + srcPtr[stride + 1] ;

        srcPtr++;
        dstPtr[0] = (uint8_t)((b + 2)/4);;
        dstPtr++;
    }

}

void downscaleImage( unsigned char *srcImage, unsigned char *dstImage, int srcWidth, int dstHeight, int dstWidth)
{

    unsigned char *srcPtr=srcImage;
    unsigned char *dstPtr=dstImage;

    int in_stride = dstWidth;
    int out_stride = dstHeight;

    for (int j=0;j<dstHeight;j++)
    {
        downsizeRow(srcPtr, dstPtr, srcWidth);  // in_stride is needed
        // as the function requires access to iptr+in_stride
        srcPtr+=in_stride * 2;
        dstImage+=out_stride;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    unsigned char srcimage[4*4];
    unsigned char dstimage[2*2];


    for (int i = 0; i<4*4; i++)
    {
        srcimage[i] = 25;
    }
    std::cout<<"source Image \n"<<std::endl;
    for (int i = 0; i<4*4; i++)
    {

        std::cout<<srcimage[i];
    }

    downscaleImage(srcimage, dstimage, 4,4,2);
    std::cout<<"dest Image"<<std::endl;
    for (int i = 0; i<2*2; i++)
    {

    //    std::cout<<dstimage[i];
    }

    return a.exec();
}

I see you are using Qt, so just in case you don't need to reinvent the wheel, QImage has a convenience function that will do resizing (effectively down-sampling) for you. 我发现你正在使用Qt,所以万一你不需要重新发明轮子,QImage有一个便利功能,可以为你调整大小(有效地下采样)。

QImage smallImage = bigImage.scaled(bigImage.width() / 2, bigImage.heigth() / 2, Qt::KeepAspectRatio, Qt::SmoothTransformation);

In case QImage is too slow for you, you can also try using QPixmap which is generally faster. 如果QImage对你来说太慢,你也可以尝试使用通常更快的QPixmap。

Omitting Qt::SmoothTransformation will fall back to using the default Qt::FastTransformation which will be even faster. 省略Qt::SmoothTransformation将回退到使用默认的Qt::FastTransformation ,这将更快。

There's not much wrong in your code -- basically just keep proper track of the read/write pointer locations (remember to update with strides). 你的代码没有太大的错误 - 基本上只是保持对读/写指针位置的正确跟踪(记得用步幅更新)。 This requires using 2 nested loops one way or another. 这需要以这种或那种方式使用2个嵌套循环。 (+ fix the divider to 4). (+将分隔线固定为4)。

I've found the following approach useful: processing one row at a time has not much speed penalty, but allows easier integration of various kernels . 我发现以下方法很有用:一次处理一行没有太大的速度损失,但允许更容易地集成各种内核

iptr=input_image;  in_stride = in_width;
optr=output_image; out_stride = out_width;
for (j=0;j<out_height;j++) {
    process_row(iptr, optr, in_width);  // in_stride is needed
    // as the function requires access to iptr+in_stride
    iptr+=in_stride * 2;
    optr+=out_stride;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM