2020-01-15 C++ 絕對(duì)定向

#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

using namespace cv;
using namespace std;

//求解絕對(duì)定向的步驟
/*
① 給定七個(gè)參數(shù)的初始值 phi = omega = kappa = 0 scale = 1 X = Y =Z= 0屯烦;
② 計(jì)算控制點(diǎn)地面坐標(biāo)系的重心坐標(biāo)和各控制點(diǎn)重心化的坐標(biāo)
③ 計(jì)算模型點(diǎn)空間坐標(biāo)系的重心坐標(biāo)和各模型點(diǎn)重心化的坐標(biāo)
④ 計(jì)算常數(shù)項(xiàng) 誤差方程的常數(shù)項(xiàng)(矩陣表示)【lx ly lz】^T 書(shū)本71
⑤ 計(jì)算誤差方程的系數(shù)矩陣 一般為3*7 矩陣(多個(gè)控制點(diǎn)則表示為3n * 7) 
⑥ 逐點(diǎn)法化求解法方程
⑦ 計(jì)算待定系數(shù)(scale phi omega kappa)的新值
⑧ 判斷待定系數(shù)改正數(shù)是否均小于限定閾值xita
⑨ 根據(jù)求解的系數(shù)(scale phi omega kappa)代入重心變換方程求解X Y Z
*/

#define NUM 4 //地面控制點(diǎn)數(shù)量
#define JINDU 0.001//閾值
#define PI 3.14159265358975

//矩陣的數(shù)乘
Mat muul(Mat& p, double s) {
    int row = p.rows;
    int col = p.cols;
    Mat res = Mat_<double>(row, col);

    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {

            res.at <double>(i, j) = s;
        }

    }

    res = p.mul(res);
    double a = res.at<double>(0, 0);
    return res;

}


//求重心
Mat getTheCore(vector<Mat> &vec1) {

    int num = vec1.size();
    Mat p1 = (Mat_<double>(3, 1) << 0.0, 0.0, 0.0);
    for (int i = 0; i < num; i++)
    {
        p1 = p1 + vec1[i];


    }
    double cc = 1 / (double)num;
    Mat res = muul(p1,cc);
    double a = res.at<double>(0, 0);

    return res;

}

//攝影測(cè)量R矩陣
Mat getTheR(double omiga, double phi, double kamma) {
    double a1 = cos(phi) * cos(kamma) - sin(phi) * sin(omiga) * sin(kamma);
    double a2 = -cos(phi) * sin(kamma) - sin(phi) * sin(omiga) * cos(kamma);
    double a3 = -sin(phi) * cos(omiga);
    double b1 = cos(omiga) * sin(kamma);
    double b2 = cos(omiga) * cos(kamma);
    double b3 = -sin(omiga);
    double c1 = sin(phi) * cos(kamma) + cos(phi) * sin(omiga) * sin(kamma);
    double c2 = -sin(phi) * sin(kamma) + cos(phi) * sin(omiga) * cos(kamma);
    double c3 = cos(phi) * cos(omiga);

    Mat result = (Mat_<double>(3, 3) << a1, a2, a3, b1, b2, b3, c1, c2, c3);
    return result;

}

//多個(gè)控制點(diǎn)的矩陣形式轉(zhuǎn)換
Mat transMat(vector<Mat>& vec, int num) {

    Mat ret = vec[0];

    for (int i = 1; i < vec.size(); i++)
    {
        vconcat(ret, vec[i], ret);
    }
    return ret;
}

//L

Mat getL(vector<Mat>& vec_tp, vector<Mat>& vec, double scale, Mat& r) {

    vector<Mat> vec_L;

    for (int i = 0; i < vec.size(); i++)
    {
        Mat m_tp = vec_tp[i];
        Mat m = vec[i];
        Mat r_m = r * m;
        Mat L = m_tp - muul(r_m,scale);
        vec_L.push_back(L);

    }

    Mat LL = transMat(vec_L, NUM);

    return LL;
}

//A

Mat getA(vector<Mat> &vec) {

    vector<Mat> vec_A;
    for (int i = 0; i < vec.size(); i++)
    {
        Mat m = vec[i];
        double X = m.at<double>(0, 0);
        double Y = m.at<double>(1, 0);
        double Z = m.at<double>(2, 0);

        Mat A = (Mat_<double>(3, 7) << 1, 0, 0, X, -Z, 0, -Y,
            0, 1, 0, Y, 0, -Z, X,
            0, 0, 1, Z, X, Y, 0);

        vec_A.push_back(A);
    }

    
    Mat AA = transMat(vec_A, NUM);


    return AA;

}

//求重心化
vector<Mat> CoreMat(vector<Mat> &p1, Mat &core) {

    vector<Mat> result;

    for (int i = 0; i < p1.size(); i++)
    {
        Mat m = p1[i];
        Mat res_m = m - core;
        result.push_back(res_m);
    }

    return result;
}

//計(jì)算改正數(shù)
Mat getX(Mat& A, Mat& L) {

    Mat AtA = (A.t()) * A;
    Mat nAtA;
    invert(AtA, nAtA, DECOMP_LU);
    Mat X = nAtA * (A.t()) * L;
    return X;
}

int main(int argc, char* argv[]) {



    // 初始化參數(shù)
    double scale = 1.0;
    double omega = 0.0;
    double phi = 0.0;
    double kappa = 0.0;
    double X = 0.0;
    double Y = 0.0;
    double Z = 0.0;

    //改正數(shù)
    double d_scale = 1.0;
    double d_phi = 1.0;
    double d_omega = 1.0;
    double d_kappa = 1.0;

    double jindu = JINDU;

    /*測(cè)試一下*/



    vector<Mat> vec1 = {(Mat_<double>(3,1)<< 153.706,767.599, 4.98951),(Mat_<double>(3,1) << 826.447,757.146,45.0979) ,(Mat_<double>(3,1) << 130.021,-772.319,-14.688) ,(Mat_<double>(3,1) << 804.556, -782.906 ,-22.5479) };//像輔助原始點(diǎn)坐標(biāo)
    vector<Mat> vec2 = {(Mat_<double>(3,1) << 5083.26,5852.04,527.963),(Mat_<double>(3,1) << 5779.98,5906.4,571.513) ,(Mat_<double>(3,1) << 5210.76,4258.46,461.775) ,(Mat_<double>(3,1) << 5909.37,4314.29,455.517) };//控制點(diǎn)地面原始點(diǎn)坐標(biāo)

    vector<Mat> core_vec1;//像輔助重心化點(diǎn)坐標(biāo)
    vector<Mat> core_vec2;//控制點(diǎn)地面重心化點(diǎn)坐標(biāo)

    //求解重心和重心化坐標(biāo)
    Mat core1 = getTheCore(vec1);
    Mat core2 = getTheCore(vec2);


    core_vec1 = CoreMat(vec1, core1);
    core_vec2 = CoreMat(vec2, core2);


    while (!(!(fabs(d_kappa) > jindu) && !(fabs(d_omega) > jindu) && !(fabs(d_phi) > jindu)))
    {
        //獲得矩陣形式的R,A L
        Mat R = getTheR(omega, phi, kappa);
        Mat A = getA(core_vec1);
        Mat L = getL(core_vec2, core_vec1, scale, R);

        //計(jì)算改正數(shù)
        Mat XX = getX(A, L);
    

        //計(jì)算新值
        d_scale = XX.at<double>(3, 0);
        d_phi = XX.at<double>(4, 0);
        d_omega = XX.at <double>(5, 0);
        d_kappa = XX.at<double>(6, 0);

        scale = scale *(1 + d_scale);
        phi += d_phi;
        omega += d_omega;
        kappa += d_kappa;
    }
    

    //計(jì)算最終的XYZ
    Mat R = getTheR(omega, phi, kappa);
    Mat XYZ;
    Mat r_core1 = R * core1;
    XYZ = core2 - muul(r_core1, scale);
 
    double pi = PI;
    double dS_omega = (180/pi)*(omega - int(omega / (2*pi)) * (2*pi));
    double dS_phi = (180 / pi) * (phi - int(phi / (2 * pi)) * (2 * pi));
    double dS_kappa = (180 / pi) * (kappa - int(kappa / (2 * pi)) * (2 * pi));
    X = XYZ.at<double>(0, 0);
    Y = XYZ.at<double>(1, 0);
    Z = XYZ.at<double>(2, 0);

    return 1;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渺氧,一起剝皮案震驚了整個(gè)濱河市涩哟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌啄栓,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宙彪,死亡現(xiàn)場(chǎng)離奇詭異蜻势,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)屋彪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)所宰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人畜挥,你說(shuō)我怎么就攤上這事仔粥。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵躯泰,是天一觀的道長(zhǎng)谭羔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)麦向,這世上最難降的妖魔是什么瘟裸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮诵竭,結(jié)果婚禮上话告,老公的妹妹穿的比我還像新娘。我一直安慰自己秀撇,他們只是感情好超棺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著呵燕,像睡著了一般棠绘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上再扭,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天氧苍,我揣著相機(jī)與錄音,去河邊找鬼泛范。 笑死让虐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的罢荡。 我是一名探鬼主播赡突,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼区赵!你這毒婦竟也來(lái)了惭缰?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤笼才,失蹤者是張志新(化名)和其女友劉穎漱受,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體骡送,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昂羡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摔踱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虐先。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖派敷,靈堂內(nèi)的尸體忽然破棺而出赴穗,到底是詐尸還是另有隱情,我是刑警寧澤膀息,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布般眉,位于F島的核電站,受9級(jí)特大地震影響潜支,放射性物質(zhì)發(fā)生泄漏甸赃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一冗酿、第九天 我趴在偏房一處隱蔽的房頂上張望埠对。 院中可真熱鬧,春花似錦裁替、人聲如沸项玛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)襟沮。三九已至,卻和暖如春昌腰,著一層夾襖步出監(jiān)牢的瞬間开伏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工遭商, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留固灵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓劫流,卻偏偏與公主長(zhǎng)得像巫玻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子祠汇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容