0

画像を2つダウンサンプリングしようとしています。画像はグレースケールであると想定しているため、1つのチャネルのみで作業し、平均4ピクセルを試し、結果をdestImageに入れます。destImageを正しく入力する方法がわかりません。ここでコードを見つけてください:

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();
}
4

2 に答える 2

1

Qtを使用しているようですので、車輪の再発明が必要ない場合に備えて、QImageにはサイズ変更(効果的にダウンサンプリング)を行う便利な機能があります。

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

QImageが遅すぎる場合は、一般的に高速なQPixmapを使用することもできます。

省略Qt::SmoothTransformationすると、デフォルトの使用にフォールバックし、Qt::FastTransformationさらに高速になります。

于 2013-03-14T10:54:41.270 に答える
1

コードに大きな問題はありません。基本的には、読み取り/書き込みポインタの場所を適切に追跡するだけです(ストライドで更新することを忘れないでください)。これには、2つのネストされたループを何らかの方法で使用する必要があります。(+仕切りを4に固定します)。

次のアプローチが役立つことがわかりました。一度に1行を処理しても速度の低下はあまりありませんが、さまざまなカーネルの統合が容易になります。

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;
}
于 2013-03-14T11:09:19.810 に答える