2010-03-30 11 views
8

मैं .NET में पृष्ठभूमि छवि में बहु रंग प्राप्त करना चाहता हूं। क्या यह संभव है?किसी छवि में बहु रंग कैसे प्राप्त करें?

+0

आप 'बहुमत रंग' के अर्थ को स्पष्ट कर सकते हैं? क्या आपका मतलब है कि किसी छवि में अक्सर रंग का उपयोग किया जाता है; एक छवि का औसत रंग; 'उच्चतम' मूल्य रंग समतुल्य आरजीबी? – Seidr

+3

आपको शायद "बहु रंग" से क्या मतलब है उसे स्पष्ट करने की आवश्यकता है। अधिकांश छवियों के लिए, यह असंभव है कि कोई भी रंग उचित बहुमत का गठन करेगा। मुझे लगता है कि आप या तो सबसे अधिक बार रंग (पिक्सेल द्वारा पिक्सेल), या प्रमुख घटक (या तो आर, जी या बी) का मतलब है। – MusiGenesis

+0

क्या आपको गति या सटीकता की आवश्यकता है? क्या आप सबसे अधिक इस्तेमाल किया रंग, औसत रंग, या प्रवृत्ति रंग भी चाहते हैं? क्या आपको आरजीबी मिश्रित या अलग होना चाहिए? –

उत्तर

6

आप छवि में सभी पिक्सल के माध्यम से पाश कर सकते हैं और आरजीबी मान निर्धारित करने के लिए getPixel विधि का उपयोग कर सकते हैं। उसके बाद आप एक शब्दकोश प्राप्त कर सकते हैं जो एआरजीबी मूल्य को गिनती के साथ स्टोर करता है। फिर आप छवि में कौन सी एआरजीबी मान मौजूद हैं देख सकते हैं।

var list = new Dictionary<int, int>(); 
Bitmap myImage = (Bitmap)Bitmap.FromFile("C:/test.jpeg"); 
for (int x = 0; x < myImage.Width; x++) 
{ 
    for (int y = 0; y < myImage.Height; y++) 
    { 
     int rgb = myImage.GetPixel(x, y).ToArgb(); 
     if (!list.ContainsKey(rgb)) 
      list.Add(rgb, 1); 
     else 
      list[rgb]++; 
    } 
} 

जैसा कि बताया गया है कि इस तरह के रंगों के लिए कोई सहानुभूति नहीं है। यदि आप एक अधिक 'सामान्य' बहुमत रंग चाहते थे तो आप समानता पर सीमा पार कर सकते थे। जैसे के बजाय:

if (!list.ContainsKey(rgb)) 
     list.Add(rgb, 1); 
    else 
     list[rgb]++; 

तुम कर सकते हो:

var added = false; 
for (int i = 0; i < 10; i++) 
{ 
    if (list.ContainsKey(rgb+i)) 
    { 
     list[rgb+i]++; 
     added = true; 
     break; 
    } 
    if (list.ContainsKey(rgb-i)) 
    { 
     list[rgb-i]++; 
     added = true; 
     break; 
    } 
} 
if(!added) 
    list.Add(rgb, 1); 

आप सकता है 10 की दहलीज जो कुछ भी आप की जरूरत है।

+0

यदि यह एक "सच्चा रंग" जेपीईजी है ... जो कि प्रति कुंजी बहुत कम मायने रखता है शब्दकोश में बहुत से मूल्य हो सकता है। –

+0

सहमत हुए। आपको काम करने के लिए किसी प्रकार की कताई या समूह की आवश्यकता होगी। इस के साथ आप 2 पूरी तरह से लाल पिक्सेल और काले रंग के सूक्ष्म रूपों का एक टन हो सकते हैं और बहु ​​रंग के रूप में लाल रंग के साथ बाहर आ सकते हैं। – RandomEngy

+0

अच्छी तरह से तकनीकी रूप से लाल रंग बहु रंग होगा। – CeejeeB

5

तुम भी स्टैक ओवरफ़्लो पर इस एल्गोरिथ्म चैलेंज उपयोगी हो सकते हैं:

Algorithm challenge: Generate color scheme from an image

भी छवि का एक हिस्टोग्राम बनाने पर विचार - और 'बहुमत रंग' के रूप में उच्चतम मूल्य का रंग ले रही है: http://www.phpclasses.org/browse/file/15953.html

3

मान लें कि आप RGB (बनाम, कहें, CMYK) का उपयोग करके प्रत्येक पिक्सेल के रंग को चित्रित करते हैं, आप एक 3 डी सरणी (आर, जी और बी के लिए प्रत्येक आयाम) बना सकते हैं। फिर उन प्रत्येक डिब्बे पर निर्णय लें जिन्हें आप प्रत्येक आयाम में रखना चाहते हैं - अधिक डिब्बे, उतना ही भिन्नता जो आप समान रंगों के बीच बना रहे हैं।

एक बार ऐसा करने के बाद, बस अपनी छवि के बिटमैप प्रतिनिधित्व के माध्यम से # पिक्सल को एकत्रित करें जो आपके 3 डी सरणी में से प्रत्येक कक्ष में आता है। उच्चतम योग वाला सेल मुख्य रंग होगा।

शायद आप अपने एल्गोरिदम को प्रत्येक आयाम में # डिब्बे के लिए आसानी से कॉन्फ़िगर करने योग्य बनाना चाहते हैं ताकि आप समायोजित कर सकें कि यह समान रंगों के बीच कितना भेदभाव करता है।

image = new Bitmap("C:\\test.bmp", true); 
int x, y; 
// Loop through the images pixels to product 3d histogram 
for(x=0; x<image.Width; x++) 
{ 
    for(y=0; y<image.Height; y++) 
    { 
     Color pixelColor = image.GetPixel(x, y); 

     // Increment color count in appropriate cell of your 3d histogram here 
     ... 
    } 
} 
5

यह छवि के लिए औसत रंग वापस करेगा।

static Color AverageColor(string fileName) 
{ 
    using (var bmp = new Bitmap(fileName)) 
    { 
     int width = bmp.Width; 
     int height = bmp.Height; 
     int red = 0; 
     int green = 0; 
     int blue = 0; 
     int alpha = 0; 
     for (int x = 0; x < width; x++) 
      for (int y = 0; y < height; y++) 
      { 
       var pixel = bmp.GetPixel(x, y); 
       red += pixel.R; 
       green += pixel.G; 
       blue += pixel.B; 
       alpha += pixel.A; 
      } 

     Func<int, int> avg = c => c/(width * height); 

     red = avg(red); 
     green = avg(green); 
     blue = avg(blue); 
     alpha = avg(alpha); 

     var color = Color.FromArgb(alpha, red, green, blue); 

     return color; 
    } 
} 
+0

मुझे नहीं लगता कि परिणाम "बहु रंग" के रूप में योग्यता प्राप्त करता है क्योंकि औसत रंग भी एक पिक्सेल नहीं हो सकता है। – Kaniu

+0

बहुत सच ... और इसलिए मैंने प्रश्न के तहत मेरी टिप्पणी में अधिक जानकारी मांगी। कोई प्रतिक्रिया नहीं तो यह मेरी प्रविष्टि है। प्रदर्शन के लिए –

4

यह असुरक्षित सूचक पहुंच का उपयोग कर छवि के लिए औसत रंग वापस कर देगा। नोट: कोड केवल 24bppRgb के लिए अनुकूलित किया गया है, अन्य पिक्सेल प्रारूपों के लिए अनुकूलित किया जा सकता है।

unsafe static Color GetColor(string filename) 
    { 
     using (var image = (Bitmap)Bitmap.FromFile(filename)) 
     { 
      if (image.PixelFormat != PixelFormat.Format24bppRgb) throw new NotSupportedException(String.Format("Unsupported pixel format: {0}", image.PixelFormat)); 

      var pixelSize = 3; 
      var bounds = new Rectangle(0, 0, image.Width, image.Height); 
      var data = image.LockBits(bounds, ImageLockMode.ReadOnly, image.PixelFormat); 

      long r = 0; 
      long g = 0; 
      long b = 0; 

      for (int y = 0; y < data.Height; ++y) 
      { 
       byte* row = (byte*)data.Scan0 + (y * data.Stride); 
       for (int x = 0; x < data.Width; ++x) 
       { 
        var pos = x * pixelSize; 
        b += row[pos]; 
        g += row[pos + 1]; 
        r += row[pos + 2]; 
       } 
      } 

      r = r/(data.Width * data.Height); 
      g = g/(data.Width * data.Height); 
      b = b/(data.Width * data.Height); 
      image.UnlockBits(data); 

      return Color.FromArgb((int)r, (int)g, (int)b); 
     } 
    } 

सार: http://gist.github.com/349210

+0

+1। प्रत्येक पिक्सल पर GetPixel को कॉल करना बेहद धीमा है। – RandomEngy

+1

बेहद धीमा एक असाधारण का थोड़ा सा है। मैं 15fps 800x600 पर वीडियो फ्रेम का विश्लेषण करने के लिए GetPixel विधि का उपयोग करने में सक्षम था। तो अगर पोस्टर को सिर्फ एक छवि का विश्लेषण करने की आवश्यकता है GetPixel पर्याप्त से अधिक है। – CeejeeB

संबंधित मुद्दे