image - Bicubic interpolation in C -
im trying deal bicubic image interpolation in c. therefore i've built small script.
1. "resize_image"-function:
void resize_image(ppmimage *source_image, ppmimage *destination_image, float scale) { uint8_t sample[3]; int y, x; destination_image->x = (long)((float)(source_image->x)*scale); destination_image->y = (long)((float)(source_image->y)*scale); (y = 0; y < destination_image->y; y++) { float v = (float)y / (float)(destination_image->y - 1); (x = 0; x < destination_image->x; ++x) { float u = (float)x / (float)(destination_image->x - 1); sample_bicubic(source_image, u, v, sample); destination_image->data[x+((destination_image->y)*y)].red = sample[0]; destination_image->data[x+((destination_image->y)*y)].green = sample[1]; destination_image->data[x+((destination_image->y)*y)].blue = sample[2]; } } } 2. "sample_bicubic"-function
void sample_bicubic(ppmimage *source_image, float u, float v, uint8_t sample[]) { float x = (u * source_image->x)-0.5; int xint = (int)x; float xfract = x-floor(x); float y = (v * source_image->y) - 0.5; int yint = (int)y; float yfract = y - floor(y); int i; uint8_t p00[3]; uint8_t p10[3]; uint8_t p20[3]; uint8_t p30[3]; uint8_t p01[3]; uint8_t p11[3]; uint8_t p21[3]; uint8_t p31[3]; uint8_t p02[3]; uint8_t p12[3]; uint8_t p22[3]; uint8_t p32[3]; uint8_t p03[3]; uint8_t p13[3]; uint8_t p23[3]; uint8_t p33[3]; // 1st row get_pixel_clamped(source_image, xint - 1, yint - 1, p00); get_pixel_clamped(source_image, xint + 0, yint - 1, p10); get_pixel_clamped(source_image, xint + 1, yint - 1, p20); get_pixel_clamped(source_image, xint + 2, yint - 1, p30); // 2nd row get_pixel_clamped(source_image, xint - 1, yint + 0, p01); get_pixel_clamped(source_image, xint + 0, yint + 0, p11); get_pixel_clamped(source_image, xint + 1, yint + 0, p21); get_pixel_clamped(source_image, xint + 2, yint + 0, p31); // 3rd row get_pixel_clamped(source_image, xint - 1, yint + 1, p02); get_pixel_clamped(source_image, xint + 0, yint + 1, p12); get_pixel_clamped(source_image, xint + 1, yint + 1, p22); get_pixel_clamped(source_image, xint + 2, yint + 1, p32); // 4th row get_pixel_clamped(source_image, xint - 1, yint + 2, p03); get_pixel_clamped(source_image, xint + 0, yint + 2, p13); get_pixel_clamped(source_image, xint + 1, yint + 2, p23); get_pixel_clamped(source_image, xint + 2, yint + 2, p33); // interpolate bi-cubically! (i = 0; < 3; i++) { float col0 = cubic_hermite(p00[i], p10[i], p20[i], p30[i], xfract); float col1 = cubic_hermite(p01[i], p11[i], p21[i], p31[i], xfract); float col2 = cubic_hermite(p02[i], p12[i], p22[i], p32[i], xfract); float col3 = cubic_hermite(p03[i], p13[i], p23[i], p33[i], xfract); float value = cubic_hermite(col0, col1, col2, col3, yfract); clamp(value, 0.0f, 255.0f); sample[i] = (uint8_t)value; printf("sample[%d]=%d\n",i,sample[i]); } } 3. "interpolation helpers"
float cubic_hermite(float a, float b, float c, float d, float t) { float = -a / 2.0f + (3.0f*b) / 2.0f - (3.0f*c) / 2.0f + d / 2.0f; float b = - (5.0f*b) / 2.0f + 2.0f*c - d / 2.0f; float c = -a / 2.0f + c / 2.0f; float d = b; return a*t*t*t + b*t*t + c*t + d; } void get_pixel_clamped(ppmimage *source_image, int x, int y, uint8_t temp[]) { clamp(x, 0, source_image->x - 1); clamp(y, 0, source_image->y - 1); temp[0] = source_image->data[x+(w*y)].red; temp[1] = source_image->data[x+(w*y)].green; temp[2] = source_image->data[x+(w*y)].blue; } i've uploaded complete code stuff around here.
there no syntax errors executing code.
but output image confused me.
the input image (21x20pixel):
this input image scaled 2 (42x40pixel):
the interpolation seems work fine @ points, image looks pixels shifted.
can tell me i'm doing wrong? script made of: http://blog.demofox.org/2015/08/15/resizing-images-with-bicubic-interpolation/
thanks guys!
(please don't consider efficiency of code ... aweful know)
from resize_image() function:
destination_image->data[x+((destination_image->y)*y)].red = sample[0]; that should be
destination_image->data[x+((destination_image->x)*y)].red = sample[0]; what helps debugging such cases initializing destination image "magic color" that's not present in actual data (e.g. awful pink:-)). notice destination pixels still have color after resize_image() call. hints problem.


Comments
Post a Comment