Я пытаюсь реализовать деформацию изображения в 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);
Это создает следующее изображение:
Как хорошо видно, значения возле границы отличны от нуля. Может кто-нибудь сказать мне, как получить черную рамку, как показано на следующем рисунке, вместо артефактов, которые я получаю из моего кода?
Следует рассматривать только черную рамку этого изображения, то есть изображение должно быть волнистым (синусоидальным), но без артефактов.
Спасибо…
Вот:
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));
Вы вычисляете местоположение исходного пикселя, но вы берете мод с шириной / высотой, чтобы убедиться, что он находится внутри изображения. Это приводит к обтеканию пикселей по краю. Вместо этого вам нужно установить любой пиксель за пределами изображения черным (или, если ваше исходное изображение имеет черную рамку, закрепите его за край).
Поскольку у вас уже есть граница, вы можете просто зафиксировать координаты, например так:
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);
Других решений пока нет …