C++ İLE GÖRÜNTÜ İŞLEME – Resim Dosyası Oluşturmak ve Kaydetmek

Herkese merhabalar. C++ ile görüntü işleme serisinin 2. bölümüne hoşgeldiniz. Bu bölümde resim dosyası oluşturma ve kaydetme işlemleri yapılacaktır.

Eğer serinin ilk bölümünü incelemdiyseniz aşağıdaki linkten serinin birinci bölümüne ulaşabilirsiniz.

https://www.veribilimiokulu.com/wp-admin/post.php?post=14459&action=edit

Serinin ilk bölümünde bahsedildiği gibi; C++ arayüz programı olarak CodeBlocks, Dev C++, Visual Studio gibi arayüz programları (IDE) kullanılabilir.

Projemize kütüphaneleri yükleyerek başlıyoruz.

#include <stdio.h>
#include <stdlib.h>

#include<iostream> = C++ programlama dilinin ana kütüphanesidir ve cin, cout, cerr, ve clog nesnelerini içerir. Ayrica bu kütüphane bilgisayar ekranına birşeyler yazdırıp, programa klavye ile değer girilmesini sağlayan işlevleri barındırır.

#include<stdio.h> =stdio.h başlık dosyasında yer alan C standart giriş ve çıkış kütüphanesindeki fonksiyon, değişken, sabit ve diğer değerler içerir. Bu sistem tarafından desteklenen diğer dosya türleriyle çalışmak için kullanır.

Şimdi ise dizinde bulunan resim dosyasını açacak ve içeriği boş yeni bir resim dosyası oluşturacağız.

FILE *girisDosya = fopen( "resimler/kameraman.bmp", "rb" );
FILE *cikisDosya = fopen( "resimler/kameraman_kopya.bmp" ,"wb" );

Burada fopen fonksiyonu ile dosyaları açma işlemi yapıyoruz. Halihazırda bulunan resim dosyasını sadece okumak için rb parametresini yerleştiriyoruz.

Dosya oluşturmak için wb parametresini yerleştiriyoruz. Bu şekilde kameraman_kopya.bmp adlı boş bir resim dosyası oluşturuyoruz. wb parametresi ile dizinde bulunmayan bir dosya oluşturuyor. Eğer kameraman_kopya.bmp adlı bir resim dosyası var ise silip boş bir dosya haline getirecektir. Bu yüzden dikkatli olmak gerekiyor.

Bir sonraki aşamada resim dosyalarının açılıp açılmadığını kontrol ediyoruz.

if( girisDosya == ( FILE* )0 )
{
    printf( "dosya açılamadı.\n" );
}

Eğer dosya açma işlemi sırasında hata olursa dosya açılamadı çıktısı alacaksınız.

Sırada açtığımız resim dosyasının bilgilerine ulaşıp aktarmak için değişkenler oluşturuyoruz.

unsigned char bilgiDepo[54];
unsigned char piksels[1024];

Komutlar ile resim içerik bilgilerini yüklemek için 54 kapasiteli bilgiDepo dizisi, resim piksel değerlerini depolamak için 1024 kapasiteli piksels dizisi oluşturuyoruz.

unsigned komutu ile dizimizin maksimum 255 minimum 0 değerleri almasını sağlıyoruz.

Sırada oluşturduğumuz değişkenlere resim dosyasının içerik bilgilerini aktaracağız.

for(int i = 0; i < 54; i++)
{
bilgiDepo[i] = getc(girisDosya);
}

getc fonksiyonu karakter okuma işlemini yapar ve bellek değişkenine aktarır.

Resim içeriklerini aktardığımız bilgiDepo değişkeni içerisinden resim genişliği, uzunluğu, bit derinliği değişkenlerini alacağız.

int genislik = *(int *)&bilgiDepo[18]; 
int uzunluk = *(int *)&bilgiDepo[22];
int bitDerinlik = *(int *)&bilgiDepo[28];

Komutlar ile bilgiDepo dizisinde tamsayı şeklinde genişlik, uzunluk, bitDerinlik gibi özellikleri alıyoruz. Burada dizimizin 18. sırasında resim genişlik değeri, 22. sırasında uzunluk değeri, 28. sırasında resmin bit değeri yer almaktadır. Bu değerleri oluşturduğumuz değişkenlere aktarıyoruz.

if( bitDerinlik<=8 )
    {
         fread( piksels, sizeof(unsigned char), 1024, girisDosya );
    }

Komutu ile resim dosyasını bit derinliği kontrol ediliyor ve giriş resminin bit derinliğine göre yeniden okuma işlemi yapılıyor.

fwrite( bitDerinlik, sizeof(unsigned char), 54, cikisDosya );
unsigned char buf[yükseklik * genişlik];
fread( buf, sizeof(unsigned char), (yükseklik*genişlik), girisDosya );

Komutları ile Çıkış dosyasına değişkenlerin içindeki bilgileri aktarma işlemi yapılıyor.

buf dizisi oluşturup boyutu resim dosyasının pikselleri toplamı olarak belirleniyor.

giriş dosyası, buf dizisine göre yeniden okuma işlemi yapılıyor.

if( bitDerinlik <=8 )
   {
       fwrite( piksels, sizeof(unsigned char), 1024, cikisDosya );
   }

Resim bit derinliği sekiz veya sekizden az ise çıkış dosyasına yazma işlemi yapılıyor.

 fwrite( buf, sizeof(unsigned char), (yükseklik *genişlik), cikisDosya );

Resim bit derinliği sekiz bitten fazla ise yeniden ayarlanıp yazma işlemi yapılıyor.

Bu işlemlerden sonra yeni bir resim dosyası oluşturuldu. Okunan resmin bilgileri alındı ve yeni resim üzerine aktarıldı.

Okunan resmin kopyası oluşturulmuş oldu.

İşlemler bittikten sonra girisDosyasını ve cikisDosyasını kapatıyoruz.

fclose( cikisDosya );
fclose( girisDosya );

Eğer tüm işlemler başarılı bir şekilde sonuçlandı ise aşağıdaki komutların çıktılarını alacağız.

printf( "Başarı ile oluşturuldu !\n" );
printf( "Genişlik : %d\n", genişlik );
printf( "Yükseklik : %d\n", yükseklik );
Şekil 1: Resim klasörü içindekiler

Şekil 1′ de gözüktüğü gibi okunan resmin kopyası oluşturulmuş oldu.

Şekil 2: Giriş ve Çıkış resimleri

Serinin sonraki resimleri okuma işlemi yapılacak ve birçok görüntü işleme algoritmaları uygulanacaktır. Resim üzerinde yapılan değişiklikler yukarıda anlatılan komutlar ile gerçekleştirilecektir.

C++ ile Görüntü işleme serimizin ikinci bölümünde Resim dosyası oluşturma ve kaydetme konusu anlatıldı.

Tüm koda ulaşmak için;

https://github.com/enesdoruk/Image-Processing-with-C/blob/master/ResimDosyas%C4%B1OlusturmakVeKaydetmek/ResimDosyas%C4%B1OlusturmakVeKaydetmek.cpp

Serinin sonraki bölümünde görüşmek dileğiyle.

Kaynakça

Yazar Hakkında
Toplam 14 yazı
Abdullah Enes Doruk
Abdullah Enes Doruk
Bursa Teknik Üniversitesi Elektrik Elektronik Mühendisliği Bölümü öğrencisi. İlgilendiği alanlar; Görüntü işleme, Sürücüsüz Araçlar, Derin Öğrenme. Abdullah Enes Doruk
Yorumlar (Yorum yapılmamış)

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

×

Bir Şeyler Ara