3

I'm working on Sobel masking for edge detection without using any special library. The output that I want to get is a text files with 512x512 matrix with values between 0 to 1. I've checked that the code is working by putting smaller values like 50 instead of 'ROW-2' and 'COL-2'. However if I put them back, the code takes forever to run.

Constant values are:

const int ROW = 512;
const int COL = 512;
const double Gx [3][3] = { {-1.0,0.0,1.0},{-2.0,0.0,2.0},{-1.0,0.0,1.0}};
const double Gy [3][3] = { {1.0,2.0,1.0},{0.0,0.0,0.0},{-1.0,-2.0,-1.0}};

This is the main function:

int main()

{  
    double NewImage[ROW][COL] = {0};    

    for (int i = 0; i < ROW; i++)
    {
        for (int j = 0; j < COL; j++)
        {
            NewImage[i][j] = 0;
        }
    }

    for (int i = 0; i < ROW-2; i++)
    {
        for (int j = 0; j < COL-2; j++)
        {

            NewImage[i+1][j+1] = SobelConvolution(i,j); 
        }
    }

    ofstream newImage;
    string filename;
    filename = "output image.txt";

    newImage.open (filename.c_str());

    for(int rows = 0; rows < ROW; rows++)
    {
        for(int cols = 0; cols < COL; cols++)
        {
            newImage << NewImage[ROW][COL] <<" ";
        }
        newImage << endl;
    }

    newImage.close();

    return 0;
}

This is the function SobelConvolution:

double SobelConvolution(int row, int col)
{   
    double convX;
    double convY;
    double conv;

    convX = ImageReader(row,col)*Gx[2][2]
            + ImageReader(row,col+1)*Gx[2][1]
            + ImageReader(row,col+2)*Gx[2][0]
            + ImageReader(row+1,col)*Gx[1][2]
            + ImageReader(row+1,col+1)*Gx[1][1]
            + ImageReader(row+1,col+2)*Gx[1][0]
            + ImageReader(row+2,col)*Gx[0][2]
            + ImageReader(row+2,col+1)*Gx[0][1]
            + ImageReader(row+2,col+2)*Gx[0][0];

    convY = ImageReader(row,col)*Gy[2][2]
            + ImageReader(row,col+1)*Gy[2][1]
            + ImageReader(row,col+2)*Gy[2][0]
            + ImageReader(row+1,col)*Gy[1][2]
            + ImageReader(row+1,col+1)*Gy[1][1]
            + ImageReader(row+1,col+2)*Gy[1][0]
            + ImageReader(row+2,col)*Gy[0][2]
            + ImageReader(row+2,col+1)*Gy[0][1]
            + ImageReader(row+2,col+2)*Gy[0][0];

    conv = sqrt((convX*convX) + (convY*convY));


    return conv;
}

This is the function ImageReader:

double ImageReader(int r, int c)
{
    double OrigImage[ROW][COL];

    ifstream defaultImage ("image.txt");

    if (defaultImage.good())
    {
        for (int i = 0; i < ROW; i++)
        {
            for (int j = 0; j < COL; j++)
            {
                defaultImage >> OrigImage[i][j];
            }
        }
    }
    return OrigImage [r][c]; 
}

Any hint or advice? Thanks in advance!

4

3 に答える 3

2

あなたがやっていることは少し効率が悪いだけでなく、申し訳ありませんが完全に正気ではありません。

画像のすべてのピクセルに対して、SobelConvolution を呼び出し、次に ImageReader を 18 回呼び出します (対応する係数がゼロであるため、そのうち 6 回は役に立ちません)。しかし、恐ろしいことに、ImageReader は毎回テキスト ファイルから完全な画像読み取りを実行するため、単純な配列検索で十分です。

したがって、合計で 4718592 回のファイル ストリームのオープン/クローズと、ファイルからの 1236950581248 の値の読み取りを実行しています。1 回のオープン/クローズと 262144 回の読み取りで十分です。(単一の読み取りが直接の配列アクセスよりもはるかにコストがかかることは考慮していません。) 完全な実行は 2 時間以上かかる場合があります。

于 2016-08-03T07:10:57.540 に答える
2

単一の画像ファイルを 18 回開き、各行と列のすべてのデータを読み取って、単一の行と列を 18 回返すだけですか? 画像ファイルを一度読み込んで、画像データ配列を関数に渡してみませんか?

于 2016-08-02T04:19:21.587 に答える