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 & HelpSyntax Questions › How to reduce an array to unique values
Page Index Toggle Pages: 1
How to reduce an array to unique values? (Read 546 times)
How to reduce an array to unique values?
Feb 10th, 2009, 4:07pm
 
Hello,

I'm working on a project that involves distilling certain colors from live video - and I've developed code to the point that I can read all the colors in an image into an array, and then sort that array by brightness, saturation, hue, etc.

What I want to do is to take these sorted arrays copy their information to a smaller array that weed out duplicate values.  I know I need to setup some expression that first compares the current to the previous values, and then appends a new value if not matched - and I've done some searching on using Java 'comparators' but so far haven't been able to identify something within the processing code base that would allow me to pull this off.  Any ideas?

Here is my current method:

color[] reduceColors(color[] sorted) {
 color[] sorted = new color[colors.length];
 color[] sorted255 = new color[256];
 for (int j = 0; j <= 255; j++) {
   for (int i = 0; i < sorted.length; i++) {
     if (int(brightness(sorted[i])) == j) {
       sorted255 = append(sorted255, sorted[i]);
     }
   }
 }
 println(sorted255);
 return sorted255;
}
Re: How to reduce an array to unique values?
Reply #1 - Feb 10th, 2009, 6:04pm
 
I see some issues in your code:
- You pass a 'sorted' parameter then hide it with a local variable of same name.
- I don't know where the 'colors' variable comes from (and what it is).
- You allocate 'sorted255' but uses append() which grows the array as needed.

Possible improvement (untested):
Code:
color[] reduceColors(color[] sorted) {
color[] sorted255 = new color[256];
for (int i = 0; i < sorted.length; i++) {
// Store at the rank of the brightness
// the latest color found with this value
sorted255[int(brightness(sorted[i])] = sorted[i];
}
println(sorted255);
return sorted255;
}
Re: How to reduce an array to unique values?
Reply #2 - Feb 10th, 2009, 11:08pm
 
Colors measured from live video are going to include a lot of noise that will make nearby colors (indistinguishable to the human eye) seem different to an algorithm that doesn't account for that.

So, for starters, we'll assume that you're doing some kind of de-noising step first, or that you're looking for an algorithm that is inherently robust to that kind of noise.

Because you're operating on live video, I'm going to assume that you're looking for an algorithm that is FAST.  Methods that rely on ArrayList or other dynamic data structures may not do the job.

I would suggest you make a 3d array of "bins", and use each bin to represent a group of nearby colors in whatever colorspace you're working in.  I'd recommend HSB, because the groupings better match human perception than RGB, but if you're working with video then YUV may be a more natural colorspace.

Each bin can hold either a single bit, if all you care about is presence/absence of a color, or an int if you would also like to count how often each color appears so as to know which colors "really matter" to the image.

Then what you do is really easy:
for each frame:
 * start by setting all the values in bins[] to false (or zero)
 then for each pixel in the image,
   * get its H/S/B values (or Y/U/V values, as appropriate)
   * map those values from their native range to the range of allowable indexes for your 3-d array of bins, obtaining new indexes h/s/b (or y/u/v)
   * set bins[h,s,b] = true (or bins[h,s,v]++ if you're counting)
 Now iterate over the bins[] array
   for any bin that is true (or non-zero), output the color corresponding to the "center" of that bin.  That is, the HSB color with values that are in the middle of each range that still falls within that bin.
Re: How to reduce an array to unique values?
Reply #3 - Feb 11th, 2009, 1:07am
 
to cup,

use a HashMap to store unique values. it will do this automatically - just send it the values.

look up HashMap in the Java Docs for implementation.

-0.
Re: How to reduce an array to unique values?
Reply #4 - Feb 11th, 2009, 4:30am
 
If you just have values, use a Set. Unlike a List, a Set will not add duplicate elements.

While a HashMap will replace duplicate keys, I believe there is a bit more overhead in adding key-value pairs to a HashMap, even if the value for every key is null.

It's a minor point, but set.add(item) is also a little simpler and more clear than map.put(item, null).
Re: How to reduce an array to unique values?
Reply #5 - Feb 11th, 2009, 4:45am
 
Thanks for all of your thoughtful replies - I am working my way through them.
Page Index Toggle Pages: 1