std::band

标准库函数bind()和function()定义于头文件中(该头文件还包括许多其他函数对象),用于处理函数及函数参数。bind()接受一个函数(或者函数对象,或者任何你可以通过”(…)”符号调用的事物),生成一个其有某一个或多个函数参数被“绑定”或重新组织的函数对象。(译注:顾名思义,bind()函数的意义就像它的函数名一样,是用来绑定函数调用的某些参数的。)例如:

        int f(int, char, double);
        // 绑定f()函数调用的第二个和第三个参数,
        // 返回一个新的函数对象为ff,它只带有一个int类型的参数
        auto ff = bind(f, _1, ‘c’, 1.2);
        int x = ff(7);                //  f(7, ‘c’, 1.2);

参数的绑定通常称为”Currying”(译注:Currying—“烹制咖喱烧菜”,此处意指对函数或函数对象进行加工修饰操作), “_1″是一个占位符对象,用于表示当函数f通过函数ff进行调用时,函数ff的第一个参数在函数f的参数列表中的位置。第一个参数称为”_1″, 第二个参数为”_2″,依此类推。例如:

        int f(int, char, double);
        auto frev = bind(f, _3, _2, _1);        // 翻转参数顺序
        int x = frev(1.2, ‘c’, 7);            // f(7, ‘c’, 1.2);

此处,auto关键字节约了我们去推断bind返回的结果类型的工作。

我们无法使用bind()绑定一个重载函数的参数,我们必须显式地指出需要绑定的重载函数的版本:

        int g(int);
        double g(double);

        auto g1 = bind(g, _1);    // 错误:调用哪一个g() ?
        // 正确,但是相当丑陋
        auto g2 = bind( (double(*)(double))g, _1);

bind()有两种版本:一个如上所述,另一个则是“历史遗留”的版本:你可以显式地描述返回类型。例如:

        auto f2 = bind<int> (f, 7, ‘c’, _1);      // 显式返回类型
        int x = f2(1.2);                    // f(7, ‘c’, 1.2);

第二种形式的存在是必要的,并且因为第一个版本((?) “and for a user simplest “,此处请参考原文))无法在C++98中实现。所以第二个版本已经被广泛使用。

function是一个拥有任何可以以”(…)”符号进行调用的值的类型。特别地,bind的返回结果可以赋值给function类型。function十分易于使用。(译注:更直观地,可以把function看成是一种表示函数的数据类型,就像函数对象一样。只不过普通的数据类型表示的是数据,function表示的是函数这个抽象概念。)例如:

        // 构造一个函数对象,
        // 它能表示的是一个返回值为float,
        // 两个参数为int,int的函数
        function<float (int x, int y)> f;   

        // 构造一个可以使用"()"进行调用的函数对象类型
        struct int_div {
                float operator() (int x, int y) const
                     { return ((float)x)/y; };
        };

        f = int_div();                    // 赋值
        cout<< f(5,3) <<endl;  // 通过函数对象进行调用
        std::accumulate(b, e, 1, f);        // 完美传递

成员函数可被看做是带有额外参数的自由函数:

        struct X {
                int foo(int);
        };

        // 所谓的额外参数,
        // 就是成员函数默认的第一个参数,
        // 也就是指向调用成员函数的对象的this指针
        function<int (X*, int)> f;
        f = &X::foo;            // 指向成员函数

        X x;
        int v = f(&x, 5);  // 在对象x上用参数5调用X::foo()
        function<int (int)> ff = std::bind(f, &x, _1);    // f的第一个参数是&x
        v = ff(5);                // 调用x.foo(5)

function对于回调函数、将操作作为参数传递等十分有用。它可以看做是C++98标准库中函数对象mem_fun_t, pointer_to_unary_function等的替代品。同样的,bind()也可以被看做是bind1st()和bind2nd()的替代品,当然比他们更强大更灵活。

/* 
 * File:   main.cpp
 * Author: Vicky.H
 * Email:  eclipser@163.com
 */
#include <iostream>
#include <functional>
#include <typeinfo>
#include <string.h>

int add1(int i, int j, int k) {
    return i + j + k;
}


class Utils {
public:
    Utils(const char* name) {
        strcpy(_name, name);
    }
    
    void sayHello(const char* name) const {
        std::cout << _name << " say: hello " << name << std::endl;
    }
    
    static int getId() {
        return 10001;
    } 
    
    int operator()(int i, int j, int k) const {
        return i + j + k;
    }
    
private:
    char _name[32];
};


/*
 * 
 */
int main(void) {
    
    // 绑定全局函数
    auto add2 = std::bind(add1, std::placeholders::_1, std::placeholders::_2, 10);
    // 函数add2 = 绑定add1函数,参数1不变,参数2不变,参数3固定为10.
    std::cout << typeid(add2).name() << std::endl;
    std::cout << "add2(1,2) = " << add2(1, 2) << std::endl;
    
    std::cout << "\n---------------------------" << std::endl;
    
    // 绑定成员函数
    Utils utils("Vicky");
    auto sayHello = std::bind(&Utils::sayHello, utils/*调用者*/, std::placeholders::_1/*参数1*/);
    sayHello("Jack");
    
    auto sayHelloToLucy = std::bind(&Utils::sayHello, utils/*调用者*/, "Lucy"/*固定参数1*/);
    sayHelloToLucy();
    
    // 绑定静态成员函数
    auto getId = std::bind(&Utils::getId);
    std::cout << getId() << std::endl;
    
    std::cout << "\n---------------------------" << std::endl;
    
    // 绑定operator函数
    auto add100 = std::bind(&Utils::operator (), utils, std::placeholders::_1, std::placeholders::_2, 100);
    std::cout << "add100(1, 2) = " << add100(1, 2) << std::endl;
    
    // 注意:无法使用std::bind()绑定一个重载函数
    
    return 0;
}



#include <iostream> #include <fstream> #include <opencv2/opencv.hpp> #include "gdal/gdal_priv.h" #pragma comment(lib, "gdal_i.lib") #include <filesystem> #include<tuple> #include <gdal.h> #include <gdal_priv.h> #include <cpl_conv.h> #include <boost/filesystem.hpp> #include "gdal_priv.h" #include "cpl_conv.h" #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl/io/ply_io.h> #include <pcl/io/pcd_io.h> using namespace std; using namespace cv; // Function to read data from a txt file and store it in a matrix bool readDataFromFile(const string& filename, Mat& dataMat) { ifstream file(filename); if (!file.is_open()) { cout << "Error: Could not open the file " << filename << endl; return false; } dataMat.create(3, 4, CV_32FC1); for (int i = 0; i < dataMat.rows; ++i) { for (int j = 0; j < dataMat.cols; ++j) { float value; if (!(file >> value)) { cout << "Error: Could not read data properly from the file " << filename << endl; return false; } dataMat.at<float>(i, j) = value; } } file.close(); return true; } // Function to convert disparity map to depth map Mat disparityToDepth(cv::Mat disImg, float baselineLength, float focalLength) { int width = disImg.cols; int height = disImg.rows; std::cout << "distance:" << width << height << std::endl; Mat depthImage = Mat::zeros(height, width, CV_32FC1); std::cout << "断点" << " 6 " << std::endl; for (int row = 0; row < height; ++row) { // std::cout << "断点" << " 7 " << std::endl; for (int col = 0; col < width; ++col) { float distance = 0; distance = disImg.at<float>(row, col); // std::cout << "distance:" << distance << std::endl; if (distance != 0.0) { depthImage.at<float>(row, col) = (baselineLength * focalLength ) / distance; } else { continue; } } } return depthImage; // 返回深度图 } std::vector<Mat> readEplimg(const std::string& folderPath) { GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径和文件名 std::vector<Mat> Eplimg; if (!boost::filesystem::exists(folderPath) || !boost::filesystem::is_directory(folderPath)) { std::cerr << "Error: " << folderPath << " is not a valid directory." << std::endl; return Eplimg; } // 遍历文件夹中的每个文件 boost::filesystem::directory_iterator end_itr; for (boost::filesystem::directory_iterator itr(folderPath); itr != end_itr; ++itr) { if (boost::filesystem::is_regular_file(itr->status()) && (itr->path().extension() == ".tiff" || itr->path().extension() == ".tif")) { std::string filePath = itr->path().string(); // 打开tiff文件 GDALDataset* poDataset = (GDALDataset*)GDALOpenShared(filePath.c_str(), GA_ReadOnly); if (poDataset == nullptr) { std::cerr << "Error opening image " << filePath << std::endl; continue; } // 获取图像宽度和高度 int width = poDataset->GetRasterXSize(); int height = poDataset->GetRasterYSize(); // 获取波段数量 int numBands = poDataset->GetRasterCount(); // 读取图像数据 cv::Mat image(height, width, CV_16U); //poDataset->RasterIO(GF_Read, 0, 0, width, height, image.data, width, height, GDT_UInt16, 0, 0); GDALRasterBand* poBand = poDataset->GetRasterBand(1); poBand->RasterIO(GF_Read, 0, 0, width, height, image.data, width, height, GDT_UInt16, 0, 0); // 关闭文件 GDALClose(poDataset); // 将图像添加到向量中 Eplimg.push_back(image); } } return Eplimg; } cv::Mat readDisparityImage(const std::string& filePath) { GDALAllRegister(); // 打开 TIFF 文件 GDALDataset *disparityDataset = (GDALDataset *)GDALOpen(filePath.c_str(), GA_ReadOnly); if (disparityDataset == NULL) { std::cerr << "无法打开图像文件!" << std::endl; return cv::Mat(); } // 获取图像宽度和高度 int width = disparityDataset->GetRasterXSize(); int height = disparityDataset->GetRasterYSize(); std::cout << "图像尺寸:" << width << " x " << height << std::endl; // 获取第一个波段 // GDALRasterBand *poBand = disparityDataset->GetRasterBand(1); // 获取波段数量 int numBands = disparityDataset->GetRasterCount(); // 读取图像数据 cv::Mat image(height, width, CV_32FC1); GDALRasterBand* poBand = disparityDataset->GetRasterBand(1); GDALDataType g_type = poBand->GetRasterDataType(); // std::cout << "断点" << width << " 1 " << height << std::endl; // float *data = new float [width * height]; // std::cout << "断点" << width << " 2 " << height << std::endl; // poBand->RasterIO(GF_Read, 0, 0, width, height, data, width, height, GDT_Float64, 0, 0); std::cout << "断点" << width << " 3 " << height << std::endl; // 将数据转换为 OpenCV 的 cv::Mat 格式 // cv::Mat img(height, width, CV_64F, data); disparityDataset->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, width, height, image.data, width, height, g_type, 0, 0); poBand->RasterIO(GF_Read, 0, 0, width, height, image.data, width, height, g_type, 0,0); std::cout << "断点" << width << " 4 " << height << std::endl; // 释放内存 // delete[] data; GDALClose(disparityDataset); return image; } std::vector<cv::Mat> readColorImages(const std::string& folderPath) { GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径和文件名 std::vector<cv::Mat> colorImg; if (!boost::filesystem::exists(folderPath) || !boost::filesystem::is_directory(folderPath)) { std::cerr << "Error: " << folderPath << " is not a valid directory." << std::endl; return colorImg; } boost::filesystem::directory_iterator end_itr; for (boost::filesystem::directory_iterator itr(folderPath); itr != end_itr; ++itr) { if (boost::filesystem::is_regular_file(itr->status()) && (itr->path().extension() == ".tiff" || itr->path().extension() == ".tif")) { std::string filePath = itr->path().string(); GDALDataset* poDataset = (GDALDataset*)GDALOpenShared(filePath.c_str(), GA_ReadOnly); if (poDataset == nullptr) { std::cerr << "Error opening image " << filePath << std::endl; continue; } int width = poDataset->GetRasterXSize(); int height = poDataset->GetRasterYSize(); int numBands = poDataset->GetRasterCount(); // 创建一个3通道的Mat矩阵 cv::Mat image(height, width, CV_8UC3); // 逐波段读取数据并存储到Mat矩阵中 for (int b = 1; b <= std::min(numBands, 3); ++b) { // 限制最多读取前3个波段 GDALRasterBand* poBand = poDataset->GetRasterBand(b); poBand->RasterIO(GF_Read, 0, 0, width, height, image.data + (b - 1), width, height, GDT_Byte, 3, width * 3); } // 关闭文件 GDALClose(poDataset); // 将图像添加到向量中 cv::cvtColor(image, image, cv::COLOR_RGB2BGR); // 转换为BGR格式 colorImg.push_back(image); } } return colorImg; } void saveDepthImageWithGDAL(const cv::Mat& depthImage, const std::string& outputPath) { // 初始化 GDAL 库 GDALAllRegister(); // 获取深度图像的尺寸信息 int width = depthImage.cols; int height = depthImage.rows; // 创建输出文件 GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("GTiff"); if (driver == nullptr) { std::cerr << "Error: Could not get GDAL driver." << std::endl; return; } // 创建输出数据集 GDALDataset* dataset = driver->Create(outputPath.c_str(), width, height, 1, GDT_Float32, NULL); if (dataset == nullptr) { std::cerr << "Error: Could not create GDAL dataset." << std::endl; return; } // 将深度图像数据写入到数据集中 float* data = (float*)CPLMalloc(sizeof(float) * width * height); for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { data[i * width + j] = depthImage.at<float>(i, j); } } GDALRasterBand* band = dataset->GetRasterBand(1); band->RasterIO(GF_Write, 0, 0, width, height, data, width, height, GDT_Float32, 0, 0); // 释放内存和关闭数据集 CPLFree(data); GDALClose(dataset); } void depthToCloudPoint(std::vector<Mat>colorImage,Mat depthImage ,float focalLength_x,float focalLength_y) { pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>); std::cout << "size:" << depthImage.rows << "x" << depthImage.cols << std::endl; for (int y = 0; y < depthImage.rows; ++y) { for (int x = 0; x < depthImage.cols; ++x) { if (y >= 0 && y < depthImage.rows && x >= 0 && x < depthImage.cols) { // 获取深度值 float depth = depthImage.at <float>(y, x); // 如果深度值为0(无效值),跳过 if (depth == 0.0f) continue; // 计算点云位置 pcl::PointXYZRGB point; point.z = depth; point.x = (x - focalLength_x) * depth / focalLength_x; point.y = (y - focalLength_y) * depth / focalLength_y; std::cout << "size:" << "9" << std::endl; //std::cout << "color:" << colorImage << std::endl; // 获取相应位置的彩色像素值作为颜色 cv::Vec3b color = colorImage[0].at<cv::Vec3b>(y, x); std::cout << "color:" << color << std::endl; point.r = color[2]; point.g = color[1]; point.b = color[0]; std::cout << "color:" << color << std::endl; // 将点添加到点云中 cloud->push_back(point); } } } pcl::io::savePLYFile("pointcloud.ply", *cloud); pcl::io::savePCDFileBinary("point_cloud.pcd", *cloud); pcl::io::savePLYFileBinary("point_cloud.ply", *cloud); std::cout << "Point cloud saved to point_cloud.ply" << std::endl; } int main() { std::vector<Mat> Eplimg = readEplimg("/home/tl/3rdparty/homeworks/build/EpiImg"); std::vector<Mat> colorImage = readColorImages("/home/tl/3rdparty/homeworks/build/EpiImg"); cv::Mat disImg = readDisparityImage("/home/tl/3rdparty/homeworks/build/017ER030_017ER031_DISP_ET0.tif"); // 检查是否成功读取 if (disImg.empty()) { std::cerr << "图像读取失败!" << std::endl; } Mat dataMatleft, dataMatright; if (!readDataFromFile("017ER030_REC.txt", dataMatleft) || !readDataFromFile("017ER031_REC.txt", dataMatright)) { return -1; } Mat K1, R1, t1, K2, R2, t2; decomposeProjectionMatrix(dataMatleft, K1, R1, t1); decomposeProjectionMatrix(dataMatright, K2, R2, t2); Mat B = t1 - t2; float baseline_length = norm(B); float focalLength_x = K1.at<float>(0, 0); // 从相机内参矩阵K1中获取水平方向的焦距 cout << "基线长度: " << baseline_length << endl; cout << "焦距: " << focalLength_x << endl; std::cout << "断点" << " 5 " << std::endl; // 或者 float focalLength_y = K1.at<float>(1, 1); // 从相机内参矩阵K1中获取垂直方向的焦距 Mat depthImage = disparityToDepth(disImg, baseline_length, focalLength_x); // 调用 disparityToDepth 函数获取深度图 // 设置输出路径 std::string outputPath = "output_depth_image.tif"; // 将深度图像保存为图片文件 saveDepthImageWithGDAL(depthImage, outputPath); // 调用函数进行深度图像到点云的转换 depthToCloudPoint(colorImage, depthImage, focalLength_x, focalLength_y); cout << "基线长度: " << baseline_length << endl; cout << "相机内参矩阵 K:" << endl << K1 << endl; cout << "旋转矩阵 R:" << endl << R1 << endl; cout << "平移向量 t:" << endl << t1 << endl; cout << "Data matrix 1:" << endl << dataMatleft << endl; cout << "Data matrix 2:" << endl << dataMatright << endl; return 0; }把这个改为只用opencv库就能实现的代码
07-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值