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 › average array of PImages to create new PImage
Page Index Toggle Pages: 1
average array of PImages to create new PImage (Read 1608 times)
average array of PImages to create new PImage
Apr 20th, 2010, 3:32pm
 
Hey Guys

I'm currently working a project and I'm afraid I've run into a bit of a conceptual road block.

What I'm trying to do is create a program which will allow the user to search flickr for images based on an input parameter, ie "dog" returns a list of images tagged as dog.

I've been able to get this portion of the code working thanks to the sketch by Brian Chung - http://www.bryanchung.net/?p=189

import proxml.*;

String userName = "";
String apiKey = "";
String nsid;
String url = "http://api.flickr.com/services/rest/";
String search = "panda";
XMLInOut xml = null;

void setup() {
 size(600,600);
 background(0);
 frameRate(15);
 xml = new XMLInOut(this);
}

void draw() {
}

void mousePressed() {
 photoSearch(search);
 //search = "bill gates";
}

void photoSearch(String _n) {
 String rest = url+"?method=flickr.photos.search";
 rest += "&api_key=" + apiKey;
 rest += "&text=" + search;
 xml.loadElement(rest);
}

void pandaPhotos(String _n) {
 String rest = url+"?method=flickr.panda.getPhotos";
 rest += "&api_key=" + apiKey;
 rest += "&username=" + _n;
 xml.loadElement(rest);
}

void interestingness(String _n) {
 String rest = url+"?method=flickr.interestingness.getList";
 rest += "&api_key=" + apiKey;
 rest += "&username=" + _n;
 xml.loadElement(rest);
}

void findByUsername(String _n) {
 String rest = url+"?method=flickr.people.findByUsername";
 rest += "&api_key=" + apiKey;
 rest += "&username=" + _n;
 xml.loadElement(rest);
}

void getPublicPhotos(String _n) {
 String rest = url+"?method=flickr.people.getPublicPhotos";
 rest += "&api_key=" + apiKey;
 rest += "&user_id=" + nsid;
 xml.loadElement(rest);
}



////////////////////////////////////////////////////

//               xmlEvent funcitons              //

////////////////////////////////////////////////////


void xmlEvent(proxml.XMLElement _x) {
 parseXML(_x);
}

void parseXML(proxml.XMLElement _x) {
 String stat = _x.getAttribute("stat");
 if (!stat.equals("ok")) {
   println("Error from Flickr");
   return;
 }
 proxml.XMLElement node = _x.getChild(0);
 String type = node.getName();
 if (type.equals("user")) {
   nsid = node.getAttribute("nsid");
   println(nsid);
   getPublicPhotos(nsid);
 }
 else if (type.equals("photos")) {
   int num = node.countChildren();
   println(num);
   getPhotos(node);
 }
}

void getPhotos(proxml.XMLElement _n) {
 int cnt = _n.countChildren();
 cnt = min(cnt,64);
 for (int i=0;i<cnt;i++) {
   proxml.XMLElement ph = _n.getChild(i);
   String fm = ph.getAttribute("farm");
   String sv = ph.getAttribute("server");
   String id  = ph.getAttribute("id");
   String sc = ph.getAttribute("secret");
   String imgURL = "http://farm"+fm+".static.flickr.com/"+
     sv + "/" + id + "_" + sc + "_s.jpg";
   PImage img = loadImage(imgURL);
   int x = (i%8) * img.width;
   int y = (i/8) * img.height;
   image(img,x,y);
 }
}

In my sketch I'd like to take the PImages created in void getPhotos(proxml.XMLElement _n) and store them into an array from which I could then theoretically compare the pixels in each image to create an "averaged" image.

This is where I'm running into trouble. I'm not really sure how to compare the pixels from a PImage array.

Here is what I've written so far-

void getPhotos(proxml.XMLElement _n) {

 int cnt = _n.countChildren();
 cnt = max(cnt,64);
 for (int i=0;i<cnt;i++) {
   proxml.XMLElement ph = _n.getChild(i);
   String fm = ph.getAttribute("farm");
   String sv = ph.getAttribute("server");
   String id  = ph.getAttribute("id");
   String sc = ph.getAttribute("secret");
   String imgURL = "http://farm"+fm+".static.flickr.com/"+
     sv + "/" + id + "_" + sc + "_s.jpg";

// new stuff

   PImage[] img = new PImage[_n.countChildren()];
   //PImage img = loadImage(imgURL);

   for ( int j = 0; j< img.length; j++ ) {

     img[j] = loadImage(imgURL);

     // int dimension = (img[j].width*img[j].height);

     // nested forloop reads the RGB values for each pixel in img[j]

     for (int x = 0; x < img[j].width; x++) {
       for (int y = 0; y < img[j].height; y++) {

         int loc = x + y*img[j].width; // var to store the location of each pixel within the image

         float r = red( (img[j].pixels[loc]) );
         float g = green( (img[j].pixels[loc]) );  
         float b = green( (img[j].pixels[loc]) );
       }
     }
   }
 }
}

Accessing the RGB values of each pixel in a photo seems to make sense, but I'm not sure how to go about comparing the pixels of different images given the above method. Is there a better way to go about doing this? Any and all help would be most appreciated! Thanks!

Re: average array of PImages to create new PImage
Reply #1 - Apr 20th, 2010, 6:55pm
 
if you a sure about the images have the same size...
one loop running through the pixelarray should also be fine

int l = img.width* img.height;
for (int i = 0; i < l; i++) {
color c = img.pixels[i];
red = red(c);
...
}

yea, now what do you mean with compare is the question.
Re: average array of PImages to create new PImage
Reply #2 - Apr 20th, 2010, 8:01pm
 
Thanks Ramin, using one loop totally makes more sense. Each image called by flickr is just a thumbnail which is 75x75 pixels so that should definitely simplify things.

By compare I meant take a look at each pixel[i] in every image, and average the RGB values of each pixel[i] to its corresponding pixel in the other images.

So for each image thumbnail there are 5625 pixels, so I would like to compare the RGB data for pixel 1, in every image and then create an new "averaged" RGB value based off that data. Sorry if this doesnt really make sense, but does that help clarify?
Re: average array of PImages to create new PImage
Reply #3 - Apr 21st, 2010, 4:44am
 
ok. mh no it sounds interesting. i am interested what comes out if you use alot images. something nice sometimes. maybe sometimes chaotic mud.

so if you know the number n of images. like you did before surround this loop with a second that checks all images. you should save the sum of color values in a  array of PVector at first.
PVector[] sum = new PVector[5625];
so in the inner loop you can sum up:
sum[i].add(red(c),...);

and after the loops run again trhough the array and
divide each PVector by n.

so now you have the averaged colors in that PVectors and can create a new Image...
PImage AvgImg = new PImage(RGB,75,75);
run trhough the array again and set each pixel to its corresponding color you have saved in the PVector...
AvgImg.pixels[i] = color(sum[i].x,sum[i].y,sum[i].z);
you can do that in the same loop, where you divide the PVectors by n.
you can copy your code if it doesnt work and need yomething different.
Re: average array of PImages to create new PImage
Reply #4 - Apr 21st, 2010, 3:03pm
 
Hey Ramin, Thanks again for the reply.

I'm not sure I quite understand what you mean. I'm relatively new to programming and I havent worked with PVectors yet so I'm a little confused on how I would structure this code. Do you think you could give me a little more in depth example of what you mean?

heres my initial stab at it which doesnt work -

     PImage[] img = new PImage[100];

     for ( int j = 0; j< img.length; j++ ) {
 
       img[j] = loadImage(imgURL);
       int numPixels = img[j].width*img[j].height;

       PVector[] sum = new PVector[numPixels];
       
         for (int k = 0; k < numPixels; k++) {    
           color c = img[j].pixels[i];
           sum[numPixels].add( red(c),green(c),blue(c) );
       }
         
         for (int h = 0; h < numPixels; h++) {
           
           sum[numPixels].div(numPixels);
           PImage AvgImg = new PImage(RGB,75,75);
           AvgImg.pixels[i] = color(sum[j].x,sum[j].y,sum[j].z);
           image(AvgImg, width/2,height/2);  
       }
     }
   }

I'm getting a Array Index Out of Bounds Exception: 5625 at- sum[numPixels].add( red(c),green(c),blue(c) );      
Re: average array of PImages to create new PImage
Reply #5 - Apr 21st, 2010, 6:29pm
 
you have to keep an eye on the variables. which values they have and which you use for the loop. the sum array is of the length numPixels
so its from sum[0] to sum[numPixels-1]. you have to use the k variable which runs from 0 to numPixels.

i wrote this method that does it:
Code:

PImage imageMixer(PImage[] img) {

 // you only need this once, cause images might hav the same size
 // so we take the first image to get the numPixels
 // but it could be any of them
 int numPixels = img[0].width*img[0].height;
 PVector[] sum = new PVector[numPixels];

 // now we sum up: for each Image
 for ( int j = 0; j< img.length; j++ ) {
   // go through the pixels and sum up
   for (int k = 0; k < numPixels; k++) {    
     color c = img[j].pixels[k];
     // in an array of objects unlike standard types you need to //construct each one (once)
     // we could make this an own loops. but the less loops the //better(tho for 75x75 its not so wild)
     if(j==0)
     sum[k] = new PVector(red(c),green(c),blue(c));
     else
    sum[k].add( red(c),green(c),blue(c) );
   }
 }

 // dividing and saving into a new image
 // RGB at the end. my mistake
 PImage AvgImg = createImage(img[0].width,img[0].height,RGB);
 for (int k = 0; k < numPixels; k++) {
   sum[k].div(img.length);
   AvgImg.pixels[k] = color(sum[k].x,sum[k].y,sum[k].z);
 }
 return AvgImg;
}


Re: average array of PImages to create new PImage
Reply #6 - Apr 22nd, 2010, 5:42pm
 
great thank you! this makes a lot more sense.
Page Index Toggle Pages: 1