Bu yazı kapsamında Python ile OPENCV kütüphanesini kullanarak basit bir nesne tespiti/sınıflama uygulamasını nasıl gerçekleştirebileceğinizi anlatacağım. Örneğimizde OpenCV ML (machine learning) modülü içerisindeki SVM(Support Vector Machine) ve Object Detection modülü içerisindeki HOG yöntemlerini kullanacağız.
SVM etiketlenmiş bir veri kümesindeki farklı sınıfları birbirinden ayıracak hyperplane(düzlemleri) çıkararak sınıflama işlemi gerçekleştirir. OpenCV dökümantasyonundan detaylı bilgilere erişebilirsiniz. HOG(Histogram of Gradient) yöntemi ise görüntü üzerinden özellik çıkarımı yapan bir yöntemdir. Alternatif olarak SURF ve ORB metotları da bir başka özellik çıkarımı yöntemleri olarak sıralanabilir. Özellik çıkarımından kastedilen şey, örneğin 224x224 boyutlarındaki bir görüntüyü işleyip, bu görüntüyü ifade eden 255 elemandan oluşan bir vektörün çıkarılması olarak düşünülebilir. Elde edilen bu daha düşük boyutlu vektörde önemli bilgilerin(özelliklerin) tutulması, gereksiz bilgilerin ise atılması hedeflenmektedir.
HOG metotunda, yatay ve dikey gradyanlar alındıktan sonra bu gradyanların histogramı hesaplanır. x ve y ekseninde hesaplanmış gradyan örneğini aşağıdaki resimde görebilirsiniz. Bu ve bunun gibi görüntü işlemede temel teşkil eden konuları öğrenmek ve uygulamalı örneklerle bunları pekiştirmek için udemy'deki kursuma göz atabilirsiniz. :) (İletişim sayfasından ulaşırsanız sizlere kupon kodu tanımlayabilirim)
Kullanacağımız yöntemlerle ilgili bu çok temel bilgilerden sonra kodları yazmaya başlayabiliriz. İlk yapacağımız bir çeşit makine öğrenmesi yöntemi olan SVM'i eğitmek amaçlı kullanacağımız bir örnek veri seti hazırlamak. Ben örnek olarak kolonya tespit uygulaması yapmaya karra verdim, bu sebeple kolonya içeren ve içermeyen bir dizi görüntü içeren iki farklı klasör oluşturdum. Siz görüntü sayısını arttırarak yöntemin performansını daha iyi test edebilirsiniz. Hazırladığım örnek veri setine ait görüntüleri aşağıda görebilirsiniz.
Şimdi bu kadar girizgahtan sonra bu 2 klasördeki görüntüleri alıp, HOG ile özellik çıkarımını yapıp, SVM ile modeli eğitip sonucunu bir dosyaya kaydeden örnek python kodunu paylaşıyorum.
import cv2 import os import numpy as np def loadImages(hog, path): file_list = os.listdir(path) x = [] for filename in file_list: img = cv2.imread(path + filename) hist = hog.compute(img) x.append(hist) return x winSize = (128, 128) blockSize = (64, 64) blockStride = (64, 64) cellSize = (32, 32) nBin = 9 hog = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nBin) featuresCologne = np.array(loadImages(hog, "dataset/1/")) featuresOther = np.array(loadImages(hog, "dataset/0/")) labelsCologne = np.ones(((len(featuresCologne),1)), np.int32) labelsOther = np.zeros(((len(featuresOther),1)), np.int32) features = np.float32(np.concatenate((featuresCologne, featuresOther), axis=0)) labels = np.concatenate((labelsCologne, labelsOther), axis=0) svm = cv2.ml.SVM_create() svm.setType(cv2.ml.SVM_C_SVC) svm.setKernel(cv2.ml.SVM_LINEAR) svm.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, int(1e7), 1e-6)) print("training....") ret = svm.train(features, cv2.ml.ROW_SAMPLE, labels) svm.save('svm_data_hog.xml')
Eğitilmiş modeli kullanarak bir video üzerindeki belirli bir bölgedeyi (ROI) tarayan ve buraya göstermiş olduğum kolonyayı tanımaya yarayan kod parçacığını ise aşağıya bırakıyorum.
import cv2 import numpy as np winSize = (128, 128) blockSize = (64, 64) blockStride = (64, 64) cellSize = (32, 32) nBin = 9 hog = cv2.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nBin) svm = cv2.ml.SVM_create() svm = cv2.ml.SVM_load("svm_data_hog.xml") cap = cv2.VideoCapture(0) if not cap.isOpened(): print("Cannot open camera") exit() x,y,w,h = 20, 50, 243, 348 while True: ret, frame = cap.read() if not ret: print("Can't receive frame. Byess") break cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),1) patch = frame[y:y+h, x:x+w, :] hist = hog.compute(patch) inputX = np.float32(np.expand_dims(hist, axis=0)) res = svm.predict(inputX)[1] print(res) ch = cv2.waitKey(1) if ch == ord('q'): break if res[0] == 1: cv2.putText(frame, "It is a Cologne", (x,y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255),1) cv2.imshow("frames", frame) cap.release() cv2.destroyAllWindows()
Ve son olarak uygulamanın örnek bir çıktısı
Her türlü görüş, öneri ve sorularınızı iletebilirsiniz...
Hiç yorum yok:
Yorum Gönder