//#include <stdio.h>
//#include <iostream>
//#include <opencv2/opencv.hpp>
//#include <Eigen/Dense>
//
//using namespace Eigen;
//using namespace cv;
//using namespace std;
//
//#define M_PI 3.1415926
//
//void GetPoints(vector<string> fileNames, std::vector<std::vector<Point>>& groupPoints, int Length, int Threshold);
//void Defined_MB_POINT(Eigen::Vector3d MB_POINTS[4]);
//void svdSolveMatrix(Eigen::Vector3d pointInB[4], Eigen::Vector3d pointInA[4], Eigen::Matrix4d& result, double& error);
//void solveMatrix(Eigen::Vector3d pointInB[4], Eigen::Vector3d pointInA[4], Eigen::Matrix4f& result, double& error);
//void solveResult(Eigen::Vector3d pointInB[4], Eigen::Vector3d pointInA[4]);
//int main()
//{
//
// // 1.0 通过手动标定的点获取点的相关坐标参数, 并实现图像的预处理发过程,主要包括质点中心的计算
// vector<string> fileNames = {
// "D:\\imgs\\4.7.jpg",
// "D:\\imgs\\5.5.jpg",
// "D:\\imgs\\6.3.jpg",
// "D:\\imgs\\7.1.jpg",
// "D:\\imgs\\7.9.jpg",
// "D:\\imgs\\8.7.jpg",
// "D:\\imgs\\9.5.jpg"
// };
//
// std::vector<std::vector<Point>> groupPoints;
//
// GetPoints(fileNames, groupPoints, 7, 60);
//
//
// // 2.0 通过坐标参数与实际距离参数 , 计算spacing
//
// // 3.0 建立适配矩阵, 该矩阵的建立需要四个点, 采用齐次坐标系表示
//
//
// waitKey(0);
// return 0;
//}
//
//
//void GetPoints(vector<string> fileNames, std::vector<std::vector<Point>>& groupPoints, int Length, int Threshold)
//{
// vector<Mat> images;
// Mat m;
// for (int i = 0; i < Length; i++)
// {
// m = imread(fileNames[i], 1);
// images.push_back(m);
// //cout << fileNames[i] << endl;
// }
// //cout << endl << endl;
//
//
// // 定义图像的大小
// int imageWidth = 812, imageHeight = 640;
//
//
//
// /*将图像二值化*/
//
// for (int k = 0; k < Length; k++)
// {
//
// for (int i = 0; i < images[k].rows; i++)
// {
// for (int j = 0; j < images[k].cols; j++)
// {
// if (images[k].at<Vec3b>(i, j)[0] < Threshold)
// {
// images[k].at<Vec3b>(i, j)[0] = 0;
// images[k].at<Vec3b>(i, j)[1] = 0;
// images[k].at<Vec3b>(i, j)[2] = 0;
// }
// else {
// images[k].at<Vec3b>(i, j)[0] = 255;
// images[k].at<Vec3b>(i, j)[1] = 255;
// images[k].at<Vec3b>(i, j)[2] = 255;
// }
// }
// }
// }
//
// /* 定义图像的截取大小中心, 超声图像就是从该位置截取的*/
// long Width = 500, height = 450, X = 50, Y = 100;
// vector<Mat> oris;
//
// for (int i = 0; i < Length; i++)
// {
// Mat grayimg(images[i], Rect(X, Y, Width, height));
// oris.push_back(grayimg);
// }
//
// /* 找到图像的轮廓, 并求解质心*/
// vector<vector<Point>> contours;
// Moments moment;
//
// Mat thr, gray;
// Point p;
// for (int i = 0; i < Length; i++)
// {
// vector<Point> groupPoint;
// cvtColor(oris[i], gray, COLOR_BGR2GRAY);
// findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
//
// for (int i = 0; i < contours.size(); i++)
// {
// Mat temp(contours.at(i));
// moment = moments(temp, false);
// if (moment.m00 != 0)//除数不能为0
// {
// p.x = cvRound(moment.m10 / moment.m00) + X;//计算重心横坐标
// p.y = cvRound(moment.m01 / moment.m00) + Y;//计算重心纵坐标
// }
// groupPoint.push_back(p);
// }
// groupPoints.push_back(groupPoint);
// }
//
//
// // 求解像素比
// double spaxing[7];
// double read_long = sqrt(5 * 5 + 40 * 40);
// double read_long1 = sqrt(10 * 10 + 30 * 30);
// for (int i = 0; i < groupPoints.size(); i++)
// {
// for (int j = 0; j < groupPoints[i].size(); j++)
// {
// Scalar color(0, 0, 255);
// circle(images[i], groupPoints[i][j], 3, color, 1, 8);
// cv::putText(images[i], std::to_string(j), groupPoints[i][j], cv::FONT_HERSHEY_SIMPLEX, 0.45, CV_RGB(255, 230, 0), 1.8);
// }
// cv::line(images[i], groupPoints[i][0], groupPoints[i][1], cv::Scalar(255, 255, 0), 1);
// /*任意取两点计算其实际的像素距离*/
// double L_IMGGE = sqrt(pow(groupPoints[i][0].x - groupPoints[i][1].x, 2) + pow(groupPoints[i][0].y - groupPoints[i][1].y, 2));
// double L_IMGGE1 = sqrt(pow(groupPoints[i][2].x - groupPoints[i][3].x, 2) + pow(groupPoints[i][2].y - groupPoints[i][3].y, 2));
// //spaxing[i] = read_long / L_IMGGE;
//
// spaxing[i] = ((read_long / L_IMGGE) + (read_long1 / L_IMGGE1)) / 2;
// cout << read_long / L_IMGGE << " " << read_long1 / L_IMGGE1 << endl;
// //cout << spaxing[i] << " ";
//
// spaxing[i] =
// //imshow(std::to_string(i + 1), images[i]);
// }
//
//
// //====================求解同步长为0.8 的像素比增长因子=============================
// cout << "像素比增长因子:" << endl;
// for (int i = 0; i < Length; i++)
// {
// cout << spaxing[i] << " ";
// /*if (i > 0)
// {
// cout << spaxing[i] - spaxing[i - 1] << " ";
// } */
// }
// cout << endl;
//
// //=================================================================================
//
//
//
// /* 定义图像的坐标点(已经计算完成 groupPoints)*/
// // 将图像坐标根据0,1 两个点做对称变换
//
// for (int i = 0; i < groupPoints.size(); i++)
// {
// double x_axi = groupPoints[i][0].x + (groupPoints[i][1].x - groupPoints[i][0].x) / 2;
// for (int j = 0; j < 4; j++)
// {
// double distance = abs(groupPoints[i][j].x - x_axi);
//
// if (groupPoints[i][j].x < x_axi) {
// groupPoints[i][j].x = groupPoints[i][j].x + 2 * distance;
// }
// else {
// groupPoints[i][j].x = groupPoints[i][j].x - 2 * distance;
// }
//
// Scalar color(0, 255, 255);
// circle(images[i], groupPoints[i][j], 3, color, 1, 8);
// cv::putText(images[i], std::to_string(j), groupPoints[i][j], cv::FONT_HERSHEY_SIMPLEX, 0.45, CV_RGB(255, 230, 0), 1.8);
// imshow(std::to_string(i + 1), images[i]);
// }
// }
//
// /*定义模板的坐标点===============================================================*/
// Eigen::Vector3d MB_POINTS[4];
// Defined_MB_POINT(MB_POINTS);
// //=================================================================================
//
// // 像素比参数
// double spacingPix[7] = { 0.100476 , 0.115214 , 0.130149, 0.144649 , 0.159711 , 0.176296 , 0.190192 };
// Eigen::Vector3d US_POINTS[7][4];
//
// // 原始的对角矩阵无法实现坐标系的转换,因此需要通过-(Y-y)
// /*Matrix3d dialog;
// dialog << 1, 0, 0,
// 0, -1, 0,
// 0, 0, 1;*/
//
// for (int j = 0; j < Length; j++)
// {
// //cout << endl << "图像" << j + 1 << " 的超声点矩阵:" << endl;
// for (int i = 0; i < 4; i++)
// {
// double values[3] = { groupPoints[j][i].x,groupPoints[j][i].y,0 };
// values[1] = values[1] - imageHeight; // 将坐标系从左上变换为左下
// US_POINTS[j][i] = Eigen::Vector3d(values) * spaxing[i];
//
// //US_POINTS[j][i] = dialog * Eigen::Vector3d(values) * spacingPix[i];
// //cout << US_POINTS[j][i].transpose() << " 1" << endl;
// }
//
// //Eigen::Matrix4f result;
// Eigen::Matrix4d result;
// double error;
//
// /*实现匹配*/
// //svdSolveMatrix(US_POINTS[j], MB_POINTS, result, error);
// //solveMatrix(US_POINTS[j], MB_POINTS, result, error);
//
//
// solveResult(US_POINTS[j], MB_POINTS);
// /*
// cout << endl << "转换矩阵T:" << endl;
// cout << result << endl << endl;
// */
//
//
// }
//}
//
//
//
//void Defined_MB_POINT(Eigen::Vector3d MB_POINTS[4])
//{
// /*下边框距离3.5mm*/
// /*左右边框距离10mm*/
//
// double A1[3] = { 60.2,8.8,0 };
// double A2[3] = { 20.2,13.8,0 };
// double A3[3] = { 45.2,18.8,0 };
// double A4[3] = { 15.2,28.8,0 };
//
// MB_POINTS[0] = Eigen::Vector3d(A1);
// MB_POINTS[1] = Eigen::Vector3d(A2);
// MB_POINTS[2] = Eigen::Vector3d(A3);
// MB_POINTS[3] = Eigen::Vector3d(A4);
//
// Matrix3d dialog;
// dialog << 1, 0, 0,
// 0, -1, 0,
// 0, 0, 1;
//
// // x 不变,y和z旋转90
// // 1.0 旋转 : 定义旋转向量
// Eigen::Vector3d ea(M_PI / 2, 0, -M_PI / 24);
// //Eigen::Vector3d ea(0, 0, 0);
// Eigen::Matrix3d rotationMatrix;
// rotationMatrix = Eigen::AngleAxisd(ea[0], Eigen::Vector3d::UnitX())
// * Eigen::AngleAxisd(ea[1], Eigen::Vector3d::UnitY())
// * Eigen::AngleAxisd(ea[2], Eigen::Vector3d::UnitZ());
//
// /*
// 5.5 深度 Vector3d ea(M_PI / 2, 0, -M_PI / 32)
// 6.3 深度 Vector3d ea(M_PI / 2, 0, -M_PI / 30)
// 7.1 深度 Vector3d ea(M_PI / 2, 0, -M_PI / 26)
// 7.9 深度
// */
//
// //cout << "体模:" << endl;
// /*转化到世界坐标系中*/
// for (int i = 0; i < 4; i++)
// {
// MB_POINTS[i] = rotationMatrix * MB_POINTS[i];
// //MB_POINTS[i] = rotationMatrix * dialog * MB_POINTS[i];
// //cout << MB_POINTS[i].transpose() << " 1" << endl;
// }
//}
//
//
///*
// 求解两个坐标系之间的转换矩阵
//*/
//void solveResult(Eigen::Vector3d pointInB[4], Eigen::Vector3d pointInA[4])
//{
//
// /*
// 数据转换, 定义两个数据结构类型
// */
// std::vector<cv::Point3f> srcPoints;
// std::vector<cv::Point3f> dstPoints;
//
//
// for (int i : {0, 1, 2})
// {
// srcPoints.push_back(cv::Point3f(pointInB[i](0), pointInB[i](1), pointInB[i](2)));
// dstPoints.push_back(cv::Point3f(pointInA[i](0), pointInA[i](1), pointInA[i](2)));
// }
//
//
//
// //==============================================
// double srcSumX = 0.0f;
// double srcSumY = 0.0f;
// double srcSumZ = 0.0f;
//
// double dstSumX = 0.0f;
// double dstSumY = 0.0f;
// double dstSumZ = 0.0f;
//
// int pointsNum = srcPoints.size();
// for (int i = 0; i < pointsNum; ++i)
// {
// srcSumX += srcPoints[i].x;
// srcSumY += srcPoints[i].y;
// srcSumZ += srcPoints[i].z;
//
// dstSumX += dstPoints[i].x;
// dstSumY += dstPoints[i].y;
// dstSumZ += dstPoints[i].z;
// }
//
// cv::Point3d centerSrc, centerDst;
//
// centerSrc.x = double(srcSumX / pointsNum);
// centerSrc.y = double(srcSumY / pointsNum);
// centerSrc.z = double(srcSumZ / pointsNum);
//
// centerDst.x = double(dstSumX / pointsNum);
// centerDst.y = double(dstSumY / pointsNum);
// centerDst.z = double(dstSumZ / pointsNum);
//
// //Mat::Mat(int rows, int cols, int type)
// cv::Mat srcMat(3, pointsNum, CV_64FC1);
// cv::Mat dstMat(3, pointsNum, CV_64FC1);
//
// for (int i = 0; i < pointsNum; ++i)//N组点
// {
// //三行
// srcMat.at<double>(0, i) = srcPoints[i].x - centerSrc.x;
// srcMat.at<double>(1, i) = srcPoints[i].y - centerSrc.y;
// srcMat.at<double>(2, i) = srcPoints[i].z - centerSrc.z;
//
// dstMat.at<double>(0, i) = dstPoints[i].x - centerDst.x;
// dstMat.at<double>(1, i) = dstPoints[i].y - centerDst.y;
// dstMat.at<double>(2, i) = dstPoints[i].z - centerDst.z;
//
// }
//
// cv::Mat matS = srcMat * dstMat.t();
//
// cv::Mat matU, matW, matV;
// cv::SVDecomp(matS, matW, matU, matV);
//
// cv::Mat matTemp = matU * matV;
// double det = cv::determinant(matTemp);//行列式的值
//
// double datM[] = { 1, 0, 0, 0, 1, 0, 0, 0, det };
// cv::Mat matM(3, 3, CV_64FC1, datM);
//
// cv::Mat matR = matV.t() * matM * matU.t();
//
// double* datR = (double*)(matR.data);
// double delta_X = centerDst.x - (centerSrc.x * datR[0] + centerSrc.y * datR[1] + centerSrc.z * datR[2]);
// double delta_Y = centerDst.y - (centerSrc.x * datR[3] + centerSrc.y * datR[4] + centerSrc.z * datR[5]);
// double delta_Z = centerDst.z - (centerSrc.x * datR[6] + centerSrc.y * datR[7] + centerSrc.z * datR[8]);
//
//
// //生成RT齐次矩阵(4*4)
// cv::Mat R_T = (cv::Mat_<double>(4, 4) <<
// matR.at<double>(0, 0), matR.at<double>(0, 1), matR.at<double>(0, 2), delta_X,
// matR.at<double>(1, 0), matR.at<double>(1, 1), matR.at<double>(1, 2), delta_Y,
// matR.at<double>(2, 0), matR.at<double>(2, 1), matR.at<double>(2, 2), delta_Z,
// 0, 0, 0, 1
// );
//
// cout << "========================";
// cout << endl << R_T << endl;
//
//}
//
//void solveMatrix(Eigen::Vector3d pointInB[4], Eigen::Vector3d pointInA[4], Eigen::Matrix4f& result, double& error)
//{
// // 求解超声 和 模板矩阵的平均中心
//
// Eigen::Matrix4f B;
// Eigen::Matrix4f A;
// Eigen::Matrix4f repmat_A;
// Eigen::Matrix4f repmat_B;
//
// Eigen::Matrix4f H;
//
// // 将数组转化为矩阵
// for (int i : {0, 1, 2, 3})
// {
// B.row(i) << pointInB[i](0), pointInB[i](1), pointInB[i](2), 1;
// A.row(i) << pointInA[i](0), pointInA[i](1), pointInA[i](2), 1;
// }
//
// // 求解平均中心
// Eigen::Vector4f centriod_A;
// Eigen::Vector4f centriod_B;
// for (int i : {0, 1, 2, 3})
// {
// float value = (float)((A.row(0) + A.row(1) + A.row(2) + A.row(3)) / 4)[i];
// centriod_A(i) = value;
// value = (float)((B.row(0) + B.row(1) + B.row(2) + B.row(3)) / 4)[i];
// centriod_B(i) = value;
// }
//
// //创建均值矩阵
// for (int i : {0, 1, 2, 3})
// {
// repmat_A.row(i) << centriod_A(0), centriod_A(1), centriod_A(2), centriod_A(3);
// repmat_B.row(i) << centriod_B(0), centriod_B(1), centriod_B(2), centriod_B(3);
// }
//
// // 创建均值矩阵的原理在于将所有的点移动到原点。
//
// H = (A - repmat_A).transpose() * (B - repmat_B);
//
// MatrixXf Hm;
//
// std::vector < std::vector < float >> vec;
// const int rows{ 4 }, cols{ 4 };
// for (int i : {0, 1, 2, 3})
// {
// std::vector<float> vec1;
// for (int j : {0, 1, 2, 3})
// {
// vec1.push_back((float)H.row(i)[j]);
// }
// vec.push_back(vec1);
// }
//
// std::vector<float> vec_;
// for (int i = 0; i < rows; ++i) {
// vec_.insert(vec_.begin() + i * cols, vec[i].begin(), vec[i].end());
// }
// Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> m(vec_.data(), rows, cols);
//
// Eigen::JacobiSVD<Eigen::MatrixXf> svd(m, Eigen::ComputeFullV | Eigen::ComputeFullU); // ComputeThinU | ComputeThinV
// Eigen::MatrixXf singular_values = svd.singularValues();
// Eigen::MatrixXf left_singular_vectors = svd.matrixU();
// Eigen::MatrixXf right_singular_vectors = svd.matrixV();
//
//
// Eigen::MatrixXf R = right_singular_vectors * left_singular_vectors.transpose();
//
// //cout << "determinant:" << R.determinant() << endl;
//
// cout << "====================" << endl;
//
// if (R.determinant() < 0)
// {
// //cout << "V" << right_singular_vectors << endl;
// for (int i = 0; i < 4; i++)
// {
// right_singular_vectors.row(i)(2) = -1 * right_singular_vectors.row(i)(2);
// }
// //cout << "-V" << right_singular_vectors << endl;
// R = right_singular_vectors * left_singular_vectors.transpose();
// }
//
// Eigen::Vector4f t = -R * centriod_A + centriod_A;
//
// R.row(0)(3) = t(0);
// R.row(1)(3) = t(1);
// R.row(2)(3) = t(2);
// R.row(3)(3) = 1;
// cout << endl << R << endl << endl;
//}
//
//void svdSolveMatrix(Eigen::Vector3d pointInB[4], Eigen::Vector3d pointInA[4], Eigen::Matrix4d& result, double& error)
//{
// //解空间
// Eigen::Vector4d r1, r2, r3, r4;
//
// 系数矩阵
// Eigen::Matrix4d matrix;
//
// //超声的z轴数据均为0 ,因此矩阵的第三列的值没有办法解出来,通过z轴 = x 和 y的叉乘即可得出
// for (int i : {0, 1, 2, 3})
// {
// matrix.row(i) << pointInB[i](0), pointInB[i](1), pointInB[i](2), 1.0;
// }
//
// Eigen::Vector4d vector1;
// vector1 << pointInA[0](0), pointInA[1](0), pointInA[2](0), pointInA[3](0);
//
// Eigen::Vector4d vector2;
// vector2 << pointInA[0](1), pointInA[1](1), pointInA[2](1), pointInA[3](1);
//
// Eigen::Vector4d vector3;
// vector3 << pointInA[0](2), pointInA[1](2), pointInA[2](2), pointInA[3](2);
//
// r1 = matrix.colPivHouseholderQr().solve(vector1);
// r2 = matrix.colPivHouseholderQr().solve(vector2);
// r3 = matrix.colPivHouseholderQr().solve(vector3);
//
// result.row(0) << r1(0), r1(1), r1(2), r1(3);
// result.row(1) << r2(0), r2(1), r2(2), r2(3);
// result.row(2) << r3(0), r3(1), r3(2), r3(3);
// result.row(3) << 0, 0, 0, 1;
//
//
// /* 求解z空间向量*/
// Eigen::Vector3d v1, v2, v3;
// v1 << r1(0), r2(0), r3(0);
// v1.normalize();
//
// v2 << r1(1), r2(1), r3(1);
// v2.normalize();
//
// v3 = v1.cross(v2);
//
// result(0, 2) = v3(0);
// result(1, 2) = v3(1);
// result(2, 2) = v3(2);
//
// cout << endl << result << endl << endl;
//
//
//}
svd求解刚性转变换矩阵
最新推荐文章于 2022-04-16 18:29:03 发布