SIFT 특징 및 SVM 기반 이미지 분류
방법:
1. 그림 유형 에 따라 모든 그림 의 SIFT 특징 을 추출 하여 훈련 합 니 다.
2. 각 유형의 그림 의 SIFT 특징 을 K 류 로 분류 하여 이러한 visual vocabulary (size 는 K) 를 구성한다.
3. 훈련 에 집 중 된 모든 사진 에 대해 vocabulary 에서 K 개의 단어의 '주파수' 를 통계 하여 해당 하 는 직사 도 를 얻는다.
4. 직사 도 를 샘플 벡터 로 하면 SVM 의 훈련 데이터 와 테스트 데 이 터 를 구축 할 수 있다.
python (numpy & opencv) 으로 샘플 을 만 들 었 습 니 다. 정확 도 는 약 89% 이 고 개선 할 수 있 습 니 다.
해당 코드 는 다음 과 같 습 니 다.
'''
@author: Tiejian Zhang
@email: [email protected]
@method: SIFT -> k-means -> SVM
'''
import cv2
import numpy as np
TrainSetInfo = {
"car" : 40,
"city" : 20,
"dog" : 30,
"earth" : 15,
"fireworks" : 20,
"flowers" : 20,
"fruits" : 20,
"glass" : 20,
"gold" : 15,
"gun" : 20,
"plane" : 40,
"sky" : 30,
"worldcup" : 40
}
TestSetInfo = {
"car" : 119,
"city" : 59,
"dog" : 49,
"earth" : 24,
"fireworks" : 54,
"flowers" : 63,
"fruits" : 78,
"glass" : 52,
"gold" : 44,
"gun" : 44,
"plane" : 102,
"sky" : 78,
"worldcup" : 131
}
def calcSiftFeature(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT(200) # max number of SIFT points is 200
kp, des = sift.detectAndCompute(gray, None)
return des
def calcFeatVec(features, centers):
featVec = np.zeros((1, 50))
for i in range(0, features.shape[0]):
fi = features[i]
diffMat = np.tile(fi, (50, 1)) - centers
sqSum = (diffMat**2).sum(axis=1)
dist = sqSum**0.5
sortedIndices = dist.argsort()
idx = sortedIndices[0] # index of the nearest center
featVec[0][idx] += 1
return featVec
def initFeatureSet():
for name, count in TrainSetInfo.items():
dir = "TrainSet/" + name + "/"
featureSet = np.float32([]).reshape(0,128)
print "Extract features from TrainSet " + name + ":"
for i in range(1, count + 1):
filename = dir + name + " (" + str(i) + ").jpg"
img = cv2.imread(filename)
des = calcSiftFeature(img)
featureSet = np.append(featureSet, des, axis=0)
featCnt = featureSet.shape[0]
print str(featCnt) + " features in " + str(count) + " images
"
# save featureSet to file
filename = "Temp/features/" + name + ".npy"
np.save(filename, featureSet)
def learnVocabulary():
wordCnt = 50
for name, count in TrainSetInfo.items():
filename = "Temp/features/" + name + ".npy"
features = np.load(filename)
print "Learn vocabulary of " + name + "..."
# use k-means to cluster a bag of features
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.1)
flags = cv2.KMEANS_RANDOM_CENTERS
compactness, labels, centers = cv2.kmeans(features, wordCnt, criteria, 20, flags)
# save vocabulary(a tuple of (labels, centers)) to file
filename = "Temp/vocabulary/" + name + ".npy"
np.save(filename, (labels, centers))
print "Done
"
def trainClassifier():
trainData = np.float32([]).reshape(0, 50)
response = np.float32([])
dictIdx = 0
for name, count in TrainSetInfo.items():
dir = "TrainSet/" + name + "/"
labels, centers = np.load("Temp/vocabulary/" + name + ".npy")
print "Init training data of " + name + "..."
for i in range(1, count + 1):
filename = dir + name + " (" + str(i) + ").jpg"
img = cv2.imread(filename)
features = calcSiftFeature(img)
featVec = calcFeatVec(features, centers)
trainData = np.append(trainData, featVec, axis=0)
res = np.repeat(np.float32([dictIdx]), count)
response = np.append(response, res)
dictIdx += 1
print "Done
"
print "Now train svm classifier..."
trainData = np.float32(trainData)
response = response.reshape(-1, 1)
svm = cv2.SVM()
svm.train_auto(trainData, response, None, None, None) # select best params
svm.save("svm.clf")
print "Done
"
def classify():
svm = cv2.SVM()
svm.load("svm.clf")
total = 0; correct = 0; dictIdx = 0
for name, count in TestSetInfo.items():
crt = 0
dir = "TestSet/" + name + "/"
labels, centers = np.load("Temp/vocabulary/" + name + ".npy")
print "Classify on TestSet " + name + ":"
for i in range(1, count + 1):
filename = dir + name + " (" + str(i) + ").jpg"
img = cv2.imread(filename)
features = calcSiftFeature(img)
featVec = calcFeatVec(features, centers)
case = np.float32(featVec)
if (dictIdx == svm.predict(case)):
crt += 1
print "Accuracy: " + str(crt) + " / " + str(count) + "
"
total += count
correct += crt
dictIdx += 1
print "Total accuracy: " + str(correct) + " / " + str(total)
if __name__ == "__main__":
initFeatureSet()
learnVocabulary()
trainClassifier()
classify()
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.