java、imagemagick、またはjmagickを使用して、画像で支配的な色を見つけることができますか?
6 に答える
Javaで各ピクセルを繰り返し、色を決定します
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
public class ImageTester {
public static void main(String args[]) throws Exception {
File file = new File("C:\\Users\\Andrew\\Desktop\\myImage.gif");
ImageInputStream is = ImageIO.createImageInputStream(file);
Iterator iter = ImageIO.getImageReaders(is);
if (!iter.hasNext())
{
System.out.println("Cannot load the specified file "+ file);
System.exit(1);
}
ImageReader imageReader = (ImageReader)iter.next();
imageReader.setInput(is);
BufferedImage image = imageReader.read(0);
int height = image.getHeight();
int width = image.getWidth();
Map m = new HashMap();
for(int i=0; i < width ; i++)
{
for(int j=0; j < height ; j++)
{
int rgb = image.getRGB(i, j);
int[] rgbArr = getRGBArr(rgb);
// Filter out grays....
if (!isGray(rgbArr)) {
Integer counter = (Integer) m.get(rgb);
if (counter == null)
counter = 0;
counter++;
m.put(rgb, counter);
}
}
}
String colourHex = getMostCommonColour(m);
System.out.println(colourHex);
}
public static String getMostCommonColour(Map map) {
List list = new LinkedList(map.entrySet());
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue())
.compareTo(((Map.Entry) (o2)).getValue());
}
});
Map.Entry me = (Map.Entry )list.get(list.size()-1);
int[] rgb= getRGBArr((Integer)me.getKey());
return Integer.toHexString(rgb[0])+" "+Integer.toHexString(rgb[1])+" "+Integer.toHexString(rgb[2]);
}
public static int[] getRGBArr(int pixel) {
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
return new int[]{red,green,blue};
}
public static boolean isGray(int[] rgbArr) {
int rgDiff = rgbArr[0] - rgbArr[1];
int rbDiff = rgbArr[0] - rgbArr[2];
// Filter out black, white and grays...... (tolerance within 10 pixels)
int tolerance = 10;
if (rgDiff > tolerance || rgDiff < -tolerance)
if (rbDiff > tolerance || rbDiff < -tolerance) {
return false;
}
return true;
}
}
Java で簡単に変換できる非常に単純なアルゴリズムをリリースしました。これはcolor-finderと呼ばれ、JavaScript で動作します。
このスレッドで提案されている解決策は、画像内のいくつかの白い文字によって無効になる可能性がありますが、私の場合は、すべてのピクセルが実際にはまったく同じ色でなくても、実際に最も目立つ色を見つけようとします.
これがライブデモです。
便利だと思ったら教えてください。
これは難しい問題です。たとえば、まったく同じ色の小さな領域と、異なる色のわずかに異なる色合いの大きな領域がある場合、最もよく使用される色を単純に探しても、必要な結果が得られる可能性は低くなります。色のセットを定義し、それぞれについて、その色であると見なす RGB 値の範囲を定義すると、より良い結果が得られます。
このトピックは、ImageMagick 談話サーバーで詳しく説明されています。たとえば、http: //www.imagemagick.org/discourse-server/viewtopic.php? f=1&t=12878
画像のドミナント カラーをすばやく取得する方法も参照してください。
プレーンなJavaを使用すると、各ピクセルを反復処理して、各色が含まれる頻度を数えることができます...
疑似コード:
Map<Color, Integer> color2counter;
for (x : width) {
for (y : height) {
color = image.getPixel(x, y)
occurrences = color2counter.get(color)
color2counter.put(color, occurrences + 1)
}
}
(0,0,0) が黒で、(255, 255, 255) が白の加法配色を使用していると仮定します (間違っている場合は修正してください)。また、RGB から支配的な色を見つけたい場合は、次のようにします。
私が持っているアイデアの 1 つは、あなたが自由に精査できる 3 つの変数を持ち、それぞれが RGB 値の 1 つを格納し、それぞれに画像内のすべてのピクセルの適切な値を追加し、(255*numOfPixels) で割ることです。色の比率を取得します。次に、3 つの比率を比較します。赤の .60 と緑の .5 は、赤がより支配的であることを意味します。
これは単なるアイデアであり、微調整が必要な場合があります...