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 › Help with color averaging multiple image files.
Page Index Toggle Pages: 1
Help with color averaging multiple image files. (Read 1403 times)
Help with color averaging multiple image files.
Jul 10th, 2008, 3:46pm
 
Hi,

I'm new to processing and still trying to wrap my head around the language. I'll have to admit, with only some experience using PHP, processing and OOP are a little intimidating.

I'm trying to develop a program that does as follows:

- Reads a directory of .jpegs from a local disk ( 0001.jpeg, 0002.jpeg etc.)
- Averages the color within each image
- Creates a "duplicate" for each image, using only the averaged color from the source image. (a one color jpeg)
- Writes each new image to a different directory or sub-directory with incremental naming.

I've been plowing through the forums and handbook, finding several examples that seem to work for each stage, but I'm having trouble understanding how to patch everything together into one program.

For the averaging process I've been using Huskee's code from http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Programs;action=display;num=1203885612;start=10#10

Quote:


PImage img;

int cellSize = 4;
int cols, rows;
int numPix;
int avgRed, avgGreen, avgBlue;
int brgtnss;
int factor = 40;
int f_red,f_green,f_blue;
float r,g,b,c_red,c_green,c_blue,c_r,c_g,c_b;
float d_red,d_green,d_blue,lerp_r,lerp_g,lerp_b;

void setup(){
 img = loadImage("wgreen.jpg"); // loads the Image
 size(img.width, img.height);
 colorMode(RGB, 255,255,255,100); // setting colormode

 cols = width / cellSize;
 rows = height / cellSize;

 numPix = rows * cols;
}



void draw (){
 image(img,0,0);
 for (int i = 0; i < cols ; i++) {
   for (int j = 0; j < rows ; j++) {

int x = i*cellSize;
int y = j*cellSize;
int loc = x + y*width;

r = red(img.pixels[loc]);
g = green(img.pixels[loc]);
b = blue(img.pixels[loc]);

float PixelBrightness = brightness(img.pixels[loc]);
brgtnss += PixelBrightness;

avgRed += r;
avgGreen += g;
avgBlue += b;

if(i == cols);
noLoop();
   }
 }
avgRed = avgRed/numPix;
avgGreen = avgGreen/numPix;
avgBlue = avgBlue/numPix;

brgtnss = brgtnss/(factor*numPix);

// calculates the dominant color and returns a factor between 0.? and 1
if ((avgRed >= avgGreen)&&(avgRed >= avgBlue)) {
  f_red = 1;
  f_green = avgGreen/avgRed;
  f_blue = avgBlue/avgRed;
} else if ((avgGreen >= avgRed)&&(avgGreen >= avgBlue)) {
  f_red = avgRed/avgGreen;
  f_green = 1;
  f_blue = avgBlue/avgGreen;
} else if ((avgBlue >= avgRed)&&(avgBlue >= avgGreen)) {
  f_red = avgRed/avgBlue;
  f_green = avgGreen/avgBlue;
  f_blue = 1;
}

color average = color(avgRed,avgGreen,avgBlue,100); // simple average calculation
c_red = brgtnss*avgRed;
c_green = brgtnss*avgGreen;
c_blue = brgtnss*avgBlue;



float m = millis(); // performance

println(brgtnss + "   " + lerp_r + " : " + lerp_g + " : " + lerp_b + " | " + m + " msecs since start");

fill(average);
stroke(0);
rect (10,10,100,60);
}




Can anyone point me in the right direction?
Any help would be wonderful.
Rob

Re: Help with color averaging multiple image files
Reply #1 - Jul 15th, 2008, 10:46am
 
hi,

for this you don't need many classes, but can do it with several methods and some global variables.
the averaging stuff can be in a seperate method. this method get have a PImage as Parameter and as a return a new PImage which just has the average color.
In your setup method you can run through your image-source directory get pics of it and turn them to one-colored images which would be saved in any destination.
You can get through all files in a directory with
Code:

String source= "C:/pics";
String dest= "C:/pics/avg";
File dir= new File(source);
if(dir.isDirectory) {
File[] fs= dir.listFiles();
for(int i=0; i< fs.length; i++) {
if(fs[i].getName().endsWith(".jpg"){
PImage srcImg = loadImage(source++"/"+fs[i].getName());
PImage newImg = avg(srcImg);
savetoDest(newImg,i); // i as counter in the new //names
}
}
}

i hope this can help you. i've just written it here so its just a sketch how you can do it.
Re: Help with color averaging multiple image files
Reply #2 - Jul 16th, 2008, 10:26pm
 
Thanks for the help,

I'm still confused as how to create the a new PImage after the source PImage color has been averaged.

I was looking at using antiplastik's java.io.File listing hack to create an array that would contain the list of files to be converted and have got it working. Although, I have no idea how to construct a process that would loop through each image and output a new jpeg.

Would this be written in void setup();? Or would I create a new class or function to be called within some sort of loop statement?

Usually after some experimentation and poking around I can come up with something, but as of yet I'm not getting very far.
Re: Help with color averaging multiple image files
Reply #3 - Jul 16th, 2008, 11:04pm
 
Q: Would this be written in void setup();?
R: Yes. Or in void draw() but then you'll have to call noLoop() in setup so it only runs once. As far as I understand, you want to process a list of files and then exit, so there is no need to make the draw() method loop.

What you could do : in your code below, rename void draw() into, for example, void processImage(PImage img, int i). At the very end of this method, call save("yourfilename" + i + ".png").

Then, in setup, get through all files you want to process as ramin showed you or as explained in the hacks section, and call processImage(srcImg, i) for each image file you've found in the directory.


Quote:
// <-- global variables

void setup() {
 // <-- get an array of filenames to process
 for (int i = 0; i < filenames.length; i++) {
   PImage imgToProcess = loadImage(filenames[i]);
   processImage(imgToProcess, i);
 }
}

void processImage(PImage img, int i) {
 // <-- process the image
 save("myimage" + i + ".png");
}
Re: Help with color averaging multiple image files
Reply #4 - Jul 22nd, 2008, 3:54am
 
antiplastik,

That makes sense to me, and I've been trying to get my method to work correctly following your example, but I keep running into a null pointer exception. I can not tell if I'm loading the images correctly, or if the function processImage() actually has anything to process.

The directory listed in the sketch has four images, 1.jpg, 2.jpg etc...


And here is where I am at,

Quote:


PImage imgToProcess;

int cellSize = 4;
int cols, rows;
int numPix;
int avgRed, avgGreen, avgBlue;
int brgtnss;
int factor = 40;
int f_red,f_green,f_blue;
float r,g,b,c_red,c_green,c_blue,c_r,c_g,c_b;
float d_red,d_green,d_blue,lerp_r,lerp_g,lerp_b;


void setup() {

 // we'll have a look in the data folder
 java.io.File folder = new java.io.File(dataPath("/Users/robmk/Desktop/average_images"));

 // let's set a filter (which returns true if file's extension is .jpg)
 java.io.FilenameFilter jpgFilter = new java.io.FilenameFilter() {
   boolean accept(File dir, String name) {
     return name.toLowerCase().endsWith(".jpg");
   }
 };

 // list the files in the data folder, passing the filter as parameter
 String[] filenames = folder.list(jpgFilter);

 // get and display the number of jpg files
 println(filenames.length + " jpg files in specified directory");

 // display the filenames
 for (int i = 0; i < filenames.length;i++) {

   println(filenames[i]); //make sure files exist


   PImage imgToProcess = loadImage(filenames[i]);

   size(640, 480);
   colorMode(RGB, 255,255,255,100); // setting colormode

   cols = width / cellSize;
   rows = height / cellSize;

   numPix = rows * cols;

   processImage(imgToProcess, i);
 }
}


void processImage(PImage img, int i) {
 // <-- process the image
 for (int q = 0; q < cols ; q++) {
   for (int j = 0; j < rows ; j++) {

     int x = q*cellSize;
     int y = j*cellSize;
     int loc = x + y*width;

     r = red(img.pixels[loc]);
     g = green(img.pixels[loc]);
     b = blue(img.pixels[loc]);

     float PixelBrightness = brightness(img.pixels[loc]);
     brgtnss += PixelBrightness;

     avgRed += r;
     avgGreen += g;
     avgBlue += b;

     if(q == cols);
     noLoop();
   }
 }
 avgRed = avgRed/numPix;
 avgGreen = avgGreen/numPix;
 avgBlue = avgBlue/numPix;

 brgtnss = brgtnss/(factor*numPix);

 // calculates the dominant color and returns a factor between 0.? and 1
 if ((avgRed >= avgGreen)&&(avgRed >= avgBlue)) {
   f_red = 1;
   f_green = avgGreen/avgRed;
   f_blue = avgBlue/avgRed;
 }
 else if ((avgGreen >= avgRed)&&(avgGreen >= avgBlue)) {
   f_red = avgRed/avgGreen;
   f_green = 1;
   f_blue = avgBlue/avgGreen;
 }
 else if ((avgBlue >= avgRed)&&(avgBlue >= avgGreen)) {
   f_red = avgRed/avgBlue;
   f_green = avgGreen/avgBlue;
   f_blue = 1;
 }

 color average = color(avgRed,avgGreen,avgBlue,100); // simple average calculation
 c_red = brgtnss*avgRed;
 c_green = brgtnss*avgGreen;
 c_blue = brgtnss*avgBlue;



 float m = millis(); // performance

 println(brgtnss + "   " + lerp_r + " : " + lerp_g + " : " + lerp_b + " | " + m + " msecs since start");

 fill(average);
 stroke(0);
 rect (10,10,100,60);

 save("myimage" + i + ".png");
}


Page Index Toggle Pages: 1