2010-12-13 15 views
9

का सबसे आम रंग हो रही है मैं एक छवि से सबसे आम रंग प्राप्त करना चाहते हैं। मैं जावा का उपयोग करता हूं और मैं सबसे प्रमुख रंग चाहता हूं। क्या यह करने के लिए कोई cbir जावा पुस्तकालय है?एक छवि

धन्यवाद

+0

वास्तव में क्या आप "प्रमुख" मतलब है ठीक, त्वरित प्रतिक्रिया काम कर रहा है? – Thomas

+0

छवि में सबसे आम रंग? –

उत्तर

2

आप कर सकते हैं पाश BufferedImage (दो छोरों - 0 से चौड़ाई के एक है, और 0 से ऊंचाई तक एक), और कॉल getRgb(x, y) मिलता है। फिर प्रत्येक अलग मूल्य गिनें। आप उस के लिए Map का उपयोग कर सकते हैं (कुंजी = रंग, मूल्य = अवसरों की संख्या)।

+0

वास्तव में? 16,581,375 रंग हो सकते हैं। – dogbane

+0

तो आप स्मृति के बारे में चिंता करते हैं? – Bozho

+2

हां। बस मेरे पीसी हो सकता है, लेकिन मेरे मानचित्र में लगभग 4 मिलियन रंगों के बाद मुझे ओओएम मिला। – dogbane

9

कितनी सटीक आप इस बनना चाहते हो? आप पूरी छवि पर बोझोस के दृष्टिकोण और लूप का उपयोग कर सकते हैं लेकिन यह बड़ी छवियों के लिए धीमा हो सकता है। 16777216 संभावित आरजीबी मूल्य हैं और मानचित्र में उनके लिए काउंटर रखने के लिए बहुत ही कुशल नहीं है।

एक विकल्प यह है कि इसे getScaledInstance का उपयोग करके छवि को एक छोटे संस्करण में स्केल करने के लिए दोहराना है। एक 1x1 छवि और उसके बाद उस पिक्सेल का रंग प्राप्त करने के लिए getRGB का उपयोग करें। आप क्या आपके लिए सबसे अच्छा काम करता है देखने के लिए इस तरह के SCALE_REPLICATE और SCALE_AREA_AVERAGING के रूप में विभिन्न resampling एल्गोरिदम के साथ प्रयोग कर सकते हैं।

+0

ध्यान दें कि यह दृष्टिकोण बोझोस के दृष्टिकोण से अलग परिणाम देगा। उत्तरार्द्ध में, छवि में सबसे अधिक बार दिखाई देने वाला रंग निर्धारित होता है, जबकि आपका दृष्टिकोण "औसत रंग" जैसे कुछ खोजने की कोशिश करता है - एक बीमार परिभाषित धारणा, लेकिन यह स्पष्ट है कि लौटा हुआ रंग मूल में कहीं भी दिखाई नहीं दे सकता है छवि।मैं यह नहीं कह रहा हूं कि एक दृष्टिकोण दूसरे की तुलना में बेहतर है, मुझे लगता है कि मूल पोस्टर को यह स्पष्ट करना होगा कि वह क्या ढूंढ रहा है। – Thomas

+0

हां, मैं समझता हूं, इसलिए मैंने पूछा कि कितनी सटीकता की आवश्यकता थी। यदि आप 'ReplicateScaleFilter' का उपयोग करते हैं तो आपको मूल रंग में दिखाई देने वाला रंग मिलेगा क्योंकि यह "स्केल करने के लिए पिक्सल की पंक्तियों और स्तंभों को छोड़ देता है"। यह 'AreaAveragingScaleFilter' की तरह कोई" मिश्रण "नहीं करता है। – dogbane

+1

आपको 16581375 से नंबर कहाँ मिला? यदि हम प्रति चैनल 8 बिट्स के बारे में बात कर रहे हैं, तो 2^24 = 16777216 संभावित आरजीबी मान हैं। – Jesper

3

क्या आप पिक्सल का एक बड़ा रैखिक सरणी के रूप में अपनी छवि पर विचार करें, और उसके बाद आप सभी की क्या करना है बस तरह यह है या नहीं? जब आप इसे सॉर्ट करते हैं, तो आप समान मानों का सबसे लंबा हिस्सा गिन सकते हैं।

3

इस पर निर्भर करते हुए कि आपको रंग मूल्य की कितनी सटीक आवश्यकता है, आप स्मृति समस्याओं से बचने के लिए समान रंग एकत्र करने वाले "रंग बाल्टी" पर विचार करना चाहेंगे। इसका मतलब कलर स्पेस को रंगों के "अंतराल" में विभाजित करना है, जहां सभी रंग समान हैं (यानी एक साथ बंद) पर्याप्त रंग के रूप में गिना जाता है। अंतराल के आकार को बदलकर आपके पास सटीकता और स्मृति खपत के बीच व्यापार-बंद को सीधे जोड़ना है।


संपादित करें: आप मूल रूप से एक हिस्टोग्राम चाहते हैं (इसे देखो)। उनमें से किसी एक की कुशलतापूर्वक गणना करने के लिए सबसे अधिक संभवतः स्थापित मानक समाधान हैं।

+0

हां, बस प्रत्येक रंग की गणना करें (पूर्णांक की सरणी के लिए सूचकांक के रूप में रंग मान का उपयोग करना बहुत आसान है) जिसे आप जल्दी से बढ़ा सकते हैं। सरणी का विश्लेषण किया जा रहा छवि से छोटा होगा और एक पूर्णांक में वृद्धि करना अधिकांश (सभी?) प्रोग्रामिंग भाषाओं में बहुत सस्ता है। – Eno

1

मैं प्रत्येक पिक्सेल के रंग की गणना करता हूं और फिर प्रत्येक रंग की कार्डिनालिटी (हिस्टोग्राम बनाता है)। शायद संतृप्ति से भारोत्तोलन। फिर, एक कम-पास फ़िल्टर लागू करें, और अधिकतम खोजें। अंत में ह्यू से वापस आरजीबी में कनवर्ट करें।

यह मानता है कि यदि आपके पास एक छवि का लाल विमान था, तो आप परिणाम चाहते हैं कि गुलाबी रंग की छाया न हो।

4

जवाब के लिए धन्यवाद। बोझो की विधि का एक व्यावहारिक उदाहरण यहां दिया गया है। यह सफेद/ग्रे/काला भी फ़िल्टर करता है।

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; 
    } 
} 
+0

प्रत्येक पिक्सेल पर पुनरावृत्ति करके करने का एक महंगा तरीका दिखता है। यह 5 एमपी फोटो – Taranfx

+0

के लिए आसानी से मर जाएगा यदि छवि बड़े पैमाने पर है, तो इसे पहले आकार दें। –

0

एंड्रयू Dyster कोड एंड्रॉयड में

import java.util.Collections; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 

import android.graphics.Bitmap; 

public class ImageTester { 

    public interface ImageColor { 
     void onImageColor(int r, int g, int b); 
    } 

    @SuppressWarnings({ "unchecked", "rawtypes" }) 
    public static void getMostCommonColour(final Bitmap image, 
      final ImageColor heColor) { 
     new Thread(new Runnable() { 
      private int rgb; 

      @Override 
      public void run() { 
       int height = image.getHeight(); 
       int width = image.getWidth(); 
       Map m = new HashMap(); 
       int boderWid = width/4; 
       int borderHeigh = height/4; 

       for (int i = boderWid; i < width - boderWid;) { 
        for (int j = borderHeigh; j < height - borderHeigh;) { 
         try { 
          rgb = image.getPixel(i, j); 

         } catch (Exception e) { 
          continue; 
         }finally{ 
          i += 20; 
          j += 20; 
         } 
         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); 

         } 

        } 
       } 
       List list = new LinkedList(m.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()); 
       heColor.onImageColor(rgb[0], rgb[1], rgb[2]); 

      } 
     }).start(); 
    } 

    public static int[] getRGBArr(int pixel) { 
     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]; 
     int tolerance = 10; 
     if (rgDiff > tolerance || rgDiff < -tolerance) 
      if (rbDiff > tolerance || rbDiff < -tolerance) { 
       return false; 
      } 
     return true; 
    } 
}