Çileli bir Girinti Hatası

Dostum hala hata yok diyon, ama orijinal görüntüye filtre uygulanıyor, hata var ki uyguluyor. Normalda ilk fotoğrafta orijinal görüntünün kendisi, hiçbir filtre uygulamadan verilmesi lazım.

Orijinal fotoğraf herhangi bir filtreden geçmiyor, sadece grayscale’e çevrilip gösteriliyor belki ondan bir hata var diye düşünüyorsunuzdur. Neden yavaş olduğu hususu ise RC kere pikseller için for dönüyorsunuz mesela 1000 x 1000 image için 1 milyon dönüş oluyor, bir de WH kadar kernel dönüyor her piksel için, 5 x 5 için toplamda 25 milyon dönüş var; yavaşlık normal olsa gerek.

image
Girinti hatası da yok bana sorarsanız. Hatta girinti fazlalığı var if’lerden biri daima True dönüyor. Harmonik, geometrik ortalamalar nasıl sonuçlanmalı bilmem, ama aritmetik olan doğru duruyor. Orijinal fotoğraf da grayscale hali ile orada duruyor.


Benim aslında asıl değinmek istediğim şudur: eğer bu kodu siz anlayarak yazdıysanız, halihazırda ne olup bittiğini bilirsiniz. Yok yazmadıysanız ama anlamaya çalışıp da anlayamadıysanız karşıdaki için bence bir sorun yoktur. Fakat yazmadıysanız ve herhangi bir nedenden dolayı yeter ki program çalışsın da nasıl çalıştığı önemli değil diye düşünüyorsanız, bu bence karşıdaki için bir nebze sorun oluşturmakta.

Ama bu forumda bir soru soran kişinin hangi niyetle sorduğunu sorgulamak haddime değil, zaten isteyen yanıtlayabilir istemeyen yanıtlamaz. Ben de yukarıda bir yanıt vermeye çalıştım.

1 Beğeni

Yahu bende böyle bir çıktı vermedi buraya kodlarını çalıştırdığın şekliyle atar mısın, bir bakayım. Hiç değişiklik yaptın mı kodlarda?

from pylab import *
from PIL import Image

görüntü = array(Image.open(r"this.png").convert("L"))

boşluk = ones((len(görüntü), 20))*255
#iki görüntü arasında dikey beyaz boşluk

boşluk_1 = ones((100,len(görüntü[0])+len(görüntü[0])+20))*255
#yatay boşluk

#İlk olarak Mean_filter fonksiyonu ile görüntüye aritmetik, geometrik ve harmonik
#filtre uygulanacaktır.

def Mean_filter(görüntü1, kernel_boyutu):
    kernel_dizisi = []
    kernel_dizisi_1 = []
    k_i = kernel_boyutu//2
    mean_veri = []
    çarpan = 1

    #Aritmetik(mean_veri), geometrik(geo_maen_veri) ve harmonik(har_mean_veri)
    #0 dizilerine filtreler uygulandıktan sonra kaydedilecektir.
    mean_veri = zeros((len(görüntü), len(görüntü[0])))
    geo_mean_veri = zeros((len(görüntü), len(görüntü[0])))
    har_mean_veri = zeros((len(görüntü), len(görüntü[0])))

    #iç içe for döngüleri aritmatik, geometrik ve harmonik filtlerelerin
    #matematiksel modelleri kullanılarak pikseller tek tek işlenmektedir.

    for i in range(len(görüntü)):
        for j in range(len(görüntü[0])):
            #k_i değişkeni ile görüntüdeki kernel boyutunu tam sayı olarak ikiyi
            #bölündüğü değer kadar görüntünün alt, üst, sağ ve sol
            #piksellerin değerlerinin değiştirmemektedir.

            if(i-k_i<0 or i+k_i>len(görüntü)-1) or (j-k_i<0 or j+k_i>len(görüntü[0])-1):
                mean_veri[i][j] = görüntü[i][j]
                geo_mean_veri[i][j] = görüntü[i][j]
                har_mean_veri[i][j] = görüntü[i][j]
                #aritmetik, geometrik ve harmonik filtrelerin matematiksel modelleri uygulamak için
            else:
                for k in range(kernel_boyutu):
                    for m in range(kernel_boyutu):
                        
                        #Piksel çarpımından oluşan geometrik filtrede Kernel boyutu arttıkça çarpma işlemi
                        #sonucunda elde edilen değerler çok büyüktür. Bu nedenle elde edilen sonuçlar
                        #önce 10'a bölünüp filtreleme işlemleri gerekleştirildikten sonra tekrar 10 ile
                        #çarpılarak normal görüntüye dönüştürülmüştür.
                        kernel_dizisi.append(görüntü[i-k_i+k][j-k_i+m]/10)
                        
                        #Harmonik filtre 1/piksel değeri olarak işlem yapıldığı için eğer piksel değeri
                        #0 olduğunda sonucun 1/0 olarak belirsiz çıkmaması için bu değer 0 alınmıştır
                        if görüntü[i-k_i+k][j-k_i+m]==0:
                            kernel_dizisi_1.append(0)
                        else:
                            kernel_dizisi_1.append(1/görüntü[i-k_i+k][j-k_i+m])
                
                if len(kernel_dizisi)==kernel_boyutu*kernel_boyutu:
                    
                    #Geometrik filtreleme için denklemde verilen matematiksel işlemler gerçekleştirilmektedir.
                    for b in range(kernel_boyutu*kernel_boyutu):
                        çarpan=abs(çarpan*kernel_dizisi[b])
                        if çarpan<0:
                            çarpan = 0
                    x = kernel_boyutu*kernel_boyutu
                    geo_mean=çarpan**(1/x)
                    geo_mean_veri[i][j] = int(geo_mean*10)
                    
                    #Aritmetik (art_mean) için oluşan kernel dizisinin ortalaması hesaplanmaktadır
                    art_mean=mean(array(kernel_dizisi))
                    mean_veri[i][j]=int(art_mean*10)
                    
                    #Harmonik (har_mean) filtreleme için denklemde verilen matematiksel işlmeler gerçekleştirilmektedir.
                    toplam=sum(kernel_dizisi_1)
                    if toplam==0:
                        har_mean=0
                    else:
                        har_mean=x/toplam
                    har_mean_veri[i][j]=int(har_mean)

                #kernel_dizisi, kernel_dizisi_1 ve çarpan değerleri diğer piksel işlemleri için resetlenmektedir.
                kernel_dizisi = []
                kernel_dizisi_1 = []
                çarpan=1

    return mean_veri, geo_mean_veri, har_mean_veri

art_mean_görüntü, geo_mean_görüntü, har_mean_görüntü = Mean_filter(görüntü, 5)
#fonksiyona git

#orijinal görüntü(görüntü), beyaz boşluk(boşluk), aritmetik filtreleme görüntüsü(art_mean_görüntü) yatay eksende yan yana getirilmiştir.
x=concatenate((görüntü, boşluk, art_mean_görüntü), axis=1)

#Harmonik görüntü(har_mean_görüntü), beyaz boşluk(boşluk), geometrik filtreleme görüntüsü(geo_mean_görüntü) yatay eksende yan yana getirilmiştir.
x1=concatenate((har_mean_görüntü, boşluk, geo_mean_görüntü), axis=1)
x2=vstack((x, boşluk_1,x1))
#x2=x+boşluk+x1 dikey eksende resimler birleştirilmiştir.

img=Image.fromarray(x2)
imshow(img, cmap="gray")
show()

göze hitap etmeyen kısımlara boşluk getirdim.

İstediğime yakın bir çözüm, hala emin değilim. Bunları kitaptan çalışıyorum. Ama zaman konusunda hala sorunlu ya, çok geç çalıştırıyor. Çok sıkıntı. Çok teşekkürler uğraştığın için.

Bunlara “mantik hatasi” veya daha genel olarak “programci hatasi” diyoruz. Bilgisayarin yakalamasina, yakalasa bile emin olmasina imkan yok. print("1 + 1 = 3")

Ayni hataya ben de dustum. Hatta hatanin programci hatasi oldugunu anladiktan sonra bile bir sure girinti hatasi oldugunu dusundum. (for disinda kalmasi gereken bir kod for icine girintileniyor…)

Buradaki sikinti da teknik soruya duygusal cevap verilmesi. Dogrusunun “su ekteki kirmizi resmi koyunca su ekteki yesil resim cikiyor, o yuzden filtre oldugunu dusunuyorum” gibi bir sey olmasi lazim, “yalan mi soyliycem” degil.


Soruya degil cevaplara bir sey katmis oldum ama soru zaten cevaplanmis duruyor.

2 Beğeni

Duygusal cevap vermediğim konusunda yemin edebilirim. :slight_smile:

Filtreler ve Görüntü işleme konusunda bir kaç kitap aldım, hala çalışıyorum, açıkçası istatistik yabancısı olmadığım için, formüller de istatistik formülleri olduğu için fonksiyonları anlasam da, program çıktısının görüntü işlemede kullandıkları alanları pratikte gördükçe daha sonra daha da iyi anlayacağım. Şuan, bundan sonra 6 farklı filtre için kod da yazdım, bunun dışında tüm sonuçlar anlamlı. Umarım bundaki sorunu da tam olarak çözeceğim.

İlgilendiğiniz için teşekkürler, saygılar ve sevgiler…

Orijinal fotoğraf herhangi bir filtreden geçmiyor, sadece grayscale’e çevrilip gösteriliyor belki ondan bir hata var diye düşünüyorsunuzdur. Neden yavaş olduğu hususu ise RC kere pikseller için for dönüyorsunuz mesela 1000 x 1000 image için 1 milyon dönüş oluyor, bir de WH kadar kernel dönüyor her piksel için, 5 x 5 için toplamda 25 milyon dönüş var; yavaşlık normal olsa gerek.

Ek olarak, görüntünün geç işlemesi konusunda söylediği kesinlikle doğru. Hatta söyledikten sonra GPU ve Kernel üzerine biraz daha çalışma gereği hissettim. Haklı olabilirsin kesinlikle.

GPU’ya bulasmadan once kodu CPU uzerinde vektorize etmeni tavsiye ediyorum. Hatta kodda numpy'den bildigimiz fonksiyonlar kullanilmis, numpy kullanilmaya baslanabilir.

Ama oncesinde kodun fonksiyonlara ayrilmasi lazim. for icinde for icinde if icinde for icinde for icinde if okunabilir bir sey degil. (i-k_i<0 or i+k_i>len(görüntü)-1) or (j-k_i<0 or j+k_i>len(görüntü[0])-1) kritik bir kontrol gibi duruyor ama ismi yok. Kod parcalara ayrilirsa parcalar yavas yavas degistirilebilir.

1 Beğeni

İnan bana bu kodların daha başka kolay bir yöntemini bulursam yazacağım buraya :slight_smile:
Bir amaca uygun modül olduğu için ve kitap üzerinden gittiğim için şuan mümkün değil.
Ama sen de haklısın.