0

I'm using this article: nonlingr as a font to understand non linear transformations, in the section GLYPHS ALONG A PATH he explains how to use a parametric curve to transform an image, i'm trying to apply a cubic bezier to an image, however i have been unsuccessfull, this is my code:

OUT.aloc(IN.width(), IN.height());

        //get the control points...
        wVector p0(values[vindex], values[vindex+1], 1);
        wVector p1(values[vindex+2], values[vindex+3], 1);
        wVector p2(values[vindex+4], values[vindex+5], 1);
        wVector p3(values[vindex+6], values[vindex+7], 1);

        //this is to calculate t based on x
        double trange = 1 / (OUT.width()-1);

        //curve coefficients
        double A = (-p0[0] + 3*p1[0] - 3*p2[0] + p3[0]);
        double B = (3*p0[0] - 6*p1[0] + 3*p2[0]);
        double C = (-3*p0[0] + 3*p1[0]);
        double D = p0[0];

        double E = (-p0[1] + 3*p1[1] - 3*p2[1] + p3[1]);
        double F = (3*p0[1] - 6*p1[1] + 3*p2[1]);
        double G = (-3*p0[1] + 3*p1[1]);
        double H = p0[1];

        //apply the transformation
        for(long i = 0; i < OUT.height(); i++){
            for(long j = 0; j < OUT.width(); j++){
                //t = x / width
                double t = trange * j;

                //apply the article given formulas                  

                double x_path_d = 3*t*t*A + 2*t*B + C;
                double y_path_d = 3*t*t*E + 2*t*F + G;

                double angle = 3.14159265/2.0 + std::atan(y_path_d / x_path_d);

                mapped_point.Set((t*t*t)*A + (t*t)*B + t*C + D + i*std::cos(angle),
                                 (t*t*t)*E + (t*t)*F + t*G + H + i*std::sin(angle),
                                 1);
                //test if the point is inside the image
                if(mapped_point[0] < 0 || 
                   mapped_point[0] >= OUT.width() || 
                   mapped_point[1] < 0 ||
                   mapped_point[1] >= IN.height())
                    continue;

                OUT.setPixel(
                    long(mapped_point[0]), 
                    long(mapped_point[1]), 
                    IN.getPixel(j, i));
            }
        }

Applying this code in a 300x196 rgb image all i get is a black screen no matter what control points i use, is hard to find information about this kind of transformation, searching for parametric curves all i find is how to draw them, not apply to images. Can someone help me on how to transform an image with a bezier curve?

Paulo Marcio
  • 263
  • 3
  • 13

1 Answers1

0

IMHO applying a curve to an image sound like using a LUT. So you will need to check for the value of the curve for different image values and then switch the image value with the one on the curve, so, create a Look-Up-Table for each possible value in the image (e.g : 0, 1, ..., 255, for a gray value 8 bit image), that is a 2x256 matrix, first column has the values from 0 to 255 and the second one having the value of the curve.

sop
  • 3,445
  • 8
  • 41
  • 84