Я делаю программу изменения размера изображения на C, и в настоящий момент у меня возникают проблемы с функцией Bilinear Interpolation (это один из многих, которые я использую). Эта проблема возникает только для 16-битных растровых изображений. Если я использую 24-разрядные версии, она идеально их изменяет.Bilinear Interpolation image resizing marks & 'splotches'
Вот мой код для билинейной интерполяции. n_w и n_h являются новые значения ширины и высоты изображения:
#define getelm(x) (((pix+index)->x)*(1-xdiff)*(1-ydiff))+(((pix+index+1)->x)*(xdiff)*(1-ydiff))+(((pix+index+o_w)->x)*(1-xdiff)*(ydiff))+((pix+index+o_w+1)->x)*xdiff*ydiff
int pad = (2*n_w) & 3;
if (pad)
pad = 4-pad;
uint16_t *buffer;
if (buf)
buffer = malloc(2*n_w);
for (i = 0; i < n_h; i++) {
for (j = 0; j < n_w; j++) {
x = (int)(j*xrat);
y = (int)(i*yrat);
xdiff = (xrat*j)-x;
ydiff = (yrat*i)-y;
index = y*o_w+x;
uint16_t container = 0;
container |= (int)(round(getelm(b))) << 11;
container |= (int)(round(getelm(g))) << 5;
container |= (int)round(getelm(r));
if (buf)
*(buffer+j) = container;
else
fwrite(&container, 1, 2, dest);
}
if (buf)
fwrite(buffer, 1, 2*n_w, dest);
fwrite(&pad, 1, pad, dest);
}
Моя 24-битная версия этого кода (где разница лишь в том, что контейнер не используется, а вместо 3 8-разрядных целых чисел УДЕРЖИВАЙТЕ RGB значения) прекрасно работает.
Этот код, однако, дает странные результаты. Посмотрите на изображение ниже:
При изменении размера этого, он дает мне эту спину:
Я не могу понять, почему это будет происходить, особенно когда он работает на 24-битных растровых изображений, а также что некоторые другие алгоритмы изменения размера (например, Nearest Neighbor) работают с 16-бит так же, как это должно быть.
EDIT: Я не думаю, что это проблема переполнения, потому что, добавив следующий код не дает никакого вывода при запуске:
if (MAX((int)(getelm(b)), 31) > 31)
printf("blue overflow: %.10f\n", (getelm(b)));
if (MAX((int)(getelm(g)), 63) > 63)
printf("green overflow: %.10f\n", (getelm(g)));
if (MAX((int)(getelm(r)), 31) > 31)
printf("red overflow: %.10f\n", (getelm(r)));
EDIT 2: Я не думаю, что это сгущенного проблема либо, это ничего не делает:
if ((getelm(b)) < 0 || (getelm(g)) < 0 || (getelm(r)) < 0)
printf("Underflow\n");
Вы пробовали проверить результат getelem(), чтобы убедиться, что он имеет соответствующую ширину и не перетекает за пределы ожидаемого диапазона? Это объясняет избыточные пиксели и тот факт, что он работает в 24 бит. – Sniggerfardimungus
См. Мое редактирование, спасибо –
И что, если вы проверите * underflow *?Отрицательное значение будет установлено на max после литья без знака. – usr2564301