2011-04-03 16 views
5

संपादित करें: हावर्ड के लिए धन्यवाद, मैंने यहां कोड को सही किया है और ऐसा लगता है कि यह अब काम कर रहा है।इस पायथन छवि धुंध समारोह के साथ क्या गलत है?

EDIT2: मैंने कोड को मूल रूप से इच्छित लंबवत धुंध को शामिल करने के लिए अद्यतन किया है। विभिन्न सेटिंग्स के साथ जिसके परिणामस्वरूप नमूना उत्पादन: Blur comparison images.jpg

कलंक के संचालन के लिए एक और संदर्भ (जावा): Blurring for Beginners


मूल पोस्ट:

मैं बुनियादी छवि प्रसंस्करण के बारे में जानने के लिए और इस सरल नकल करने की कोशिश कर रहा हूँ Blur method (पाइथन में "पुन: उपयोग परिणाम" के तहत दूसरा फ़ंक्शन ब्लरहोरिज़ोंटल)। मुझे पता है कि पीआईएल में पहले से ही धुंधले काम हैं, लेकिन मैं खुद को मूल पिक्सेल संचालन का प्रयास करना चाहता हूं।

इस फ़ंक्शन को एक स्रोत छवि लेनी चाहिए, फिर एक निश्चित त्रिज्या के आधार पर औसत आरजीबी पिक्सेल मान लेना चाहिए और संसाधित छवि को एक नई फ़ाइल में लिखना चाहिए। मेरी समस्या यह है कि मुझे पूरी तरह से गलत औसत मूल्यों के साथ बहुत सारे पिक्सल मिल रहे हैं (उदाहरण के लिए, कुछ क्षेत्रों में लाल की बजाय चमकदार हरी रेखाएं)।

2 के धुंध त्रिज्या के साथ, औसत विधि इनपुट पिक्सेल पर केंद्रित 5 पिक्सेल के लिए आरजीबी मान जोड़ती है। यह एक रनिंग कुल रखने के लिए "स्लाइडिंग विंडो" का उपयोग करता है, आउटगोइंग पिक्सेल (बाएं तरफ) घटाकर और नया आने वाला पिक्सेल (विंडो का दायां तरफ) जोड़ना। Blur method explained here

नमूना: Blur test image output.jpg

कोई भी विचार है जहाँ मैं गलत हो गया है? मुझे यकीन नहीं है कि छवि के कुछ हिस्सों में स्पष्ट रूप से धुंध क्यों है जबकि अन्य क्षेत्रों रंगों से भरे हुए हैं जो आसपास के क्षेत्रों से पूरी तरह से असंबंधित हैं।

आपकी मदद के लिए धन्यवाद।

निर्धारित श्रमजीवी कोड (धन्यवाद हावर्ड)

import Image, numpy, ImageFilter 
img = Image.open('testimage.jpg') 

imgArr = numpy.asarray(img) # readonly 

# blur radius in pixels 
radius = 2 

# blur window length in pixels 
windowLen = radius*2+1 

# columns (x) image width in pixels 
imgWidth = imgArr.shape[1] 

# rows (y) image height in pixels 
imgHeight = imgArr.shape[0] 

#simple box/window blur 
def doblur(imgArr): 
    # create array for processed image based on input image dimensions 
    imgB = numpy.zeros((imgHeight,imgWidth,3),numpy.uint8) 
    imgC = numpy.zeros((imgHeight,imgWidth,3),numpy.uint8) 

    # blur horizontal row by row 
    for ro in range(imgHeight): 
     # RGB color values 
     totalR = 0 
     totalG = 0 
     totalB = 0 

     # calculate blurred value of first pixel in each row 
     for rads in range(-radius, radius+1): 
      if (rads) >= 0 and (rads) <= imgWidth-1: 
       totalR += imgArr[ro,rads][0]/windowLen 
       totalG += imgArr[ro,rads][1]/windowLen 
       totalB += imgArr[ro,rads][2]/windowLen 

     imgB[ro,0] = [totalR,totalG,totalB] 

     # calculate blurred value of the rest of the row based on 
     # unweighted average of surrounding pixels within blur radius 
     # using sliding window totals (add incoming, subtract outgoing pixels) 
     for co in range(1,imgWidth): 
      if (co-radius-1) >= 0: 
       totalR -= imgArr[ro,co-radius-1][0]/windowLen 
       totalG -= imgArr[ro,co-radius-1][1]/windowLen 
       totalB -= imgArr[ro,co-radius-1][2]/windowLen 
      if (co+radius) <= imgWidth-1: 
       totalR += imgArr[ro,co+radius][0]/windowLen 
       totalG += imgArr[ro,co+radius][1]/windowLen 
       totalB += imgArr[ro,co+radius][2]/windowLen 

      # put average color value into imgB pixel 

      imgB[ro,co] = [totalR,totalG,totalB] 

    # blur vertical 

    for co in range(imgWidth): 
     totalR = 0 
     totalG = 0 
     totalB = 0 

     for rads in range(-radius, radius+1): 
      if (rads) >= 0 and (rads) <= imgHeight-1: 
       totalR += imgB[rads,co][0]/windowLen 
       totalG += imgB[rads,co][1]/windowLen 
       totalB += imgB[rads,co][2]/windowLen 

     imgC[0,co] = [totalR,totalG,totalB] 

     for ro in range(1,imgHeight): 
      if (ro-radius-1) >= 0: 
       totalR -= imgB[ro-radius-1,co][0]/windowLen 
       totalG -= imgB[ro-radius-1,co][1]/windowLen 
       totalB -= imgB[ro-radius-1,co][2]/windowLen 
      if (ro+radius) <= imgHeight-1: 
       totalR += imgB[ro+radius,co][0]/windowLen 
       totalG += imgB[ro+radius,co][1]/windowLen 
       totalB += imgB[ro+radius,co][2]/windowLen 

      imgC[ro,co] = [totalR,totalG,totalB] 

    return imgC 

# number of times to run blur operation 
blurPasses = 3 

# temporary image array for multiple passes 
imgTmp = imgArr 

for k in range(blurPasses): 
    imgTmp = doblur(imgTmp) 
    print "pass #",k,"done." 

imgOut = Image.fromarray(numpy.uint8(imgTmp)) 

imgOut.save('testimage-processed.png', 'PNG') 
+2

आप कुछ नमूना इनपुट/आउटपुट पोस्ट कर सकते हैं? – Blender

+1

जब मैं 'ए-बी-सी' देखता हूं तो मैं हमेशा चिंतित हूं। मुझे ऑपरेटरों की सहयोगीता को किसी भी भाषा में पर्याप्त रूप से याद नहीं है, यह जानने के लिए कि क्या इसे 'ए- (बीसी)' या '(एबी) -सी' – sarnold

+1

के रूप में व्याख्या किया जाएगा, मैंने प्रत्येक भाषा में, अतिरिक्त, घटाव, गुणा, और गणित के रूप में विभाजन सहयोगी बाएं से दाएं। एक्सपोनेंटिएशन एकमात्र आम है जो अक्सर दाएं से बाएं को जोड़ता है। –

उत्तर

2

मैं तुम्हें लाइन

for rads in range(-radius, radius): 

जो (रेंज पिछले शामिल नहीं) के दायरे -1 के लिए एक ही चलाता है के साथ समस्या है लगता है। दूसरी श्रेणी तर्क में जोड़ें।

अद्यतन: वहाँ लाइन

if (co-radius-1) > 0: 

भीतर एक और छोटा सा isue जो

if (co-radius-1) >= 0: 
+0

सभी टिप्पणियों के लिए धन्यवाद। मैंने हावर्ड के सुझाव की कोशिश की और निम्नलिखित पंक्ति में बदल दिया: 'रेंज में रेंज के लिए (-त्रिज्या, त्रिज्या + 1)' लेकिन मुझे अभी भी एक और समस्या होनी चाहिए। यहां एक नमूना छवि है, जो छवियों के पहले और बाद में दिखाती है। दूसरी छवि को मेरे मूल कोड द्वारा संसाधित किया गया था। हावर्ड के परिवर्तन के बाद तीसरी छवि को संसाधित किया गया था। [धुंधला परीक्षण छवि output.jpg] (http://i.imgur.com/U16Bf.jpg) – moski

+0

@moski एक और नाबालिग समस्या है: अगर (सह त्रिज्या -1)> 0: अगर होना चाहिए (सह -त्रिज्या -1)> = 0. – Howard

+0

बहुत बहुत धन्यवाद! मुझे लगता है कि उन दो परिवर्तनों ने मेरी त्रुटियों को ठीक कर दिया है। मैं 0 छोटी बनाम 1 से शुरू होने की गिनती के लिए खाते की सभी छोटी चीजें,> बनाम> = और +1, -1 को याद करता हूं। आंखों के दूसरे सेट के लिए धन्यवाद। मैं एक अद्यतन पोस्ट करने की तुलना में कुछ अलग छवियों का प्रयास करेंगे। [धुंधला FIXED output.png] (http://i.imgur.com/2ECNM.png) – moski

0

होना चाहिए मैं संशोधित/अपने कोड सिर्फ एक सा पुनर्संशोधित, और सोचा था कि मैं हिस्सा होता है। मुझे कस्टम ब्लर करने के लिए कुछ चाहिए जो: 1) डेटा सरणी पर काम करेगा, और 2) केवल क्षैतिज रूप से लपेटें और लंबवत नहीं। टीओडीओ नोट्स के रूप में, मैं आगे रिफैक्टरिंग के बारे में सोच रहा हूं ताकि यह आंशिक पिक्सेल मिश्रण (यानी 0.5) कर सके।आशा है कि इस मदद करता है किसी को:

def blur_image(image_data, blur_horizontal=True, blur_vertical=True, height=256, width=256, radius=1): 
    #TODO: Modify to support partial pixel blending 

    # blur window length in pixels 
    blur_window = radius*2+1 

    out_image_data = image_data 

    # blur horizontal row by row, and wrap around edges 
    if blur_horizontal: 
     for row in range(height): 
      for column in range(0, width): 
       total_red = 0 
       total_green = 0 
       total_blue = 0 

       for rads in range(-radius, radius+1): 
        pixel = (row*width) + ((column+rads) % width) 
        total_red += image_data[pixel][0]/blur_window 
        total_green += image_data[pixel][1]/blur_window 
        total_blue += image_data[pixel][2]/blur_window 

       out_image_data[row*width + column] = (total_red, total_green, total_blue, 255) 
     image_data = out_image_data 

    # blur vertical, but no wrapping 
    if blur_vertical: 
     for column in range(width): 
      for row in range(0, height): 
       total_red = 0 
       total_green = 0 
       total_blue = 0 

       blur_window = 0 
       for rads in range(-radius, radius+1): 
        if rads in range(0, height): 
         blur_window += 1 

       for rads in range(-radius, radius+1): 
        row_mod = row+rads 
        if row_mod in range(0, height): 
         pixel = (row_mod*width) + column 
         total_red += image_data[pixel][0]/blur_window 
         total_green += image_data[pixel][1]/blur_window 
         total_blue += image_data[pixel][2]/blur_window 

       out_image_data[row*width + column] = (total_red, total_green, total_blue, 255) 
     image_data = out_image_data 

    return image_data 

आप इसे उपयोग कर सकते हैं जब आप पहले से ही एक छवि RGBA पिक्सल की एक सरणी में है कि मिल गया है, तो चलाएँ:

image_data = blur_image(image_data, height=height, width=width, radius=2) 

im = Image.new('RGB', (width, height)) 
im.putdata(image_data) 
संबंधित मुद्दे