0

C++とOpenCVでイメージワーピングを実装しようとしています。私のコードは次のとおりです。

Mat input = imread("Lena.jpg",CV_LOAD_IMAGE_GRAYSCALE);    
Mat out;
double xo, yo;
input.convertTo(input, CV_32FC1);
copyMakeBorder(input, input, 3, 3, 3, 3, 0);

int height = input.rows;
int width = input.cols;

out = Mat(height, width, input.type());


for(int j = 0; j < height; j++){
    for(int i =0; i < width; i++){
        xo = (8.0 * sin(2.0 * PI * j / 128.0));
        yo = (8.0 * sin(2.0 * PI * i / 128.0));
        out.at<float>(j,i) = (float)input.at<float>(((int)(j+yo+height)%height),((int)(i+xo+width)%width));

    }
}
normalize(out, out,0,255,NORM_MINMAX,CV_8UC1);

imshow("output", out);

これにより、次の画像が生成されます。 ゆがんだ画像

はっきりと見えるので、境界付近の値はゼロではありません。コードから取得するアーティファクトの代わりに、次の画像に示すように黒い境界線を取得する方法を教えてもらえますか?

必要な黒い境界線

この画像の黒い境界線のみを考慮する必要があります。つまり、画像は波状(正弦波)である必要がありますが、アーティファクトはありません。

ありがとう...

4

1 に答える 1

2

ここ:

    xo = (8.0 * sin(2.0 * PI * j / 128.0));
    yo = (8.0 * sin(2.0 * PI * i / 128.0));
    out.at<float>(j,i) = (float)input.at<float>(((int)(j+yo+height)%height),((int)(i+xo+width)%width));

ソース ピクセルの位置を計算しますが、幅/高さで mod を取得して、画像内に収まるようにします。これにより、ピクセルがエッジで折り返されます。代わりに、画像の外側のピクセルを黒に設定する必要があります (または、ソース画像に黒い境界線がある場合は、エッジにクランプします)。

すでに境界線があるので、次のように座標を固定できます。

int ix = min(width-1, max(0, (int) (i + xo)));
int iy = min(height-1, max(0, (int) (j + yo)));
out.at<float>(j,i) = (float)input.at<float>(iy,ix);
于 2013-01-16T00:19:51.087 に答える