Bilgisayar Görüsüne Giriş

Bilgisayar görüsü (Computer Vision), bilgisayarların dijital görüntülerden ve videolardan anlamlı bilgiler çıkarmasını sağlayan yapay zeka alanıdır. İnsan görme sistemini taklit etmeyi amaçlayan bu disiplin, görüntülerdeki nesneleri tanıma, sınıflandırma, takip etme ve analiz etme yetenekleri geliştirir.
Bilgisayar görüsü, günlük hayatımızda birçok alanda kullanılmaktadır:
Tıbbi Görüntüleme: X-ray, MRI ve CT taramalarının analizi
Otonom Araçlar: Yol işaretlerini tanıma, engel tespiti
Güvenlik Sistemleri: Yüz tanıma, hareket algılama
Endüstriyel Otomasyon: Kalite kontrol, robotik görme
Sosyal Medya: Fotoğraflarda otomatik etiketleme
Augmented Reality (AR): Gerçek dünya üzerine dijital içerik ekleme

Görüntü İşlemenin Temel Kavramları

Dijital bir görüntü, piksel adı verilen küçük noktalardan oluşan iki boyutlu bir matristir. Her piksel, renk bilgisini sayısal değerler olarak saklar:
Gri Tonlamalı Görüntüler: Her piksel 0-255 arasında bir değer (0=siyah, 255=beyaz)
Renkli Görüntüler: RGB (Kırmızı, Yeşil, Mavi) kanalları, her kanal 0-255 değer aralığında
Görüntü işleme, bu piksel değerlerini matematiksel operasyonlarla manipüle ederek görüntüyü iyileştirme, filtreleme, özellik çıkarma ve analiz etme sürecidir.

OpenCV Kütüphanesine Giriş

OpenCV (Open Source Computer Vision Library), Intel tarafından başlatılan ve şu anda geniş bir topluluk tarafından geliştirilen açık kaynaklı bir bilgisayar görüsü kütüphanesidir. C++, Python, Java ve diğer dillerde kullanılabilen OpenCV, görüntü işleme ve bilgisayar görüsü için kapsamlı araçlar sunar.

OpenCV'nin Temel Özellikleri

Geniş Algoritma Yelpazesi: 2500'den fazla optimize edilmiş algoritma
Çoklu Platform Desteği: Windows, Linux, macOS, Android, iOS
Gerçek Zamanlı İşleme: Video akışları için optimize edilmiş
Makine Öğrenmesi Entegrasyonu: ML algoritmaları dahili olarak mevcut
GPU Hızlandırma: CUDA ve OpenCL desteği

OpenCV Kurulumu

pip install opencv-python pip install opencv-contrib-python # Ek modüller için

Temel Görüntü İşleme Operasyonları

Görüntü Yükleme, Gösterme ve Kaydetme

import cv2 import numpy as np import matplotlib.pyplot as plt # Görüntü yükleme image = cv2.imread('example.jpg') # OpenCV BGR formatında yükler, RGB'ye çevirmek için: image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # Görüntü boyutlarını öğrenme height, width, channels = image.shape print(f"Görüntü boyutları: {width}x{height}, Kanal sayısı: {channels}") # Görüntüyü gösterme (OpenCV penceresi) cv2.imshow('Orijinal Görüntü', image) cv2.waitKey(0) # Bir tuşa basılmasını bekle cv2.destroyAllWindows() # Tüm pencereleri kapat # Matplotlib ile gösterme (RGB formatında) plt.figure(figsize=(10, 6)) plt.subplot(1, 2, 1) plt.imshow(image_rgb) plt.title('Orijinal Görüntü') plt.axis('off') # Görüntüyü kaydetme cv2.imwrite('output.jpg', image)

Renk Uzayı Dönüşümleri

# BGR'den gri tonlamaya çevirme gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # BGR'den HSV'ye çevirme (Hue, Saturation, Value) hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # Sonuçları görselleştirme plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.imshow(image_rgb) plt.title('Orijinal (RGB)') plt.axis('off') plt.subplot(1, 3, 2) plt.imshow(gray, cmap='gray') plt.title('Gri Tonlama') plt.axis('off') plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB)) plt.title('HSV') plt.axis('off') plt.tight_layout() plt.show()

Görüntü Filtreleme ve Bulanıklaştırma

# Gaussian Blur (Gauss bulanıklaştırma) gaussian_blur = cv2.GaussianBlur(image, (15, 15), 0) # Median Blur (Medyan filtresi - gürültü giderme için iyi) median_blur = cv2.medianBlur(image, 15) # Bilateral Filter (kenarları koruyarak bulanıklaştırma) bilateral = cv2.bilateralFilter(image, 15, 80, 80) # Sonuçları karşılaştırma plt.figure(figsize=(20, 5)) plt.subplot(1, 4, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title('Orijinal') plt.axis('off') plt.subplot(1, 4, 2) plt.imshow(cv2.cvtColor(gaussian_blur, cv2.COLOR_BGR2RGB)) plt.title('Gaussian Blur') plt.axis('off') plt.subplot(1, 4, 3) plt.imshow(cv2.cvtColor(median_blur, cv2.COLOR_BGR2RGB)) plt.title('Median Blur') plt.axis('off') plt.subplot(1, 4, 4) plt.imshow(cv2.cvtColor(bilateral, cv2.COLOR_BGR2RGB)) plt.title('Bilateral Filter') plt.axis('off') plt.tight_layout() plt.show()

Kenar Algılama

# Canny kenar algılama edges = cv2.Canny(gray, 50, 150) # Sobel kenar algılama sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3) sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3) sobel_combined = np.sqrt(sobel_x**2 + sobel_y**2) # Laplacian kenar algılama laplacian = cv2.Laplacian(gray, cv2.CV_64F) plt.figure(figsize=(20, 5)) plt.subplot(1, 4, 1) plt.imshow(gray, cmap='gray') plt.title('Orijinal (Gri)') plt.axis('off') plt.subplot(1, 4, 2) plt.imshow(edges, cmap='gray') plt.title('Canny Kenar Algılama') plt.axis('off') plt.subplot(1, 4, 3) plt.imshow(sobel_combined, cmap='gray') plt.title('Sobel Kenar Algılama') plt.axis('off') plt.subplot(1, 4, 4) plt.imshow(np.abs(laplacian), cmap='gray') plt.title('Laplacian Kenar Algılama') plt.axis('off') plt.tight_layout() plt.show()

Nesne Algılama ve Tanıma

Şablon Eşleştirme (Template Matching)

def template_matching_demo(): # Ana görüntü ve şablon yükleme main_image = cv2.imread('main_image.jpg') template = cv2.imread('template.jpg') # Gri tonlamaya çevirme main_gray = cv2.cvtColor(main_image, cv2.COLOR_BGR2GRAY) template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) # Şablon boyutları h, w = template_gray.shape # Şablon eşleştirme result = cv2.matchTemplate(main_gray, template_gray, cv2.TM_CCOEFF_NORMED) # En iyi eşleşmeyi bulma min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) # Eşleşme eşiği threshold = 0.8 if max_val >= threshold: # Eşleşen bölgeyi çerçeveleme top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(main_image, top_left, bottom_right, (0, 255, 0), 2) print(f"Şablon bulundu! Güven skoru: {max_val:.2f}") else: print("Şablon bulunamadı.") # Sonuçları gösterme plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(template, cv2.COLOR_BGR2RGB)) plt.title('Şablon') plt.axis('off') plt.subplot(1, 3, 2) plt.imshow(result, cmap='hot') plt.title('Eşleştirme Sonucu') plt.axis('off') plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(main_image, cv2.COLOR_BGR2RGB)) plt.title('Tespit Edilen Nesne') plt.axis('off') plt.tight_layout() plt.show() # template_matching_demo() # Görüntü dosyaları mevcut olduğunda çalıştır

Haar Cascade ile Yüz Algılama

def face_detection_demo(): # Haar cascade sınıflandırıcısını yükleme face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml') # Görüntü yükleme image = cv2.imread('face_image.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Yüz algılama faces = face_cascade.detectMultiScale(gray, 1.3, 5) print(f"{len(faces)} yüz algılandı.") # Algılanan yüzleri çerçeveleme for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x+w, y+h), (255, 0, 0), 2) # Yüz bölgesinde göz algılama roi_gray = gray[y:y+h, x:x+w] roi_color = image[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex, ey, ew, eh) in eyes: cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2) # Sonucu gösterme plt.figure(figsize=(10, 8)) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title('Yüz ve Göz Algılama') plt.axis('off') plt.show() # face_detection_demo() # Yüz içeren görüntü dosyası mevcut olduğunda çalıştır

Kontur Algılama ve Şekil Analizi

def contour_analysis_demo(): # Basit bir şekil oluşturma (örnek için) image = np.zeros((400, 400, 3), dtype=np.uint8) # Çeşitli şekiller çizme cv2.rectangle(image, (50, 50), (150, 150), (255, 255, 255), -1) cv2.circle(image, (300, 100), 50, (255, 255, 255), -1) cv2.ellipse(image, (200, 300), (80, 40), 0, 0, 360, (255, 255, 255), -1) # Gri tonlamaya çevirme gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Konturları bulma contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Kontur analizi result_image = image.copy() for i, contour in enumerate(contours): # Kontur alanı area = cv2.contourArea(contour) # Kontur çevresi perimeter = cv2.arcLength(contour, True) # Kontur yaklaşımı epsilon = 0.02 * perimeter approx = cv2.approxPolyDP(contour, epsilon, True) # Şekil sınıflandırma if len(approx) == 3: shape = "Üçgen" elif len(approx) == 4: shape = "Dörtgen" elif len(approx) > 4: shape = "Daire/Elips" else: shape = "Bilinmeyen" # Konturları çizme cv2.drawContours(result_image, [contour], -1, (0, 255, 0), 2) # Merkez noktasını bulma M = cv2.moments(contour) if M["m00"] != 0: cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) # Şekil bilgisini yazma cv2.putText(result_image, f"{shape}", (cx-30, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1) print(f"Şekil {i+1}: {shape}, Alan: {area:.0f}, Çevre: {perimeter:.0f}") # Sonuçları gösterme plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title('Orijinal Şekiller') plt.axis('off') plt.subplot(1, 3, 2) plt.imshow(gray, cmap='gray') plt.title('Gri Tonlama') plt.axis('off') plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB)) plt.title('Kontur Analizi') plt.axis('off') plt.tight_layout() plt.show() contour_analysis_demo()

Video İşleme

def video_processing_demo(): # Video dosyasını açma (0 = webcam) cap = cv2.VideoCapture(0) # Webcam için # cap = cv2.VideoCapture('video.mp4') # Video dosyası için # Video özelliklerini alma fps = cap.get(cv2.CAP_PROP_FPS) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) print(f"Video özellikleri: {width}x{height} @ {fps} FPS") # Video yazıcı oluşturma (isteğe bağlı) fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('output.avi', fourcc, fps, (width, height)) # Arka plan çıkarıcı backSub = cv2.createBackgroundSubtractorMOG2() while True: ret, frame = cap.read() if not ret: break # Arka plan çıkarma (hareket algılama) fgMask = backSub.apply(frame) # Gürültü giderme kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) fgMask = cv2.morphologyEx(fgMask, cv2.MORPH_OPEN, kernel) # Konturları bulma contours, _ = cv2.findContours(fgMask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Büyük konturları çerçeveleme for contour in contours: if cv2.contourArea(contour) > 500: # Minimum alan eşiği x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) cv2.putText(frame, 'Hareket', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) # Sonuçları gösterme cv2.imshow('Orijinal', frame) cv2.imshow('Ön Plan Maskesi', fgMask) # Video dosyasına yazma (isteğe bağlı) # out.write(frame) # 'q' tuşuna basılırsa çık if cv2.waitKey(1) & 0xFF == ord('q'): break # Kaynakları serbest bırakma cap.release() out.release() cv2.destroyAllWindows() # video_processing_demo() # Webcam veya video dosyası mevcut olduğunda çalıştır

Masaüstü Uygulamasında OpenCV Kullanımı

Tkinter ile OpenCV entegrasyonu örneği:
import tkinter as tk from tkinter import filedialog, messagebox from PIL import Image, ImageTk import cv2 import numpy as np class ImageProcessorApp: def __init__(self, root): self.root = root self.root.title("OpenCV Görüntü İşleyici") self.root.geometry("800x600") self.original_image = None self.processed_image = None self.setup_ui() def setup_ui(self): # Menü çubuğu menubar = tk.Menu(self.root) self.root.config(menu=menubar) file_menu = tk.Menu(menubar, tearoff=0) menubar.add_cascade(label="Dosya", menu=file_menu) file_menu.add_command(label="Görüntü Aç", command=self.open_image) file_menu.add_command(label="Kaydet", command=self.save_image) file_menu.add_separator() file_menu.add_command(label="Çıkış", command=self.root.quit) # Ana çerçeve main_frame = tk.Frame(self.root) main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # Kontrol paneli control_frame = tk.Frame(main_frame) control_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10)) tk.Label(control_frame, text="Görüntü İşleme Araçları", font=("Arial", 12, "bold")).pack(pady=(0, 10)) # İşleme butonları tk.Button(control_frame, text="Gri Tonlama", command=self.convert_to_gray, width=15).pack(pady=2) tk.Button(control_frame, text="Gaussian Blur", command=self.apply_gaussian_blur, width=15).pack(pady=2) tk.Button(control_frame, text="Kenar Algılama", command=self.detect_edges, width=15).pack(pady=2) tk.Button(control_frame, text="Histogram Eşitleme", command=self.equalize_histogram, width=15).pack(pady=2) tk.Button(control_frame, text="Orijinali Geri Yükle", command=self.restore_original, width=15).pack(pady=2) # Görüntü gösterme alanı self.image_frame = tk.Frame(main_frame, bg="lightgray") self.image_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) self.image_label = tk.Label(self.image_frame, text="Görüntü yüklemek için Dosya > Görüntü Aç", bg="lightgray") self.image_label.pack(expand=True) def open_image(self): file_path = filedialog.askopenfilename( title="Görüntü Seç", filetypes=[("Görüntü dosyaları", "*.png *.jpg *.jpeg *.bmp *.tiff")] ) if file_path: self.original_image = cv2.imread(file_path) self.processed_image = self.original_image.copy() self.display_image(self.processed_image) def display_image(self, cv_image): # OpenCV görüntüsünü Tkinter için hazırlama if len(cv_image.shape) == 3: cv_image_rgb = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB) else: cv_image_rgb = cv_image # Görüntüyü yeniden boyutlandırma (pencereye sığdırma) height, width = cv_image_rgb.shape[:2] max_width, max_height = 500, 400 if width > max_width or height > max_height: scale = min(max_width/width, max_height/height) new_width = int(width * scale) new_height = int(height * scale) cv_image_rgb = cv2.resize(cv_image_rgb, (new_width, new_height)) # PIL Image'e çevirme if len(cv_image_rgb.shape) == 2: pil_image = Image.fromarray(cv_image_rgb, mode='L') else: pil_image = Image.fromarray(cv_image_rgb) # Tkinter PhotoImage'e çevirme photo = ImageTk.PhotoImage(pil_image) # Görüntüyü gösterme self.image_label.config(image=photo, text="") self.image_label.image = photo # Referansı koruma def convert_to_gray(self): if self.processed_image is not None: self.processed_image = cv2.cvtColor(self.processed_image, cv2.COLOR_BGR2GRAY) self.display_image(self.processed_image) def apply_gaussian_blur(self): if self.processed_image is not None: self.processed_image = cv2.GaussianBlur(self.processed_image, (15, 15), 0) self.display_image(self.processed_image) def detect_edges(self): if self.processed_image is not None: if len(self.processed_image.shape) == 3: gray = cv2.cvtColor(self.processed_image, cv2.COLOR_BGR2GRAY) else: gray = self.processed_image self.processed_image = cv2.Canny(gray, 50, 150) self.display_image(self.processed_image) def equalize_histogram(self): if self.processed_image is not None: if len(self.processed_image.shape) == 3: # Renkli görüntü için YUV renk uzayında histogram eşitleme yuv = cv2.cvtColor(self.processed_image, cv2.COLOR_BGR2YUV) yuv[:,:,0] = cv2.equalizeHist(yuv[:,:,0]) self.processed_image = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR) else: # Gri tonlamalı görüntü için direkt histogram eşitleme self.processed_image = cv2.equalizeHist(self.processed_image) self.display_image(self.processed_image) def restore_original(self): if self.original_image is not None: self.processed_image = self.original_image.copy() self.display_image(self.processed_image) def save_image(self): if self.processed_image is not None: file_path = filedialog.asksaveasfilename( title="Görüntüyü Kaydet", defaultextension=".jpg", filetypes=[("JPEG", "*.jpg"), ("PNG", "*.png"), ("BMP", "*.bmp")] ) if file_path: cv2.imwrite(file_path, self.processed_image) messagebox.showinfo("Başarılı", "Görüntü başarıyla kaydedildi!") if __name__ == "__main__": root = tk.Tk() app = ImageProcessorApp(root) root.mainloop()

Gelişmiş Konular

Özellik Algılama (Feature Detection)

def feature_detection_demo(): # Görüntü yükleme image = cv2.imread('example.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # SIFT (Scale-Invariant Feature Transform) özellik algılayıcı sift = cv2.SIFT_create() keypoints_sift, descriptors_sift = sift.detectAndCompute(gray, None) # ORB (Oriented FAST and Rotated BRIEF) özellik algılayıcı orb = cv2.ORB_create() keypoints_orb, descriptors_orb = orb.detectAndCompute(gray, None) # Özellik noktalarını çizme image_sift = cv2.drawKeypoints(image, keypoints_sift, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) image_orb = cv2.drawKeypoints(image, keypoints_orb, None, color=(0,255,0)) print(f"SIFT özellik noktası sayısı: {len(keypoints_sift)}") print(f"ORB özellik noktası sayısı: {len(keypoints_orb)}") # Sonuçları gösterme plt.figure(figsize=(15, 5)) plt.subplot(1, 3, 1) plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) plt.title('Orijinal Görüntü') plt.axis('off') plt.subplot(1, 3, 2) plt.imshow(cv2.cvtColor(image_sift, cv2.COLOR_BGR2RGB)) plt.title('SIFT Özellik Noktaları') plt.axis('off') plt.subplot(1, 3, 3) plt.imshow(cv2.cvtColor(image_orb, cv2.COLOR_BGR2RGB)) plt.title('ORB Özellik Noktaları') plt.axis('off') plt.tight_layout() plt.show() # feature_detection_demo() # Görüntü dosyası mevcut olduğunda çalıştır

Sonuç

Bu derste, OpenCV kütüphanesi kullanarak görüntü işleme ve bilgisayar görüsünün temel kavramlarını öğrendiniz. OpenCV, masaüstü uygulamalarınıza güçlü görsel analiz yetenekleri kazandırmak için mükemmel bir araçtır. Yüz tanıma, nesne algılama, hareket takibi ve görüntü iyileştirme gibi özellikler, uygulamalarınızı daha akıllı ve kullanışlı hale getirebilir.
Bir sonraki derste, doğal dil işleme (NLP) konularını inceleyeceğiz ve metin tabanlı yapay zeka uygulamalarını masaüstü programlarına nasıl entegre edeceğimizi öğreneceğiz.