How to efficiently count the number of unique colors in Java
How to efficiently count the number of unique colors in Java?
How to efficiently count the number of unique colors in Java?
Hi costa_974!
The problem you have is not that simple : color is something very hard to define ;-) But if you just want to count the different values your Mat contains, the best you can do is to follow the C# example. I don't have opencv java-binding enabled here so I can't test if the solution I suggest is correct, but here is the idea:
import java.util.HashSet;
public static void main(String[] args) {
Mat m = ... your stuff here. I suppose a CV_U8 matrix
int size = (int)m.total();
int nbChannels = m.channels();
byte[] temp = new byte[size * nbChannels];
m.get(0, 0, temp);
Set<Integer> set = new HashSet<Integer>();//will contain all different values
for (int i = 0; i < size; i++)
{
int pixelVal = 0;
for(int j=0; j<nbChannels; j++)
pixelVal+= (temp[i*nbChannels+j] << (8*j));
set.add(pixelVal);
}
System.out.println("Color number : " + set.size());
}
An other version (but doesn't seems to work) using double conversion in order to deal with unsigned char matrix...
import java.util.HashSet;
public static void main(String[] args) {
Mat m = //... your image here.
Mat dblImg = new Mat();//use double as unsigned byte doesn't exist in java...
if(m.channels()==3)
m.convertTo(dblImg, CvType.CV_64FC3);
else
m.convertTo(dblImg, CvType.CV_64FC1);
int size = (int)m.total();
int nbChannels = m.channels();
double[] temp = new double[size * nbChannels];
dblImg.get(0, 0, temp);
Set<Double> set = new HashSet<Double>();//will contain all different values
for (int i = 0; i < size; i++)
{
double pixelVal = temp[i*nbChannels];
for(int j=1; j<nbChannels; j++)
pixelVal+= (temp[i*nbChannels+j] * 256. * j);
set.add(pixelVal);
}
System.out.println("Color number : " + set.size()) ;
}
I hope this will solve your problem!
I updated some part of the code as it seems to exist some problem with Byte values!
also, the c++ version returns the same count as your java byte[] version before. (the double[] one returns less)
Ok thank you very much! But I think that java will be a little slow iterating every pixel... I hoped there was a fast native method.
But... by the way... do you know that opencv.org is not accessible since 2 days... Site not configured, Coming soon: Another fine website hosted by WebFaction.
@berak If the byte[] version works, it's indeed the best way to do this. I will then post the two version...
@costa_974 I noticed this before, they are probably working on that. Maybe you can fill a bug report in code.opencv.org, but I'm not sure it's the right place to do that...
not all images are rgba, most algos work on plain grayscale(1channel) even.
also, alpha is most useless to computer-vision..
don't worry, that looks more like someone's working on it.
the docs are still there, if you need them.
( i'm more hoping, they're transferring to a better hoster.. )
Asked: 2014-10-20 15:07:53 -0600
Seen: 3,034 times
Last updated: Oct 24 '14
Can you be a little more explicit? What is unique color?
Well what you should do is the following
It's much simpler... let's rephrase the question in "How to efficiently count colors in a Mat object in Java", without "unique"... I know there's cvCountNonZero, but I have to split the channels... etc, or I could iterate every pixels. I would like a simple way to count colors like in Photoshop fo example. Thanks.
I would not suggest you to iterate, because it is slow, here is the documentation of split and using cvCountNonZero, I do not think is really what you want, can you give a link of Photoshop color counter?
@costa_974, even if you just count colors. Then the combination is still endless if you do not predefine what you see as colors. With an 8 bit image and 3 channels RGB you have multiple thousands of comibnations. Keep in mind that color is NOT the same for a PC as for a human eye!
c# code: public static int CountImageColors(string fileName) { int count = 0; HashSet<Color> colors = new HashSet<Color>(); Bitmap bmp = null;
OpenCV doesn't support C# probably you are using a wrapper? You should then address forum related to that wrapper and not this one.
ok... you guys are too smart! i'm not able to be clear! the c# code is just an example! how can I do the same in opencv? I just want to count the colors in a image!