Pazar, Ekim 07, 2007

OpenCv'ye Giriş 3

ilk örneğimizde görüntü dosyasını okuyup ekranda gösterdik. Ama eksik bir nokta kaldı kaydetmek için ne yapacağız ?
Görüntüyü Kaydetmemiz gerektiğinde cvSaveImage fonksiyonunu kullanıyoruz.

int cvSaveImage( const char* filename, const CvArr* image );
filename : Kaydedilecek Görüntüye vereceğimiz dosya ismi dosya isminde kullandığımız
uzantıya göre kaydedilir. mesela a.jpg dersek jpg formatında a.bmp dersek bmp formatında
kaydedilir.
image : Kaydedilecek Görüntünün işaretçisi

Görüntü dediğimiz şey Renk noktalarından - piksel - oluşan 2 boyutlu bir matristir. görüntüyle ilgili işlemler için bizim bu noktaları okuyup yazmamız lazım. Piksel deki renk değerleri değişik şekillerde tutulabilir ben yaygın olan iksini belirteceğim
Gri Resim : Her piksel renk değeri tek kanalda 1 byte da tutulur 0 siyah en koyu -255 beyaz en parlak renk
RGB Renkli Resim : Her renk değeri Kırmızı - Red - Yeşil -Green- ve Mavi -Blue- olmak üzere 3 kanalda tutulur her kanal büyüklüğü 1 byte dır.
Konunun detayları için bakınız : Sayısal Resim , Renkler , Gri ve Renkli Resimler

OpenCv de bu işi nasıl yaparız ?
Biraz karmaşık görülebilecek fakat en hızlı yolu işaretçileri kullanmaktır. bu değerlere ulaşmak için IplImage yapısını kullanacağız. görüntü bir matrsidir dedik
sütün sayısı -x ekseni - yani eni width değerinde tutulur.
satır sayısı -y ekseni - yani yüksekliği height değerinde tutulur
IplImage in imageData işaretçisi piksel değerlerinin başlangıcıdır.

int height = grnt->height; // yükseklik
int width = grnt->width; // En
int step = grnt->widthStep; // En x Kanal
int channels = grnt->nChannels; // Kanal sayısı
uchar *data = (uchar *)grnt->imageData;
uğraşmak istediğimiz pikselin koordinatlarını (x y) kullanarak
data[y*step+x*channels+k]
yani (10,20) koordinatlarındaki piksel için
Gri resim için
data[20*step+10*channels+0]
RGB Renkli resim için
data[20*step+10*channels+0] // Mavi
data[20*step+10*channels+1] // Yeşil
data[20*step+10*channels+2] // Kırmızı
şeklinde okuyup yazabiliriz.

Aşağıda bir örnek program var Örnek Program da iki tane görüntü açıyoruz Ekranda gösterirken İlk görüntüden ikinci görüntüye geçiş yapıyoruz. İlk görüntü silikleşirken ikinci görünmeye başlıyor.
Ders3
indirin çalıştırın inceleyin anlamadığınız yer olursa - olmaz ya hani belki - çekinmeden sorabilirsiniz...


Örnekte ilk defa kullandığımız fonksiyonları kısaca anlatalım
IplImage* cvCreateImage( CvSize size, int depth, int channels );
İstenen özelliklerde Boş görüntü oluşturmak için kullanılır.

size : Oluşturulcak Görüntünün ebatları
CvSize ebatları tutan bir yapıdır
typedef struct CvSize
{
int width; /* width of the rectangle */
int height; /* height of the rectangle */
}
CvSize;
şeklinde tanımlanmış değerlere atama yapmak için
cvSize( int width, int height );
fonksiyonu kullanılır.

depth : Biz buna renk derinliği diyelim Oluşturulacak görüntünün piksel renk değerlerinin
her kanal için büyüklüğü tanımlanır. biz genellikle IPL_DEPTH_8U yani 8 bit - 1 byte - işaretsiz tamsayı kullanıyoruz. tabii değişik alternatiflerde var
IPL_DEPTH_8U - unsigned 8-bit integers
IPL_DEPTH_8S - signed 8-bit integers
IPL_DEPTH_16U - unsigned 16-bit integers
IPL_DEPTH_16S - signed 16-bit integers
IPL_DEPTH_32S - signed 32-bit integers
IPL_DEPTH_32F - single precision floating-point numbers
IPL_DEPTH_64F - double precision floating-point numbers
gibi kafanızı karıştırmayın kullandıkça öğrenirsizin

channels : her piksel için kullanılan kanal sayısı 1 gri sevyeli resimler için 3 RGB renkli resimler için.
void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR );
Görüntünün ebatlarını değiştirmenize yarar

src : Ebatı değiştirilecek resim
dst : Yeni ebatları içeren resim
interpolation : Ebat değişikliği işleminde kullanılacak yöntem
  • CV_INTER_NN - nearest-neigbor interpolation,
  • CV_INTER_LINEAR - bilinear interpolation (used by default)
  • CV_INTER_AREA - resampling using pixel area relation. It is preferred method for image
  • decimation that gives moire-free results. In case of zooming it is similar to CV_INTER_NN method.
  • CV_INTER_CUBIC - bicubic interpolation.
void cvMoveWindow( const char* name, int x, int y );
Pencereyi ekranda istediğiniz yerde konumlandırmanıza yarar.
name : Konumlandırılacak pencerenin adı
x ve y : Pencerenin ekrandaki sol üst köşesinin konumu

Son olarak Opencv için bir chm dosyası oluşturdum
Opencv.chm
indirin. CodeBlocks içinde
Settings -> Environment -> Help Files kısmından yardım dosyası olarak tanımlayın
ulaşımınız kolay olsun.

1 yorum:

onur dedi ki...

Merhabalar ;
---------------------------------
for(int i=0;i<height;i++)
{ cout<<endl;
for(int j=0;j<width;j++)
{
cout<<data1[i*step+j*channels+0]<<" ";
}
}
---------------------------------
Şeklinde resmin pixel değerlerinin olduğu 2-boyutlu matrisi ekrana bastırırken sonsuz döngüye giriyor.Ayrıca tek tek bastırdığımda(galiba uchar dan dolayı)8-bit li sayılar yerine harf bastırıyor?.bu sorunu nasıl çözebilirim?.teşekkürler