We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Image warping/morphing
Page Index Toggle Pages: 1
Image warping/morphing (Read 6623 times)
Image warping/morphing
Jan 29th, 2006, 9:50pm
 
I did a search on the alpha and beta discourse but I could not find any reference to examples of image warping in Processing, and I do not understand the algorithms I found through Google; Does anyone know of any simple and efficient image warping alorithms based off of a grid system? Perhaps I am not searching for the right terms. Also I dont want to warp/morph between two images... I want to make a grid/point interface where a user can drag the points and warp the image. Thanks.
Re: Image warping/morphing
Reply #1 - Jan 29th, 2006, 9:57pm
 
It's quite simple.  Draw the image as a grid of polygons.  You can use the vertex() method with u and v coordinates to specify a piece of the original image, then simply use a nested for loop to draw all the squares that make up the full image.

For warping, simply displace the coordinates of the grid points.

Marcello
Re: Image warping/morphing
Reply #2 - Jan 29th, 2006, 10:03pm
 
How do I draw an image inside a polygon. The image properties seem to only permit squares or rectangles.
Re: Image warping/morphing
Reply #3 - Jan 29th, 2006, 11:18pm
 
The answer is... textures.
Re: Image warping/morphing
Reply #4 - Mar 3rd, 2009, 12:19am
 
Hey guys I'm trying to create a program that will warp an image too. I've follwed the steps for drawing the image as a set of polygons, but I don't know what it means to draw all the squares that make up the full image. Can anyone help please?

Here's my simple code so far:


PImage img;

void setup() {
 size(350,350,P3D);
 img = loadImage("image.jpg");
}

void draw() {
   beginShape();
   texture(img);
   // Top-Left
   vertex(0,0,0,0);
   // Top-Right
   vertex(350,0,350,0);
   // Bottom-Right
   vertex(350,350,350,350);
   // Bottom-Left
   vertex(0,350,0,350);
   endShape();
}
Re: Image warping/morphing
Reply #5 - Mar 3rd, 2009, 6:54pm
 
While mapping the image to a polygon surface and then deforming the surface will work, that is IMHO a very overkill method.

Image warping is really just a process for taking each coordinate in the destination image, mapping it through some function to yield coordinates in the original image, then copying the pixel at the mapped coordinates in the original image to the proper coordinates in the destination image.

If your goal is to play with image warping and get a sense for how that works, IMHO, don't distract yourself with all this business of building a polygon mesh and texture mapping the image onto it.  That technique certainly has its place in the world, but a more straightforward method of mapping pixels from source image to destination image gives you a much more direct appreciation for what's going on, it's a lot shorter to code, and makes it a lot easier for you just to play around with different formulas to see what happens to the image.  Here's a quick example to get you started:

PImage source, destination;

void setup()
{
 source = loadImage("liberty_3.jpg");  // fill in your own image here
 size(source.width, source.height);
 noLoop();
 destination = warp(source);
}

void draw()
{
 image(destination, 0, 0);
}

// implement a simple vertical wave warp.
PImage warp(PImage source)
{
 float waveAmplitude = 20, // pixels
       numWaves = 5;       // how many full wave cycles to run down the image
 int w = source.width, h = source.height;
 PImage destination = new PImage(w,h);
 source.loadPixels();
 destination.loadPixels();

 float yToPhase = 2*PI*numWaves / h; // conversion factor from y values to radians.

 for(int x = 0; x < w; x++)
   for(int y = 0; y < h; y++)
   {
     int newX, newY;
     newX = int(x + waveAmplitude*sin(y * yToPhase));
     newY = y;
     color c;
     if(newX >= w || newX < 0 ||
        newY >= h || newY < 0)
       c = color(0,0,0);
     else
       c = source.pixels[newY*w + newX];
     destination.pixels[y*w+x] = c;
   }
 return destination;
}
Re: Image warping/morphing
Reply #6 - Mar 4th, 2009, 12:55pm
 
Thanks a lot for that it has really helped. I understand that you can shrink, expand and move the image(or in your case, create the wave effect)around by either adding, subtracting, dividing or multiplying the values in 'newX' and/or 'newY'.

But I've noticed that this only warps the image as a whole. How do I go about warping certain areas of an image? For example, if the source image is an image of a face, I would like to warp the lips so that I can make it smile or frown.    
Re: Image warping/morphing
Reply #7 - Mar 4th, 2009, 1:07pm
 
This thread might interest you: Help: making a 'caricature' of an image
Re: Image warping/morphing
Reply #8 - Mar 4th, 2009, 6:41pm
 
> But I've noticed that this only warps the image as a whole. How do I go about warping certain areas of an image? For example, if the source image is an image of a face, I would like to warp the lips so that I can make it smile or frown.

That would just mean that for most of the image, newX = x and newY = y (a so-called "identity" transform), while in the region of interest you use some other formula.

Note that unless you take some pains to smooth out the area where you transition from identity transform to something else, you're likely to end up with ugly visual artifacts at those edges.  One strategy is to define an area around the area of interest, in which you linearly interpolate between the identity transform at the "outer" edge to whatever else at the "inner" edge.  In that way, you smoothly transition from regular coordinates to transformed coordinates, and greatly minimize any discontinuities associated with going from the unwarped to the warped parts of the image.
Re: Image warping/morphing
Reply #9 - Mar 13th, 2009, 6:25pm
 
Thanks, I know that for most of the image, newX = x and newY = y, and by changing those values the whole image can be warped. But as i said earlier, I want to be able to warp any coordinates inside the image.
Re: Image warping/morphing
Reply #10 - Mar 13th, 2009, 8:54pm
 
I think it was pretty well explained in the earlier parts of the thread.  Read them again.

If you want to modify the WHOLE image in a consistent way, apply the same coordinate transformation to every pixel, as shown by my sample code.

If you want to modify PART of an image, then in that part of the image you transform the coordinates in some manner, but in the rest of the image you leave them alone.  Here's a cheezy modification to my other code that only applies the transformation within a circle at the center of the image:

PImage warp(PImage source)
{
 float waveAmplitude = 20, // pixels
       numWaves = 5;       // how many full wave cycles to run down the image
 int w = source.width, h = source.height;
 PImage destination = new PImage(w,h);
 source.loadPixels();
 destination.loadPixels();

 float yToPhase = 2*PI*numWaves / h; // conversion factor from y values to radians.

 for(int x = 0; x < w; x++)
   for(int y = 0; y < h; y++)
   {
     // In a 100-pixel radius circle around the center, apply a sine-wave transform.
     if(sqrt((x-width/2)*(x-width/2) + (y-height/2)*(y-height/2)) < 100)
     {
       int newX, newY;
       newX = int(x + waveAmplitude*sin(y * yToPhase));
       newY = y;
       color c;
       if(newX >= w || newX < 0 ||
          newY >= h || newY < 0)
         c = color(0,0,0);
       else
         c = source.pixels[newY*w + newX];
       destination.pixels[y*w+x] = c;
     }
     else // everywhere else, just copy pixels straight over.
       destination.pixels[y*w+x] = source.pixels[y*w+x];
   }
 return destination;
}

If you compare this with my original, you'll see that there's hardly any difference in the code; it just restricts the effect to a particular area.  To do something more interesting, you'll want to change the condition inside of this if() statement:

if(sqrt((x-width/2)*(x-width/2) + (y-height/2)*(y-height/2)) < 100)

to only select the area you want to modify.
Re: Image warping/morphing
Reply #11 - Feb 3rd, 2010, 10:46pm
 
i have this code that loads a blurred black and white image , then according to the gray values of the loaded image creates line warps that define the surface with a z vaule of elevation.

i want achieve a similar effect. however,  except rather than defining the surface with lines i want to load a second image and have it warp according to the gray values in 1st image.

cutting my teeth on processing. any help would be awsome!

here is the initial code for the line warping:

import processing.opengl.*;

int gap;
int num_lines;
float z_value;
PImage img;
float value;
color[] myarr;
boolean dosave=true;


void setup(){
size(1000, 800, OPENGL);
background(0);
strokeWeight(0.2);

noLoop();

gap = 8;
z_value = 50;
num_lines = floor(height/gap);


PImage img = loadImage("image.jpg");// black and white image with a blur for  smooth warping lines
image(img,0,0);
loadPixels();

myarr= new color[pixels.length];

for (int i=0; i <(width*height) -1; i++){
float brg = brightness(pixels[i]);
myarr[i] = abs ((int) brg);
}
}

void draw(){
background(0);
stroke(255);
strokeWeight(1);
fill(0);
smooth();
pushMatrix();

translate(width/2, height/2);

rotateX(PI/6);
rotateZ(0);

scale(1);
translate(-width/2,-height/2);

for (int i=0; i < num_lines; i++){
beginShape();
for ( int j=0; j < width; j++){ // x resolution

value = map (myarr[i*gap*width+j],0, 255, 0, z_value);
vertex(j, i*gap, value);

}
endShape();

}

popMatrix();
save("image.tif");

if(dosave) {
endRaw();
dosave=false;
}

}
Re: Image warping/morphing
Reply #12 - Jun 10th, 2010, 11:12am
 
For those who want to know the actual mathematical technique for morphing, and they are familiar with basic linear algebra,  
google: beier morphing

Just combine this technique with the pixel-polygon stuff mentioned above, and it wouldn't be so hard.
Page Index Toggle Pages: 1