2010-06-15 15 views
5

मुझे अल्फा पारदर्शिता के साथ एक पीएनजी छवि में सभी सफेद (आईएसएच) पिक्सल को प्रतिस्थापित करने की आवश्यकता है।छवि गुरु: मेरे पायथन पीएनजी पारदर्शिता समारोह को अनुकूलित करें

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

मैं उत्कृष्ट थोड़ा pyPNG module पाया जाता है और करता है कि मैं क्या जरूरत है एक छोटे से समारोह ऊपर दस्तक करने में कामयाब रहे:

मुख्य पाश के लिए

make_transparent.py

छद्म कोड होगा कुछ की तरह:

for each pixel: 
    if pixel looks "quite white": 
     set pixel values to transparent 
    otherwise: 
     keep existing pixel values 

और (8 बिट मान मानते हैं) "काफी सफेद" होगा:

where each r,g,b value is greater than "240" 
AND each r,g,b value is within "20" of each other 

यह पहली बार है जब मैंने कच्चे पिक्सेल डेटा के साथ इस तरह काम किया है, और हालांकि काम करता है, यह भी बेहद खराब प्रदर्शन करता है। ऐसा लगता है कि प्रत्येक पिक्सेल पर इस तरह से डेटा को प्रोसेस करने का एक और अधिक प्रभावी तरीका होना चाहिए? (Matrices?)

मैं उम्मीद कर रहा था कि इन चीजों से निपटने में अधिक अनुभव रखने वाले किसी व्यक्ति को मेरे एल्गोरिदम में मेरी कुछ और अधिक स्पष्ट गलतियों/सुधारों को इंगित करने में सक्षम हो सकता है।

धन्यवाद!

+3

आरजीबी 240 की तुलना में सभी अधिक से अधिक, क्या मुझे लगता है पर एक 0-255 पैमाने पर है, तो वे हैं:

यहाँ, अगर आप चित्र को कॉपी करने के लिए तैयार थे, तो आप एक सूची समझ इस्तेमाल कर सकते हैं जरूरी है कि एक दूसरे के 20 के भीतर, वे नहीं हैं? – AakashM

+0

(कारण मैं पूछता हूं क्योंकि यदि * सभी * हमें उन पिक्सेल की आवश्यकता है जहां आर, जी, बी सभी 241+ हैं, तो यह अधिक संभावना है कि एक मैट्रिक्स-वाई विधि है) – AakashM

+0

हां यह 0-255 है पैमाने। और वास्तविक थ्रेसहोल्ड मान दुर्भाग्यवश 240 से ऊपर होने के बावजूद भिन्न होते हैं, छवि स्रोतों के बीच एक अच्छी तरह से ट्यूनिंग के रूप में। मुझे थ्रेसहोल्ड = 210 मिला है और सहनशीलता = 30 ने पूरे दौर के अच्छे परिणाम दिए हैं। –

उत्तर

1

यह अभी भी हर पिक्सेल आता है, लेकिन तेजी से हो सकता है:

new_pixels = [] 
for row in pixels: 
    new_row = array('B', row) 
    i = 0 
    while i < len(new_row): 
     r = new_row[i] 
     g = new_row[i + 1] 
     b = new_row[i + 2] 
     if r>threshold and g>threshold and b>threshold: 
      m = int((r+g+b)/3) 
      if nearly_eq(r,m,tolerance) and nearly_eq(g,m,tolerance) and nearly_eq(b,m,tolerance): 
       new_row[i + 3] = 0 
     i += 4 
    new_pixels.append(new_row) 

यह slicen जनरेटर है, जो पूरी पंक्ति को कॉपी किया जाएगा से बचा जाता है प्रत्येक पिक्सेल के लिए पिक्सल (हर बार कम एक पिक्सेल)।

यह इनपुट पंक्ति को सीधे कॉपी करके आउटपुट पंक्ति को पूर्व-आवंटित करता है, और उसके बाद केवल पिक्सेल के अल्फा मान को बदलता है जो बदल गया है।

यहां तक ​​कि तेजी से पिक्सल का एक नया सेट आवंटित नहीं किया जाएगा, और केवल स्रोत छवि में पिक्सल पर सीधे लिखना होगा (मान लीजिए कि आपको किसी और चीज़ के लिए स्रोत छवि की आवश्यकता नहीं है)।

+0

वैसे भी, आपका मूल कोड आर, जी और बी के बजाय लगभग तीन बार (आर, ...) की जांच कर रहा है। –

+0

मुझे इस धन्यवाद से लगभग 25% की गति में वृद्धि हुई है! .... मैंने सीधे मूल पिक्सेल सरणी में हेरफेर करने की कोशिश की, लेकिन उसमें पूरी छवि को स्मृति में लोड करने की आवश्यकता थी, जो एक समग्र मंदी के कारण समाप्त हुआ। –

0

मुझे पूरा यकीन है कि इसके लिए कोई छोटा कटौती नहीं है। आपको प्रत्येक पिक्सेल पर जाना होगा।

1

ईमानदारी से, केवल एकमात्र ह्यूरिस्टिक मैं कल्पना कर सकता हूं कि आपकी छवि पर कुछ मनमाने ढंग से यादृच्छिक बिंदु चुन रहे हैं और flood fill का उपयोग कर रहे हैं।

यह केवल तभी काम करता है जब आपकी छवि बड़े संगत सफेद भाग के रूप में अच्छी तरह से काम करती है (यदि आपकी छवि पृष्ठभूमि के सामने कोई या छोटी छेद वाली वस्तु नहीं है, तो आप भाग्य में हैं - आपको वास्तव में एक बिंदु है जिसके लिए एक ह्युरिस्टिक है बाढ़ से भरने के लिए)।

(अस्वीकरण: मैं कोई छवि गुरु हूँ = /)

+0

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

+0

आप अपने बाढ़ भरने को कैसे लागू कर रहे थे? यदि आप रिकर्सिव कार्यान्वयन का उपयोग कर रहे हैं, तो आपको पिक्सल या स्टोर सीमाओं पर फिर से जाना नहीं चाहिए। –

0

यह समस्या छवियों की तुलना में पाइथन में लूप के साथ और अधिक करने के लिए प्रतीत होती है।

पायथन लूप बेहद धीमी हैं, इसलिए उनसे बचने और बिल्ट-इन लूप ऑपरेटरों का उपयोग करना सबसे अच्छा है।

def make_transparent(pixel): 
    if pixel looks "quite white": return transparent 
    else: return pixel 

newImage = [make_transparent(p) for p in oldImage] 
संबंधित मुद्दे