私の目標は、Halide で信号に依存するガウス ノイズをモデル化できるようにすることです。私は現在Halideに移植しているOpenCVで構築されたモデルを持っています。問題は、Halide の乱数ジェネレーターが正規分布していないことです。そのため、外部関数を使用してノイズ値を生成する必要があります。
実装の試行では、C++ 乱数ジェネレーターを使用して正規分布ノイズを生成し、Halide Func を使用して各ピクセルでノイズの信号依存の標準偏差を生成し、次にノイズを renoise のピクセルに追加します。以下に、関数のレイアウトを示します。
// Note: This is an implementation of the noise model found in the paper below:
// "Noise measurement for raw-data of digital imaging sensors by
// automatic segmentation of non-uniform targets"
float get_normal_dist_rand( float mean, float std_dev ) {
std::default_random_engine generator;
std::normal_distribution<float> distribution(mean,std_dev);
float out = distribution(generator);
return out;
}
Func make_get_std_dev( Func *in_func ) {
Var x, y, c;
float q = 0.0060;
float p = 0.0500;
// std_dev = q * sqrt(unnoised_pixel - p)
Func get_std_dev("get_std_dev");
get_std_dev(x,y,c) = q * sqrt( (*in_func)(x,y,c) - p );
return get_std_dev;
}
Func make_renoise( Func *in_func, Func *std_dev ) {
Var x, y, c;
// Noise parameters
// noised_pixel = unnoised_pixel +
// gaussian_rand( std_dev = q * sqrt(unnoised_pixel - p) )
// q and p values do not vary between channels
Func renoise("renoise");
renoise(x,y,c) = (*in_func)(x,y,c) +
get_normal_dist_rand(0,(*std_dev)(x,y,c));
return renoise;
}
これは私には理にかなっていますが、残念ながら、コンパイルしようとすると次のエラーが表示されます。
../common/pipe_stages.cpp: In function 'Halide::Func make_renoise(Halide::Func*, Halide::Func*)':
../common/pipe_stages.cpp:223:64: error: cannot convert 'std::enable_if<true, Halide::FuncRef>::type {aka Halide::FuncRef}' to 'float' for argument '2' to 'float get_normal_dist_rand(float, float)'
get_normal_dist_rand(0,(*std_dev)(x,y,c));
^
そのため、 Func の出力を C++ 関数に提供できないようです。これは Halide の制限として理にかなっていると思いますが、信号依存の正規分布ノイズを実装する代替手段は実際には見当たりません。Halide で外部 C++ 関数を使用する別の方法はありますか? 「extern」の使用について話している人を見たことがありますが、残念ながらその機能に関するドキュメントは非常に軽いようで、必要なものを見つけることができません。