【opencv】示例-cout_mat.cpp cout输出各种格式矩阵、向量

de82278bd350974a97b06d0ee8064b7f.png

/*
 * cvout_sample 只是演示了 cv::Mat 的序列化输出能力。
 * 也就是说,现在可以这样使用:cv::Mat M(...); cout << M;。
 */


#include "opencv2/core.hpp" // 包含OpenCV核心功能的头文件
#include <iostream> // 包含标准输入输出流的头文件


// 使用标准和OpenCV命名空间中的名字,避免每次调用时都要加前缀
using namespace std;
using namespace cv;


// 帮助信息的函数
static void help(char** argv)
{
    cout
    << "\n------------------------------------------------------------------\n"
    << " This program shows the serial out capabilities of cv::Mat\n"
    << "That is, cv::Mat M(...); cout << M;  Now works.\n"
    << "Output can be formatted to OpenCV, matlab, python, numpy, csv and \n"
    << "C styles Usage:\n"
    << argv[0]
    << "\n------------------------------------------------------------------\n\n"
    << endl;
}


// 程序的主入口点
int main(int argc, char** argv)
{
    cv::CommandLineParser parser(argc, argv, "{help h||}"); // 创建命令行解析器
    if (parser.has("help")) // 如果用户请求帮助
    {
        help(argv); // 显示帮助信息
        return 0; // 退出程序
    }
    Mat I = Mat::eye(4, 4, CV_64F); // 创建一个4x4的双精度单位矩阵
    I.at<double>(1,1) = CV_PI; // 将第1行第1列的元素设为π
    cout << "I = \n" << I << ";" << endl << endl; // 打印矩阵


    Mat r = Mat(10, 3, CV_8UC3); // 创建一个10x3的8位无符号3通道(彩色)矩阵
    randu(r, Scalar::all(0), Scalar::all(255)); // 使用随机值填充矩阵


    // 以下部分演示不同输出格式
    cout << "r (default) = \n" << r << ";" << endl << endl;
    cout << "r (matlab) = \n" << format(r, Formatter::FMT_MATLAB) << ";" << endl << endl;
    cout << "r (python) = \n" << format(r, Formatter::FMT_PYTHON) << ";" << endl << endl;
    cout << "r (numpy) = \n" << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;
    cout << "r (csv) = \n" << format(r, Formatter::FMT_CSV) << ";" << endl << endl;
    cout << "r (c) = \n" << format(r, Formatter::FMT_C) << ";" << endl << endl;


    Point2f p(5, 1); // 创建一个2D浮点型点
    cout << "p = " << p << ";" << endl; // 打印点


    Point3f p3f(2, 6, 7); // 创建一个3D浮点型点
    cout << "p3f = " << p3f << ";" << endl; // 打印点


    vector<float> v; // 创建一个浮点型向量
    v.push_back(1); // 向向量中添加元素
    v.push_back(2);
    v.push_back(3);


    cout << "shortvec = " << Mat(v) << endl; // 打印向量


    vector<Point2f> points(20); // 创建一个包含20个2D浮点型点的向量
    for (size_t i = 0; i < points.size(); ++i) // 用循环填充这个向量
        points[i] = Point2f((float)(i * 5), (float)(i % 7));


    cout << "points = " << points << ";" << endl; // 打印点的向量
    return 0; // 程序结束
}

这段代码展示了OpenCV库中的cv::Mat类的序列化输出功能。它包含了一系列可以输出为不同格式的示例,如OpenCV风格、Matlab风格、Python的NumPy风格、CSV风格和C风格。同时,也展示了如何在控制台中显示点和点向量。总的来说,这段代码主要用于教学和演示如何在C++中使用OpenCV的cv::Mat对象以不同的编程语言风格格式化输出。

终端输出:

I =
[1, 0, 0, 0;
 0, 3.141592653589793, 0, 0;
 0, 0, 1, 0;
 0, 0, 0, 1];


r (default) =
[ 91,   2,  79, 179,  52, 205, 236,   8, 181;
 239,  26, 248, 207, 218,  45, 183, 158, 101;
 102,  18, 118,  68, 210, 139, 198, 207, 211;
 181, 162, 197, 191, 196,  40,   7, 243, 230;
  45,   6,  48, 173, 242, 125, 175,  90,  63;
  90,  22, 112, 221, 167, 224, 113, 208, 123;
 214,  35, 229,   6, 143, 138,  98,  81, 118;
 187, 167, 140, 218, 178,  23,  43, 133, 154;
 150,  76, 101,   8,  38, 238,  84,  47,   7;
 117, 246, 163, 237,  69, 129,  60, 101,  41];


r (matlab) =
(:, :, 1) =
 91, 179, 236;
239, 207, 183;
102,  68, 198;
181, 191,   7;
 45, 173, 175;
 90, 221, 113;
214,   6,  98;
187, 218,  43;
150,   8,  84;
117, 237,  60
(:, :, 2) =
  2,  52,   8;
 26, 218, 158;
 18, 210, 207;
162, 196, 243;
  6, 242,  90;
 22, 167, 208;
 35, 143,  81;
167, 178, 133;
 76,  38,  47;
246,  69, 101
(:, :, 3) =
 79, 205, 181;
248,  45, 101;
118, 139, 211;
197,  40, 230;
 48, 125,  63;
112, 224, 123;
229, 138, 118;
140,  23, 154;
101, 238,   7;
163, 129,  41;


r (python) =
[[[ 91,   2,  79], [179,  52, 205], [236,   8, 181]],
 [[239,  26, 248], [207, 218,  45], [183, 158, 101]],
 [[102,  18, 118], [ 68, 210, 139], [198, 207, 211]],
 [[181, 162, 197], [191, 196,  40], [  7, 243, 230]],
 [[ 45,   6,  48], [173, 242, 125], [175,  90,  63]],
 [[ 90,  22, 112], [221, 167, 224], [113, 208, 123]],
 [[214,  35, 229], [  6, 143, 138], [ 98,  81, 118]],
 [[187, 167, 140], [218, 178,  23], [ 43, 133, 154]],
 [[150,  76, 101], [  8,  38, 238], [ 84,  47,   7]],
 [[117, 246, 163], [237,  69, 129], [ 60, 101,  41]]];


r (numpy) =
array([[[ 91,   2,  79], [179,  52, 205], [236,   8, 181]],
       [[239,  26, 248], [207, 218,  45], [183, 158, 101]],
       [[102,  18, 118], [ 68, 210, 139], [198, 207, 211]],
       [[181, 162, 197], [191, 196,  40], [  7, 243, 230]],
       [[ 45,   6,  48], [173, 242, 125], [175,  90,  63]],
       [[ 90,  22, 112], [221, 167, 224], [113, 208, 123]],
       [[214,  35, 229], [  6, 143, 138], [ 98,  81, 118]],
       [[187, 167, 140], [218, 178,  23], [ 43, 133, 154]],
       [[150,  76, 101], [  8,  38, 238], [ 84,  47,   7]],
       [[117, 246, 163], [237,  69, 129], [ 60, 101,  41]]], dtype='uint8');


r (csv) =
 91,   2,  79, 179,  52, 205, 236,   8, 181
239,  26, 248, 207, 218,  45, 183, 158, 101
102,  18, 118,  68, 210, 139, 198, 207, 211
181, 162, 197, 191, 196,  40,   7, 243, 230
 45,   6,  48, 173, 242, 125, 175,  90,  63
 90,  22, 112, 221, 167, 224, 113, 208, 123
214,  35, 229,   6, 143, 138,  98,  81, 118
187, 167, 140, 218, 178,  23,  43, 133, 154
150,  76, 101,   8,  38, 238,  84,  47,   7
117, 246, 163, 237,  69, 129,  60, 101,  41
;


r (c) =
{ 91,   2,  79, 179,  52, 205, 236,   8, 181,
 239,  26, 248, 207, 218,  45, 183, 158, 101,
 102,  18, 118,  68, 210, 139, 198, 207, 211,
 181, 162, 197, 191, 196,  40,   7, 243, 230,
  45,   6,  48, 173, 242, 125, 175,  90,  63,
  90,  22, 112, 221, 167, 224, 113, 208, 123,
 214,  35, 229,   6, 143, 138,  98,  81, 118,
 187, 167, 140, 218, 178,  23,  43, 133, 154,
 150,  76, 101,   8,  38, 238,  84,  47,   7,
 117, 246, 163, 237,  69, 129,  60, 101,  41};


p = [5, 1];
p3f = [2, 6, 7];
shortvec = [1;
 2;
 3]
points = [0, 0;
 5, 1;
 10, 2;
 15, 3;
 20, 4;
 25, 5;
 30, 6;
 35, 0;
 40, 1;
 45, 2;
 50, 3;
 55, 4;
 60, 5;
 65, 6;
 70, 0;
 75, 1;
 80, 2;
 85, 3;
 90, 4;
 95, 5];

dcd4dd2b091614e567df1739d04bba1d.png

#include <opencv2/opencv.hpp> #include <iostream> #include <vector> #include <cmath> using namespace cv; using namespace std; // 归一化向量函数 Mat normalizeVec(const Mat& vec) { double x = vec.at<double>(0); double y = vec.at<double>(1); double z = vec.at<double>(2); double norm = sqrt(x * x + y * y + z * z); return (Mat_<double>(3, 1) << x / norm, y / norm, z / norm); } // 计算叉积 Mat crossProduct(const Mat& a, const Mat& b) { double ax = a.at<double>(0), ay = a.at<double>(1), az = a.at<double>(2); double bx = b.at<double>(0), by = b.at<double>(1), bz = b.at<double>(2); return (Mat_<double>(3, 1) << ay * bz - az * by, az * bx - ax * bz, ax * by - ay * bx); } // 确保变换后包含整个原始图像 Mat ensureFullImage(const Mat& H, const Mat& img, Size& new_size) { vector<Point2d> corners(4); corners[0] = Point2d(0, 0); corners[1] = Point2d(img.cols - 1, 0); corners[2] = Point2d(0, img.rows - 1); corners[3] = Point2d(img.cols - 1, img.rows - 1); vector<Point2d> transformed(4); perspectiveTransform(corners, transformed, H); double min_x = transformed[0].x; double min_y = transformed[0].y; double max_x = transformed[0].x; double max_y = transformed[0].y; for (int i = 1; i < 4; i++) { min_x = min(min_x, transformed[i].x); min_y = min(min_y, transformed[i].y); max_x = max(max_x, transformed[i].x); max_y = max(max_y, transformed[i].y); } double width = max_x - min_x; double height = max_y - min_y; // 设置最大尺寸限制 const int MAX_DIMENSION = 15000; if (width <= 0 || height <= 0 || width > MAX_DIMENSION || height > MAX_DIMENSION) { new_size = img.size(); return Mat::eye(3, 3, CV_64F); } // 添加30%边界 + 200像素固定边界 double border_x = max(width * 0.3, 200.0); double border_y = max(height * 0.3, 200.0); min_x -= border_x; max_x += border_x; min_y -= border_y; max_y += border_y; new_size = Size(ceil(max_x - min_x), ceil(max_y - min_y)); // 创建平移矩阵 Mat T = Mat::eye(3, 3, CV_64F); T.at<double>(0, 2) = -min_x; T.at<double>(1, 2) = -min_y; return T * H; } int main() { try { // 定义投影矩阵 (确保每个矩阵有12个元素) Mat P1 = (Mat_<double>(3, 4) << -12179.8753230552230, 7050.9952897638232, -2467.7527210258945, -17321440031.6463700000000, 4723.7392252925192, 5779.0243267188052, -11880.0042304789190, -22040783539.2805860000000, -0.4907881086633, -0.5142398041434, -0.7033380810316, 2000536.1381758042000 ); Mat P2 = (Mat_<double>(3, 4) << -12158.6697497674500, 7092.3578385200199, -2453.7545028069599, -17474815958.9305270000000, 4621.9021026258170, 5524.7193480639962, -12039.9681076173220, -21127026467.7189250000000, -0.5027584877552, -0.5235467256044, -0.6878464429645, 2038373.8802346450000 ); // 加载图像 Mat img_left = imread("D:\\work\\data1\\015AR027.tif"); Mat img_right = imread("D:\\work\\data1\\015AR028.tif"); if (img_left.empty() || img_right.empty()) { cerr << "Error loading images" << endl; return -1; } // 分解投影矩阵 Mat K1, K2, R1, R2, t1, t2; decomposeProjectionMatrix(P1, K1, R1, t1); decomposeProjectionMatrix(P2, K2, R2, t2); t1 = t1.rowRange(0, 3) / t1.at<double>(3); t2 = t2.rowRange(0, 3) / t2.at<double>(3); // 计算相机中心和基线 Mat R1_inv = R1.inv(DECOMP_SVD); Mat R2_inv = R2.inv(DECOMP_SVD); Mat C1 = -R1_inv * t1; Mat C2 = -R2_inv * t2; Mat b = C2 - C1; // 定义三个方向 vector<Mat> rops; rops.push_back((Mat_<double>(3, 1) << 0, 0, 1)); // 水平 rops.push_back((Mat_<double>(3, 1) << 0, 1, 0)); // 垂直 rops.push_back(normalizeVec(R1.row(2).t())); // 原始 vector<string> dir_names; dir_names.push_back("horizontal"); dir_names.push_back("vertical"); dir_names.push_back("original"); for (int i = 0; i < 3; i++) { // 计算坐标系 Mat z_axis = rops[i]; Mat x_axis, y_axis; // 处理基线与方向平行的情况 Mat cross_b_z = crossProduct(b, z_axis); double n = norm(cross_b_z); if (n < 1e-5) { Mat ref_vec = (Mat_<double>(3, 1) << 1, 0, 0); if (abs(z_axis.dot(ref_vec)) > 0.95) { ref_vec = (Mat_<double>(3, 1) << 0, 0, 1); } x_axis = normalizeVec(ref_vec - (ref_vec.dot(z_axis)) * z_axis); } else { x_axis = normalizeVec(cross_b_z); } y_axis = normalizeVec(crossProduct(z_axis, x_axis)); // 构造目标旋转矩阵 Mat R_target = (Mat_<double>(3, 3) << x_axis.at<double>(0), x_axis.at<double>(1), x_axis.at<double>(2), y_axis.at<double>(0), y_axis.at<double>(1), y_axis.at<double>(2), z_axis.at<double>(0), z_axis.at<double>(1), z_axis.at<double>(2)); R_target = R_target.t(); // 计算新的旋转矩阵和单应矩阵 Mat R1_new = R_target * R1.t(); Mat R2_new = R_target * R2.t(); Mat K1_temp = K1.clone(); Mat K2_temp = K2.clone(); K1_temp.at<double>(0, 2) = 0; K1_temp.at<double>(1, 2) = 0; K2_temp.at<double>(0, 2) = 0; K2_temp.at<double>(1, 2) = 0; double avg_focal1 = (K1.at<double>(0, 0) + K1.at<double>(1, 1)) / 2.0; double avg_focal2 = (K2.at<double>(0, 0) + K2.at<double>(1, 1)) / 2.0; K1_temp.at<double>(0, 0) = avg_focal1; K1_temp.at<double>(1, 1) = avg_focal1; K2_temp.at<double>(0, 0) = avg_focal2; K2_temp.at<double>(1, 1) = avg_focal2; Mat H1 = K1_temp * R1_new * K1.inv(); Mat H2 = K2_temp * R2_new * K2.inv(); // 调整单应矩阵确保包含整个图像 Size new_size1, new_size2; Mat H1_adj = ensureFullImage(H1, img_left, new_size1); Mat H2_adj = ensureFullImage(H2, img_right, new_size2); // 应用透视变换 Mat rect_left, rect_right; warpPerspective(img_left, rect_left, H1_adj, new_size1); warpPerspective(img_right, rect_right, H2_adj, new_size2); // 保存结果 imwrite("rectified_left_" + dir_names[i] + ".png", rect_left); imwrite("rectified_right_" + dir_names[i] + ".png", rect_right); } cout << "核线影像已生成并保存!" << endl; return 0; } catch (const Exception& e) { cerr << "OpenCV Exception: " << e.what() << endl; return -1; } catch (...) { cerr << "Unknown exception occurred!" << endl; return -1; } }把生成的结果图保存到"D:\work\data1\result"
07-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值