SFMedu閱讀細節---給自己看

 

 

SFMedu有python版本,但是有一些問題,我們把他解決能運行,但是我們還是會用matlab版本:

https://github.com/aferral/Structure-from-motion-python

python2

sudo pip install opencv-python==3.3.0.10

sudo pip install opencv-contrib-python==3.3.0.10

sudo pip install plyfile

修改代碼:

graph.py

def triangulateGraph(graph,imagesize):
    newGraph = graph
    n = newGraph.str.shape[0]
    X = np.zeros((n,4))
    colIms = np.array([imagesize[1], imagesize[0]]).reshape((2, 1))
    imsize = colIms.repeat(len(graph.frames), axis=1)
    for i in range(n):
        validCamera = np.where(graph.ObsIdx[i] != -1)[0]
        P = np.zeros((3,4,validCamera.shape[0]))
        x= np.zeros((validCamera.shape[0],2))
        cnt=0
        #Consigue los puntos en el plano de la camara y la matriz de proyeccion
        for ind in validCamera:
            temp = int(newGraph.ObsIdx[i][ind])
            x[cnt,:] = newGraph.obsVal[temp,:]
            P[:,:,cnt] = np.dot(newGraph.focal,newGraph.mot[:,:,ind])
            cnt+=1
        X[i,:] = vgg_X_from_xP_nonlin(x,P,imsize,X=None)
    allscales = X[:,3].reshape((n, 1))
    newGraph.str = X[:,0:3] / np.hstack([allscales,allscales,allscales])
    return newGraph

mergeGraph.py

def mergeG(gA, gB):
    # Como ejemplo sean frames A 1 2 y B 2 3
    # los frarmes son las camaras o fotos

    # Primero se calculan frames que hacen overlap
    comFram = list(set(gA.frames).intersection(gB.frames))

    # Luego las que son propias de A y las propias de B (en ej A1 B3)
    propB = list(set(gB.frames).difference(gA.frames))
    indpB = [gB.frames.index(a) for a in propB]

    # Si no hay comunes retorna error
    # Si las propias de B son ninguna tira error
    if len(comFram) == 0:
        raise Exception("Comunes vacio ")
    if len(propB) == 0:
        raise Exception("No hay propias de B")

    # Crear grafo mezclca igual a grafo A
    merged = deepcopy(gA)

    # Para el primer overlap (pueden existir muchos)
    firstOv = comFram[0]

    # Transforma B.mot b.str al mismo sistema de cordenadas de A
    commonA = gA.frames.index(firstOv)
    commonB = gB.frames.index(firstOv)
    # Consigue transformada rtB

    transf = catRt(invertRt(gA.mot[:, :, commonA]), gB.mot[:, :, commonB])
    gB.str = transformPtsByRt(np.transpose(gB.str), transf, False)  # Aplicar a str B

    # Mot ahora es la concadenacion de mot y el inverso RtB
    for i in range(len(gB.frames)):
        gB.mot[:, :, i] = catRt(gB.mot[:, :, i], invertRt(transf))
    merged.frames = list(set(gA.frames).union(set(gB.frames)))
    newMot = np.zeros((3, 4, len(merged.frames)))
    newMot[:, :, np.array(range(len(gA.frames)))] = gA.mot
    newMot[:, :, np.array(range(len(gA.frames), len(merged.frames)))] = gB.mot[:, :, indpB]

    merged.mot = newMot
    # Agrega frames a grafico

    # Ahora caso common frames mas de una
    for fr in comFram:
        cA = gA.frames.index(fr)
        cB = gB.frames.index(fr)

        obsIndA = gA.ObsIdx[:, cA][gA.ObsIdx[:, cA] != -1]
        obsIndA = gA.ObsIdx[:, cA]
        valA = gA.obsVal[obsIndA.astype(np.int), :]

        obsIndB = gB.ObsIdx[:, cB][gB.ObsIdx[:, cB] != -1]
        obsIndB = gB.ObsIdx[:, cB]
        valB = gB.obsVal[obsIndB.astype(np.int), :]

        iA = findInterIndexA(valA, valB)[0]
        comunes = valA[iA]
        iB = np.array([getIndexOfRow(valB, row)[0][0] for row in comunes])

        iA,iB = deleteRepeated(iA.tolist(), iB.tolist(),valA,valB)
        iA = np.array(iA)
        iB = np.array(iB)

        for i in range(iA.shape[0]):
            # idA = obsIndA[iA[i]]
            # idB = obsIndB[iB[i]]
            for j in range(len(indpB)):
                bObbsIdx = gB.ObsIdx[iB[i], indpB[j]]
                # Agrego un elemento a obsVal y a ObsIdx
                bObbsIdx = int(bObbsIdx)
                merged.obsVal = np.vstack([merged.obsVal, gB.obsVal[bObbsIdx, :]])
                while merged.ObsIdx.shape[1] < (len(gA.frames) + j + 1):
                    merged.ObsIdx = np.hstack([merged.ObsIdx, minus1((merged.ObsIdx.shape[0], 1))])
                merged.ObsIdx[iA[i], len(gA.frames) + j] = merged.obsVal.shape[0]-1

        # Calcula set diference
        diferentesB = setDif(valB, valA)
        idB = np.array([getIndexOfRow(valB, row)[0][0] for row in diferentesB])

        for i in range(idB.shape[0]):
            bObbsIdx = gB.ObsIdx[idB[i], cB]
            bObbsIdx = int(bObbsIdx)
            merged.obsVal = np.vstack([merged.obsVal, gB.obsVal[bObbsIdx, :]])
            merged.ObsIdx = np.vstack([merged.ObsIdx, minus1((1,merged.ObsIdx.shape[1]))])
            merged.ObsIdx[merged.ObsIdx.shape[0]-1, cA] = merged.obsVal.shape[0]-1
            merged.str = np.vstack([ merged.str   ,  gB.str[:,idB[i]].reshape((1,3))  ])
            for j in range(len(indpB)):
                bObbsIdx = gB.ObsIdx[idB[i], indpB[j]]
                bObbsIdx = int(bObbsIdx)
                merged.obsVal = np.vstack([merged.obsVal, gB.obsVal[bObbsIdx, :]])
                while merged.ObsIdx.shape[1] < (len(gA.frames) + j + 1):
                    merged.ObsIdx = np.hstack([merged.ObsIdx, minus1((merged.ObsIdx.shape[0], 1))])
                merged.ObsIdx[-1, len(gA.frames) + j] = merged.obsVal.shape[0]-1


    #Revisa si quedo alguna columna sin algun valor
    #Selecciona en ObsIdx los frames comunes y dif en Gb
    #Asegurate que para ningun punto se cumpla A and B
    #Siendo A = En columnas comunes todas tienen el valor de -1
    #Siendo B = En columnas dif la suma de los valores mayores que -1 es mayor que 0
    newB = np.zeros((1,len(gB.frames)))
    newB[:,np.array(indpB)] = 1
    A= (np.sum( gB.ObsIdx[:,np.bitwise_not(newB.astype(np.bool)).astype(int)[0]], axis=1) < 0 )
    B= (np.sum( gB.ObsIdx[:,newB[0].astype(np.int)], axis=1) > 0 )
    assert(not np.any(np.bitwise_and(A,B)))

    return merged

 





進入正式流程:

http://3dvision.princeton.edu/courses/SFMedu/slides.pptx

5點算法
動態估計焦距
成對相鄰匹配之外
三焦點張量
使它對於不同的圖像輸入穩定
使它適用於視頻輸入
使它工作更快
檢查所有理論並修復所有錯誤

關於F矩陣和E矩陣:

https://blog.csdn.net/try_again_later/article/details/88655563

自由度爲7

 

直接線性變換算法

代數誤差與幾何誤差 

由(非線性)最小二乘求解器(例如Ceres)求解

4個匹配對,8個點

RANSAC估計基本矩陣

關於計算機視覺中的最優化問題:

http://cmp.felk.cvut.cz/old_pages/mini/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章