IRCForumları - IRC ve mIRC Kullanıcılarının Buluşma Noktası

IRCForumları - IRC ve mIRC Kullanıcılarının Buluşma Noktası (https://www.ircforumlari.net/)
-   C ve C++ (https://www.ircforumlari.net/c-ve-c/)
-   -   C++ ile Konvolüsyon İşlemi (https://www.ircforumlari.net/c-ve-c/547363-c-ile-konvolusyon-islemi.html)

SeckiN 09 Eylül 2013 22:11

C++ ile Konvolüsyon İşlemi
 
Konvolüsyon, birim dürtü yanıtı( h(t) ) bilinen bir sistemin x(t) giriş işaretine karşılık üreteceği y(t) çıkış işaretini zaman domeninde bulmaya yarayan bir işlemdir. Konvolüsyon işlemi * sembolü ile gösterilir ve bir boyutlu sürekli zamanlı konvolüsyon işlemi aşağıdaki formül ile hesaplanır.

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

Benzer şekilde ayrık konvolüsyon işlemi ise aşağıdaki gibidir.

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

Konvolüsyon işleminin uygulanabilmesi için sistemin lineer ve zamanla değişmeyen olması
gerekmektedir. Konvolüsyon işleminin daha iyi anlaşılması için aşağıdaki hareketli resim
incelenebilir.

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

Burada kırmızı renkli işaret sistemin birim dürtü yanıtının ters çevrilmiş şeklini simgelemektedir. Bu işaret -∞ dan başlayarak +∞ a doğru adım adım kaydırılır ve her kaydırma sonrası x işareti ile örtüşen kısımın altında kalan alanı hesaplanır. Hesaplanan bu sonuç lineer zamanla değişmeyen sistemin x giriş işaretine karşı ürettiği çıkış işaretidir.

İki boyutlu konvolüsyon işlemide benzer olarak aşağıdaki formül ile ifade edilir.

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

Burada h(x,y) konvolüsyon çekirdek matrisi(kernel) olarak adlandırılır ve genellikle 3x3,5x5,7x7 gibi büyüklükte seçilir. Seçilen çekirdek matrisinde yer alan değerler komşu piksellerin merkez piksele yapacağı etkinin ağırlığını gösterir.

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]

A*h=h matrisi ters çevrilerek hesaplanmak istenen (2,4) pikselin üzerine koyuldu. (2,4) pikselinin yeni değeri=24*2+5*8+15*4+7*7+14*5+16*3+13*6+20*1+22*8= 575 bulunur.

Hesaplamada yaşanacak sorunlar:
Konvolüsyon işlemi sırsaında problem oluşturacak bazı noktalar vardır.
▲Bunlardan ilki şüphesiz ki kenar noktalardır. Çekirdek matrisin merkez elemanı görüntü üzerindeki ilk pikselin üzerine gelecek şekilde konulduğunda çekirdek matrisin bazı elamanlarına karşılık çarpılacak eleman bulunmaz. Bu durumda programın hata vermemesi için yazılan kodlarda giriş matrisine çekirdek matrisin boyunun bir eksiği kadar satır ve sütun eklenmiş ve bu satırlar 0 alınarak programın hata vermesi engellenmiştir.
▲Bir diğer sorun ise işlem sonrası hesaplanan yeni piksel değerinin seçilen çekirdek matris ağırlıklarına bağlı olarak 0-255 aralığı dışında kalmasıdır. Bu durumda programda kontrol edilmiş ve sınırlar dışında kalan değerler sınır değerlerine çekilmiştir.
▲Hesaplama yapılırken hesaplanan yeni değerler yeni bir matris üzerinde tutularak yeni değerler ile işlem yapılan matrisin değerlerinin karışması ve hatalı sonuç üretmesi engellenmiştir.

Kod:

BMP im=yenim_bmp(kaynak.bminfo.width,kaynak.bminfo.height);
    BMP kaynako=yenim_bmp(kaynak.bminfo.width+k-1,kaynak.bminfo.height+k-1);
    int i,j,m,n;
    double red,green,blue;
           
    for (i=0;i < kaynak.bminfo.width;i++) {
        for (j=0;j < kaynak.bminfo.height;j++) {         
    kaynako.pixels[i+(k-1)/2][j+(k-1)/2].red=kaynak.pixels[i][j].red;
    kaynako.pixels[i+(k-1)/2][j+(k-1)/2].green=kaynak.pixels[i][j].green;
    kaynako.pixels[i+(k-1)/2][j+(k-1)/2].blue=kaynak.pixels[i][j].blue; }}
   
    for (i=0;i < kaynak.bminfo.width;i++) {
        for (j=0;j < kaynak.bminfo.height;j++) {
            for (m=0;m < k; m++) {
                for (n=0;n < k; n++) {
   
    red+=kaynako.pixels[i+m][j+n].red*filt[m][n];
    green+=kaynako.pixels[i+m][j+n].green*filt[m][n];
    blue+=kaynako.pixels[i+m][j+n].blue*filt[m][n];
    }}
    im.pixels[i][j].red= red<0 ?    0: red>255  ? 255:(byte)red;
    im.pixels[i][j].green=green<0 ? 0: green>255 ? 255:(byte)green;
    im.pixels[i][j].blue=blue<0 ?  0: blue>255  ? 255:(byte)blue;
    red=0;
    green=0;
    blue=0;
    }}
           
    return im;

Basit bir de kenar bulma algoritması ile fonksiyonun nasıl kullanacağını görelim.

Kod:

resim=resim_acm("istanbul.bmp");//istanbul.bmp resmi açılıyor
            double **filtre;
            filtre = new double* [3];
            for(i=0;i<3;i++) { filtre[i]=new double [3]; }
            filtre[0][0]=-1;
            filtre[0][1]=-1;
            filtre[0][2]=-1;
            filtre[1][0]=-1;
            filtre[1][1]=8;
            filtre[1][2]=-1;
            filtre[2][0]=-1;
            filtre[2][1]=-1;
            filtre[2][2]=-1;
yeni=resim_kon(resim,filtre,3);//resim matrisi ile filtre matrisinin konvolüsyonu alınıyor.
resim_yaz(yeni,"istanbul_k.bmp");//resim istanbul_k adında kaydediliyor

[Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...][Üye Olmadan Linkleri Göremezsiniz. Üye Olmak için TIKLAYIN...]


Alıntı


Tüm Zamanlar GMT +3 Olarak Ayarlanmış. Şuanki Zaman: 20:06.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions, Inc.
Search Engine Friendly URLs by vBSEO
Copyright ©2004 - 2025 IRCForumlari.Net Sparhawk