Patch-Based Optimization for Image-Based Texture Mapping(EAGLE-TextureMapping) 编译运行笔记

编译

eagle_textureMapping.pro

TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
#CONFIG -= qt

QMAKE_CXXFLAGS += -std=gnu++14

QMAKE_CXXFLAGS += -fopenmp
LIBS += -fopenmp

DESTDIR += ./bin
OBJECTS_DIR += ./lib

HEADERS += \
    getalignresults.h \
    settings.h \
    rayint/acc/acceleration.h \
    rayint/acc/bvh_tree.h \
    rayint/acc/defines.h \
    rayint/acc/kd_tree.h \
    rayint/acc/primitives.h \
    rayint/math/algo.h \
    rayint/math/defines.h \
    rayint/math/vector.h

SOURCES += main.cpp \
    getalignresults.cpp

INCLUDEPATH += ./rayint

#INCLUDEPATH += /home/eagle/CPP
#LIBS += /home/eagle/CPP/libEagle_Utils.so

INCLUDEPATH += /home/cyz/EAGLE-TextureMapping/lib
LIBS += /home/cyz/EAGLE-TextureMapping/lib/libEagle_Utils.so

INCLUDEPATH += /usr/local/include/eigen3

LIBS += -lboost_filesystem -lboost_system

#INCLUDEPATH += /usr/local/include/opencv
#LIBS += -lopencv_world #-lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc

INCLUDEPATH += /usr/local/opencv4/include/opencv4
LIBS +=  -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc # -L/usr/local/opencv4/lib

#INCLUDEPATH += /usr/include/ni /usr/local/cuda/include /usr/local/include/vtk-7.1 /usr/local/include/pcl-1.9
#LIBS += -L"/usr/local/lib" -lpcl_common -lpcl_io -lpcl_io_ply

INCLUDEPATH += /usr/include/ni /usr/include /usr/local/include/vtk-6.3 /usr/local/include/pcl-1.9
LIBS += -L"/usr/local/lib" -lpcl_common -lpcl_io -lpcl_io_ply

运行

settings.h

#ifndef SETTINGS_H
#define SETTINGS_H

#include "Eagle_Utils.h"

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

class Settings
{
public:
    int originImgW, originImgH, originDepthW, originDepthH, imgW, imgH, scaleInitW, scaleInitH;
    int patchWidth, patchStep, patchSize, frameStart, frameEnd;
    double scaleFactor, alpha_u, alpha_v, lamda, patchRandomSearchTimes;
    size_t scaleTimes;
    std::vector<size_t> kfIndexs, scaleIters;

    std::string resultsPathSurfix;
    std::string allFramesPath, cameraTxtFile, camTrajNamePattern;
    std::string keyFramesPath, kfCameraTxtFile, patchmatchBinFile, originResolution, plyFile;
    std::string rgbNamePattern, dNamePattern, kfRGBNamePattern, kfDNamePattern, rgbNameExt, kfRGBMatch;
    bool camTrajFromWorldToCam;
    float cameraDFx, cameraDFy, cameraDCx, cameraDCy, cameraFx, cameraFy, cameraCx, cameraCy;
    cv::Mat1f cameraK, cameraDK;
    char depthType;

    Settings()
    {
        // set the intrinsics of the RGB camera and the depth camera
        {
            // origin source img's resolution
            originImgW = 1920;
            originImgH = 1080;
            // camera's data
            cameraFx = 1081.37f;
            cameraFy = 1081.37f;
            cameraCx = 959.5f;
            cameraCy = 539.5f;
            // origin depth img's resolution
            originDepthW = originImgW;
            originDepthH = originImgH;
            // depth camera's data
            cameraDFx = cameraFx;
            cameraDFy = cameraFy;
            cameraDCx = cameraCx;
            cameraDCy = cameraCy;
        }

        // set the file extension of RGB image (to store the rgb file in Results folder)
        rgbNameExt = "jpg";
        // set the depth data type
        //  f - float  i - int  s - ushort  b - uchar
        depthType = 'f';

        // if you already have a ply file, than no need to set these variables to use PCL for getting a ply
        //   (more details can be found in main.cpp)
        {
            // all frames' path
            allFramesPath = "/home/wsy/TextureRecover/Datas/bloster2_1";
            // all frames' name pattern
            rgbNamePattern = "%05d." + rgbNameExt;
            dNamePattern = "%05d.png";
            // frames' start and end
            frameStart = 0;
            frameEnd = 394;
            // all frames' camera positions txt file after using PCL KF to get the ply (under the keyFramesPath folder)
            //  the format :
            //    id id id
            //    R(0,0) R(0,1) R(0,2) T(0)
            //    R(1,0) R(1,1) R(1,2) T(1)
            //    R(2,0) R(2,1) R(2,2) T(2)
            //    0 0 0 1
            cameraTxtFile = "traj.txt";
        }

        // keyframes' path (where the rgbd images are)
        //keyFramesPath = "/media/eagle/4670D70170D6F6A1/Datas/LAB/bloster/raw";
        //keyFramesPath = "/home/cyz/EAGLE-TextureMapping/datas";
        // keyframes' name pattern
        kfRGBNamePattern = "color_%02d." + rgbNameExt;
        kfRGBMatch = "color_*." + rgbNameExt;
        // [optional] keyframes' depth name pattern, using depth images to do a check when remapping
        kfDNamePattern = "depth_%02d.png";
        // valid keyframes ( all are valid if empty)
        kfIndexs = {0,1,3,4,5,11,12,13};

        // necessary files under the keyFramesPath folder
        {
            // key frames' camera positions txt file after running getKeyFrames.cpp
            //  the format is same as the cameraTxtFile
            kfCameraTxtFile = "kfTraj.txt";
            // camera files' name pattern (if kfCameraTxtFile doesn't exist, then assume every image has its own camera file)
            //  in each file, all data is in one line with format "T(0) T(1) T(2) R(0,0) R(0,1) R(0,2) R(1,0) R(1,1) R(1,2) R(2,0) R(2,1) R(2,2)"
            camTrajNamePattern = "color_%02d.cam";
            // the ply file
            //plyFile = "mesh_1.ply";
            plyFile = "world.ply";
        }

        // if the camera matrix is a projection from the world coord to camera coord, set this flag to true,
        //  otherwise, the data is from camera coord to world coord, and inv() will be called.
        //  if the cameraTxtFile and the plyFile are from PCL KF, then this should be false.
        camTrajFromWorldToCam = true;

        // surfix of the resultsPath to distinguish with different results under different params
        resultsPathSurfix = "";

        // scale
        scaleTimes = 10;
        scaleIters = {50, 45, 40, 35, 30, 25, 20, 15, 10, 5};
        scaleInitH = originImgH / 4;

        // the width and height of a patch
        patchWidth = 7;
        // the step of patchs when voting
        patchStep = 1;
        // the times of range when random searching in patchmatch
        //  searching window's width = patchRandomSearchTimes * sqrt(imgW * imgH)
        patchRandomSearchTimes = 0.01;

        // weight the similarity from Si to Ti
        alpha_u = 1.0;
        // weight the similarity from Ti to Si
        alpha_v = 2.0;
        // weight the consistency that how much M affects Ti
        lamda = 5.0;

        // -----------------
        //  custom
        // -----------------
        init_zhou_small();

        // -----------------
        //  init
        // -----------------
        // scale
        scaleInitW = static_cast<int>( std::round(originImgW * scaleInitH * 1.0 / originImgH) );
        if ( scaleTimes > 1 )
            scaleFactor = pow( originImgH * 1.0 / scaleInitH, 1.0 / (scaleTimes-1) );
        else
            scaleFactor = 1.0;

        // camera's intrinsic matrix
        //   fx  0 cx
        // [  0 fy cy ]
        //    0  0  1
        cameraK = (cv::Mat_<float>(3,3) << cameraFx, 0, cameraCx, 0, cameraFy, cameraCy, 0, 0, 1);
        cameraDK = (cv::Mat_<float>(3,3) << cameraDFx, 0, cameraDCx, 0, cameraDFy, cameraDCy, 0, 0, 1);
        // patch's size
        patchSize = patchWidth * patchWidth;

        // img's resolution during the current scale
        imgW = originImgW;
        imgH = originImgH;
    }

    void init_zhou_small(){
        originImgW = 768;
        originImgH = 576;
        cameraFx = 640.0f;
        cameraFy = 640.0f;
        cameraCx = 384.0f;
        cameraCy = 288.0f;
        // origin depth img's resolution
        originDepthW = originImgW;
        originDepthH = originImgH;
        // depth camera's data
        cameraDFx = cameraFx;
        cameraDFy = cameraFy;
        cameraDCx = cameraCx;
        cameraDCy = cameraCy;

        keyFramesPath = "/home/cyz/EAGLE-TextureMapping/rock_test";
        rgbNameExt = "jpg";
        kfRGBNamePattern = "%05d." + rgbNameExt;
        kfRGBMatch = "*." + rgbNameExt;
        kfDNamePattern = "%05d.png";
        depthType = 'f';
        camTrajFromWorldToCam = true;
        plyFile = "world.ply";
        resultsPathSurfix = "";


        kfIndexs = {1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,19,21,22,23,24};

        scaleTimes = 10;
        scaleInitH = originImgH / 4;

        lamda = 5;
        /*
        scaleIters = {2, 1};
        scaleTimes = scaleIters.size();
        scaleInitH = originImgH / 4;

        // the width and height of a patch
        patchWidth = 7;
        // the step of patchs when voting
        patchStep = 1;
        // the times of range when random searching in patchmatch
        //  searching window's width = patchRandomSearchTimes * sqrt(imgW * imgH)
        patchRandomSearchTimes = 0.01;

        // weight the similarity from Si to Ti
        alpha_u = 1.0;
        // weight the similarity from Ti to Si
        alpha_v = 2.0;
        // weight the consistency that how much M affects Ti
        lamda = 10.0;
        */
    }
};

#endif // SETTINGS_H

附一、RC数据处理

calibration.xml

    <format mask="*.txt" desc="PBO_external" writer="cvs" requiresEqualResolution="1" undistortImages="1" undistortPrincipal="1">
        <body>
$ExportCameras( 
$(index:d)  $(index:d)  $(index+1:d)
$(R00:g)    $(R01:g)    $(R02:g)    $(tx:g)
$(R10:g)    $(R11:g)    $(R12:g)    $(ty:g)
$(R20:g)    $(R21:g)    $(R22:g)    $(tz:g)
0    0    0    1
	
)
</body>
    </format>

<format mask="*.txt" desc="internal" writer="cvs" requiresEqualResolution="1" undistortImages="1" undistortPrincipal="1">
        <body>
$ExportCameras($(index:d) $(f*scale:g) $(px*scale+0.5*width) $(py*scale+0.5*height)
)
</body>
    </format>

附二、工具代码

pfm转png

# -*- coding: UTF-8 -*-
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import os
import re
import cv2


def pfm_png_file_name(pfm_file_path, png_file_path):
    png_file_path = {}
    for root, dirs, files in os.walk(pfm_file_path):
        for file in files:
            file = os.path.splitext(file)[0] + ".png"
            files = os.path.splitext(file)[0] + ".pfm"
            png_file_path = os.path.join(root, file)
            pfm_file_path = os.path.join(root, files)
            pfm_png(pfm_file_path, png_file_path)


def pfm_png(pfm_file_path, png_file_path):
    with open(pfm_file_path, 'rb') as pfm_file:
        header = pfm_file.readline().decode().rstrip()
        channel = 3 if header == 'PF' else 1

        dim_match = re.match(r'^(\d+)\s(\d+)\s$', pfm_file.readline().decode('utf-8'))
        if dim_match:
            width, height = map(int, dim_match.groups())
        else:
            raise Exception("Malformed PFM header.")

        scale = float(pfm_file.readline().decode().strip())
        if scale < 0:
            endian = '<'  # little endlian
            scale = -scale
        else:
            endian = '>'  # big endlian

        disparity = np.fromfile(pfm_file, endian + 'f')

        img = np.reshape(disparity, newshape=(height, width))
        img = np.flipud(img)
        plt.imsave(os.path.join(png_file_path), img)


def main():
    pfm_file_dir = 'C:\\Users\\23865\\Desktop\\data0\\lion\\pfm'
    png_file_dir = 'E:\\stone\\png'
    pfm_png_file_name(pfm_file_dir, png_file_dir)


if __name__ == '__main__':
    main()

注:生成结果在pfm的文件夹里。

colmap转opencv

即cameras.xml转kfTraj.txt。

from PIL import Image
import cv2
import numpy as np
import torch

def Transpose(A): # 3x3转置
    for i in range(len(A[0])-1):  # len(A[0])矩阵列数
        for j in range(i, len(A)-1):  # len(A)矩阵行数
            # 转置就是A[i][j]和A[j][i]互换
            A[j][i], A[i][j] = A[i][j], A[j][i]

def x2y(A,F): # 交换x、y轴
    B = np.array([[0,1,0],[1,0,0],[0,0,1]])
    # G = np.array([[-1,0,0],[0,1,0],[0,0,1]]) # x轴换方向
    C = A[[0,1,2],:]
    D = C[:,[0,1,2]]
    t = A[:,3]
    t = t[:3]
    E = np.dot(D,B)
    # H = np.dot(E,G)
    F[:3,:3] = E
    F[:3,3] = t
    F[3,3] = 1
    print('F:', F)
    print('-----------------------')

def y_revolve(A,H): # 绕y轴旋转180度
    B = np.array([[-1, 0, 0], [0, 1, 0], [0, 0, -1]])
    C = A[[0, 1, 2], :]
    D = C[:, [0, 1, 2]]
    t = A[:, 3]
    t = t[:3]
    E = np.dot(B, D)
    H[:3,:3] = E
    H[:3,3] = t
    H[3,3] = 1
    print('F:', H)
    print('-----------------------')

def centerSymmetry(A,L): # 中心对称
    N = np.array([[1,0,0,0],[0,-1,0,0],[0,0,-1,0],[0,0,0,1]])
    E = np.dot(A,N)
    L[:4,:4] = E
    print('L:',L)

def opencv_to_kfTraj():
    """
    坐标系转换
    """
    # file_traj = PATH_PROJECT / "traj.txt"
    file_traj = 'C:\\Users\\23865\\Desktop\\shizi\\kfTraj.txt'
    file_opencv = 'C:\\Users\\23865\\Desktop\\shizi\\cameras.xml'
    # fs = cv2.FileStorage(str(FILE_CAMERA.with_name(file_opencv)), cv2.FILE_STORAGE_READ)
    fs = cv2.FileStorage(str(file_opencv), cv2.FILE_STORAGE_READ)
    root = fs.root()
    with open(str(file_traj), mode="w", encoding="utf8") as f:
        for i, key in enumerate(sorted(root.keys())):
            print(i,key)
            node = root.getNode(key)
            mat_ext = node.getNode("camExternals").mat()
            print(mat_ext)
            print('-----------------------')

            # Transpose(mat_ext)
            print(mat_ext)
            print('-----------------------')

            # F = np.array([[0,1,0,0],[1,0,0,0],[0,0,1,0],[0,1,0,1]])
            '''
            F = np.zeros((4,4))
            x2y(mat_ext,F)
            
            L = np.zeros((4, 4))
            centerSymmetry(F,L)
            
            L = np.zeros((4, 4))
            centerSymmetry(mat_ext, L)
            

            H = np.zeros((4, 4))
            y_revolve(mat_ext, H)
            '''
            mat_int = node.getNode("camIntrinsics").mat()
            image_size = node.getNode("imageSize")
            width = image_size.getNode("Width").real()
            height = image_size.getNode("Height").real()
            print(f"{i}\t{i}\t{i + 1}", file=f)
            np.savetxt(f,mat_ext, fmt='%.8f')

def main():
    opencv_to_kfTraj()

if __name__ == '__main__':
    main()

附三、参考资料

boost

在Ubuntu上安装Boost的五种方法
ubuntu 16.04 下更换boost版本 - 虚生 - 博客园
CMake时,boost报错

QT&QT Creator

Creating Project Files | qmake Manual
QT创建工程时不存在Kits的解决方案
QT Creator + MinGW或MSVC 开发环境搭建
打开现有 Qt 项目
Ubuntu 18.04系统下的QT安装
How to solve qt5 (packages not found) cmake errors in mac
Qt5Core上的CMake错误
Qt Creator中的.pro文件的详解
QT程序中使用so动态库,如何设置LD_LIBRARY_PATH环境变量
Qt Creator快捷键大全,附快捷键配置方法
QT下输出.pro文件中的信息到输出窗口

ubuntu下设置include及lib搜索路径

ubuntu下如何设置程序include搜索路径及链接路径

CMake

cmake的使用以及相关配置(opencv、Eigen等)

opencv

linux配置openCV
Linux 完全卸载重装
Ubuntu配置OpenCV及多版本OpenCV共存
Linux环境下OpenCV的安装与配置
Ubuntu 18.04安装OpenCV4.0和环境配置
Ubuntu18.04 安装 OpenCV4.3 及环境配置
Opencv 4.3(CUDA11 ) 编译踩坑记录
Ubuntu - OpenCV 源码安装与测试
opencv 编译
opencv/opencv_contrib: Repository for OpenCV’s extra modules
ubuntu18.04+cuda9.0+boost下安装opencv3.2.0问题解决

opencv_world

Opencv为什么编译后没有opencv_world.lib

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沃洛德.辛肯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值