1

私は現在、画像処理プロジェクトに取り組んでいます。Python、SimpleITK、numpy、およびその他のいくつかのライブラリを使用して、DICOM 画像のスタックを取得し、それらを 3D numpy 配列に変換してから、SITK またはその他の数学的手法 (マスキング、等。)

現在、3x3 近傍の平均を取り、その近傍の中心ピクセルをその平均値に置き換える平均化フィルタを作成しようとしています。その結果、ぼやけた画像になります。Python は 300x300x400 ピクセルを非常に高速にループするのが得意ではないため、C ライブラリを使用して実行しようとしています。問題は、私は C が得意ではないことです。

以下は私のCコードです:

int i, j, k, m, n, p;
double kernsum;

void iter(double *data, int N, int height, int width, int depth, double *kernavg){
    double kern[N*N];
    for (k = 0; k < depth; k++){
        for (i = (N - 1)/2; i < height - 1; i++){
            for (j = (N - 1)/2; j < width - 1; j++){                
                for (m = i - (N - 1)/2; m < i + (N - 1)/2; m++){
                    for (n = j - (N - 1)/2; n < j + (N - 1)/2; n++){
                        kern[m + n*N] = data[i + j*width + k*width*depth];
                    }
                }       
                kernsum = 0;
                for (p = 0; p < N*N; p++){
                    kernsum += kern[p];
                }
                kernavg[i + j*width + k*width*depth] = kernsum/(N*N);
            }
        }
    }
}

そして、これが私が使用しているpythonコードの一部です。poststack は、大きな 3D numpy 配列です。

height = poststack.shape[1]
width = poststack.shape[2]
depth = poststack.shape[0]
N = 3

kernavgimg = np.zeros(poststack.shape, dtype = np.double)
lib = ctypes.cdll.LoadLibrary('./iter.so')
iter = lib.iter

iter(ctypes.c_void_p(poststack.ctypes.data), ctypes.c_int(N), 
    ctypes.c_int(height), ctypes.c_int(width), ctypes.c_int(depth),
    ctypes.c_void_p(kernavgimg.ctypes.data))

print kernavgimg

pyplot.imshow(kernavgimg[0, :, :], cmap = 'gray')
pyplot.show()
image.imsave('/media/sd/K/LabCode/python_code/dump/test.png', kernavgimg.data[0, :, :], cmap = 'gray')

pyplot.imshow(poststack[0, :, :], cmap = 'gray')
pyplot.show()
image.imsave('/media/sd/K/LabCode/python_code/dump/orig.png', poststack[0, :, :], cmap = 'gray')

print kernavgimg[0, :, :] == poststack[0, :, :]
print kernavgimg.shape
print poststack.shape

この StackOverflow の投稿を見て、元の質問をした人と違うことをしているとは思いません...

入力と出力のために Numpy 配列を C 関数に渡す

私は愚かな間違いを犯していることを知っていますが、それは何ですか?

4

1 に答える 1

1

kern[m*N + n*N]問題は、インデックスが割り当てられた配列境界の外にある場所にアクセスしようとするため、C コードがセグメンテーション フォールトを生成することです。

多次元配列のインデックス付けが間違っています。X形状の配列の場合、C の平坦化された配列に(n, m)相当するのはであり、上記のコードで使用していた方法ではありません。X[i][j]X[i*m + j]

于 2015-06-13T23:45:11.857 に答える