VLAD 학습 총화 와 python 실현

6895 단어
업무 수요 에 따라 전형 적 인 이미지 검색 알고리즘 을 연 구 했 고 하나씩 기록 하여 자신 이 복습 하고 여러분 과 교류 하 는 데 편리 하도록 했다.
이 박문 은 VLAD 에 관 한 것 이다.(vector of locally aggregated descriptors) 즉, 부분 설명자 의 벡터 를 취 합 하 는 것 은 SIFT, SURF, ORB 등 이미지 의 부분 설명 자 를 이용 하여 취 합 된 작업 을 한 다음 에 긴 벡터 로 그림 을 표현 하 는 과정 입 니 다. 이미지 표징 을 벡터 로 하 는 것 은 이미지 검색 의 선 결 조건 입 니 다. 이미지 검색 사상 은 이미지 조회 와 검 사 를 하 는 것 이기 때 문 입 니 다.소 라 이브 러 리 의 이미 지 는 유사 성 측정 을 한 다음 유사 성 이 가장 큰 값 을 출력 합 니 다. 수학 본질은 벡터 간 의 유사 성 측정 입 니 다. 물론 두 그림 으로 유사 성 측정 을 직접 할 수 있 습 니 다. 예 를 들 어 픽 셀 값 이 떨 어 지 거나 색 직사 도 분포 의 유사 성 을 계산 할 수 있 습 니 다. 소량의 데 이 터 는 문제 가 없 지만 대량의 데 이 터 를 먼저 저장 하 는 것 은 이미지 입 니 다.큰 문제 입 니 다. 그 다음 에 이렇게 하 는 검색 속도 가 너무 느 리 고 디스크 와 메모리 공간 이 많이 필요 합 니 다.
우 리 는 이미지 에 대해 간단 한 작업 을 해 야 한다. 즉, 하나의 설명 방식 을 선택 하면 이미지 의 내용 을 잘 대표 할 수 있 을 뿐만 아니 라 하드웨어 자원 에 대한 소모 도 비교적 낮 을 뿐만 아니 라 빠 른 검색 속도 도 가 져 야 한다. 분명히 국부 설명자 의 집합 벡터 를 바탕 으로 이런 문 제 를 해결 할 수 있다.(PS: SIFT 가 뭔 지 모 르 면 다른 블 로 그 를 볼 수 있 습 니 다. 이것 은 여러 가지 해석 이 있 고 성숙 한 이미지 특징 추출 방법 입 니 다)
블 로 거들 은 논문 을 먼저 연구 한 다음 에 논문 내용 에 따라 알고리즘 을 실현 하 는 것 을 좋아 하기 때문에 논문 부터 말한다.
을 참고 하 십시오.
이 논문 에서 작 가 는 비교적 성숙 한 집합 부분 벡터 의 두 가지 방법 을 가로로 비교 했다. BOF (Bag of features), FK (Fisher kernel)저 는 여기 서 더 이상 상세 하 게 전개 하지 않 겠 습 니 다. 후속 적 인 박문 은 그것들 에 대해 단독으로 기록 할 것 입 니 다. VLAD 의 장점 은 속도 가 빠 르 고 정밀도 가 높 아서 하드웨어 자원 의 대량 소 모 를 야기 하지 않 는 다 는 것 입 니 다. 그러나 이 알고리즘 들 은 모두 공 통 된 단점 을 가지 고 있 습 니 다. 대량의 데이터 에 직접 응용 할 수 없습니다. 데이터 양 이 너무 많 기 때문에 진일보 한 인 코딩 처리 로 압축 해 야 합 니 다. 이것 은 참조 할 수 있 습 니 다.나의 박문 을 시험 하 다.
곱 하기 양 적 학습 과 실전 총 결 클릭 하여 링크 열기
이 알고리즘 은 대량의 데이터 의 인 코딩 처리 에 대해 제 기 된 것 이다.
VLAD 로 돌아 가면 알고리즘 은 다음 과 같은 몇 단계 로 나 눌 수 있 습 니 다.
1. 그림 을 추출 하 는 SIFT 설명
2. 추출 한 SIFT 설명자 (모든 훈련 이미지 의 SIFT) 를 이용 하여 코드 북 한 권 을 훈련 시 키 고 훈련 방법 은 K - means 입 니 다.
3. 한 이미지 의 모든 SIFT 설명 자 를 최근 이웃 원칙 에 따라 코드 북 에 배정 합 니 다 (즉, K 개의 클 러 스 터 센터 에 배분 합 니 다)
4. 모든 집합 중심 에 잔 차 와 (즉, 현재 집합 중심 에 속 하 는 모든 SIFT 에서 집합 중심 을 뺀 다음 에 화 해 를 구 하 는 것)
5. 이 잔 차 와 L2 를 획일 화 한 다음 에 K * 128 의 장 벡터 로 연결 합 니 다. 128 은 단일 SIFT 의 길이 입 니 다.
대량의 데 이 터 를 고려 하지 않 으 면 이 훈련 과 라 이브 러 리 구축 과정 은 이미 충분 하 다. 다섯 번 째 단계 의 결과 (이미지 라 이브 러 리) 를 직접 저장 한 다음 에 조회 이미지 에 대해 상술 한 조작 을 한 다음 에 이미지 라 이브 러 리 의 모든 벡터 의 유럽식 거 리 를 계산 하고 출력 전 5 개의 최소 거 리 를 두 는 것 은 완전한 검색 과정 이다.
 
코드:
 

#!/usr/bin/env python

print "feature"
import pickle 
from sklearn import cluster
from sklearn.cluster import  MiniBatchKMeans
batch_size=1000
import sys
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
import cv2
import matplotlib.pyplot as plt
import numpy as np
import skimage.io as io
#model_root='/media/mysj/c2338634-673f-4908-8d27-3f73bda92d05/home/mysj'
#sys.path.insert(0,model_root)

def getImage(str):
    
    mat=io.ImageCollection(str)
    print len(mat)
   

    return mat
def getOrb(mat):
    label={}
    orbdic=[]
    siftt=cv2.xfeatures2d.SIFT_create()
    for i in range(len(mat)):
        kp=siftt.detect(mat[i],None)
        des=siftt.compute(mat[i],kp)
        #des_pca=(PCA(n_components=128).fit_transform(des[1].transpose())).transpose()
        #des[1]=Vlad(des[1])
        #print des[1].shape
        #final=Vlad(des[1])
        final=des[1]
        print i
        print final.shape
        #print final
        orbdic.append(final)
        
        #label[i]=des[1].shape[0]
    return orbdic,label
#################################################################################
## use minibatchkmeans to train your sift descriptors,then you will get a codebook with k words 
def codebook(orbdic):
    mbk = MiniBatchKMeans(init='k-means++', n_clusters=64,max_iter=1000, batch_size=batch_size,
                      n_init=10, max_no_improvement=10, verbose=0).fit(orbdic)
    label=mbk.labels_
    centroid=mbk.cluster_centers_
    return label,centroid
#########################################################################################

########################################################################################### 
## assign all the sift descriptors of each picture to the nearest codeword,and we can use a K*128 vlad vector to descrip each 
## picture
## refer to my blog
## notice:if picture x doesn't have any sift descriptor which belongs to code word i ,we use a 128d zero vector to represent it.
def vlad(locdpt,centroid):
    dis={}
    final=[]
    for i in range(locdpt.shape[0]):
        des=[]
        for j in range(centroid.shape[0]):
            des.append(np.linalg.norm(locdpt[i]-centroid[j]))
        if dis.has_key(np.argmin(des)):
            dis[np.argmin(des)].append(locdpt[i])
        else:
            dis[np.argmin(des)]=[locdpt[i]]
    #print len(dis),dis.keys()
    for i in range(64):
        total=0
        if dis.has_key(i):
            for j in range(len(dis[i])):
            
                total=total+dis[i][j]-centroid[i]
            if np.linalg.norm(total)!=0:
                total=total/np.linalg.norm(total)
                
        else:
            total=np.zeros((128,))
        final.append(total)
    print len(final)    
    final=concate2(final,len(final))
    return final
###############################################################################################
def gfinal(mat):
    gf=[]
    orbdic,label=getOrb(mat)
    database=concate(orbdic,len(orbdic))
    label,centroid=codebook(database)
    print centroid.shape
    for i in range(len(orbdic)):
        gf.append(vlad(orbdic[i],centroid))
    return gf

def concate2(orbdic,l):
    #print "concate-all-features-vector"
    database=orbdic[0]
    for i in range(1,l):
        #print orbdic[i].shape
        database=np.hstack((database,orbdic[i]))
    return database
        
def concate(orbdic,l):
    #print "concate-all-features-vector"
    database=orbdic[0]
    for i in range(1,l):
        database=np.vstack((database,orbdic[i]))
    return database

def train(database):
    label,centroid=codebook(database)
    print centroid.shape
    with open("codebook.pickle",'wb')as pk:
        pickle.dump(centroid,pk)

def test(orbdic):
    final=[]
    with open("codebook.pickle",'rb')as pk:
        codebook=pickle.load(pk)
    print codebook.shape
    for i in range(len(orbdic)):
        final.append(vlad(orbdic[i],codebook)) 
    final=concate(final,len(final))    
    return final    

if __name__=="__main__":
    ##the picture path
    filename="klboat"
    str=filename+"/*.jpg"
    ##get each picture's sift-descriptor
    mat=getImage(str)
    io.imshow(mat[0])
    orbdic,label=getOrb(mat)
    database=concate(orbdic,len(orbdic))
    ##train for codebook
    train(database)
    ##do NN-assign
    final=test(orbdic)
    #save vlad descriptor,size 86*(k*128)
    print final.shape
    with open("db.pickle",'wb')as pk:
        pickle.dump(final,pk)
        
    
    


여러분 이 bug 를 고 르 는 것 을 환영 합 니 다.

좋은 웹페이지 즐겨찾기