Calibração do ponto N - transformação do sistema de coordenadas



1: Algoritmo de calibração

vector_to_hom_mat2d(Px, Py, Qx, Qy, HomMat2D)
insira a descrição da imagem aqui
refere-se aqui à documentação oficial do bloco do operador halcon, usando o método dos mínimos quadrados para encontrar a matriz HomMat2D. -A calibração de nove pontos é comumente usada para encontrar a transformação de coordenadas dos dois sistemas de coordenadas. .
O seguinte princípio de implementação pessoal, o resultado é consistente com o resultado calculado pelo operador acima, o conhecimento é limitado e é apenas para aprendizado e comunicação.
1: Vejamos primeiro uma imagem. A matriz na imagem tem 2 linhas e 3 colunas, e a última coluna é 0, 0, 1; como uma matriz homogênea é usada, a expansão é omitida. A razão específica pela qual está em tal forma de matriz é, na verdade, uma série de transformações, ou seja, transformação afim bidimensional do plano.

insira a descrição da imagem aqui

2: Em seguida, use o método dos mínimos quadrados para listar os itens (método dos mínimos quadrados) insira a descrição da imagem aquie calcule a derivada parcial para cada quantidade desconhecida. Existem duas quantidades desconhecidas na figura, ou seja, duas equações são listadas. Se houver três incógnitas quantidades, ou seja, três equações e
insira a descrição da imagem aqui
três quantidades desconhecidas são derivadas, e o resultado é a quantidade desconhecida na matriz correspondente. .

3: Os métodos acima estão todos demonstrados nas notas, se forem colocados no programa como fazer? Como encontrar o desconhecido com o método acima? Abaixo está o código-fonte da minha implementação pessoal. Aqui eu uso a regra de Cramer para encontrar o sistema de equações, listar o determinante para solução e colocá-lo no código para uma solução fácil.

A maneira correta é encontrar os coeficientes de cada quantidade desconhecida, por exemplo:

insira a descrição da imagem aqui
insira a descrição da imagem aqui
4: Demonstração do código principal

//保存从界面获取的坐标数据
struct _coordList{
    
    
    QList<QPair<double,double>> pixPoines;//保存像素坐标
    QList<QPair<double,double>> physicsPoines;//保存物理坐标
};

//保存最小二乘法三个未知量(a,b,c)的结果
struct _squareLaw{
    
    
    double aa=0;
    double bb=0;
    double cc=0;
    double ab=0;
    double ac=0;
    double bc=0;
    double _a=0;
    double _b=0;
    double _c=0;
};
//导数3x4
struct _differentialCoefficient{
    
    
    QList<double> diff_a;
    QList<double> diff_b;
    QList<double> diff_c;
};

//矩阵3X3
struct _mat{
    
    
    double a=0;
    double b=0;
    double c=0;
    double d=0;
    double e=0;
    double f=0;
    double g=0;
    double h=0;
    double i=0;
};

//标定
_mat MainWindow::calibration(_coordList coordL)
{
    
    
    //保存未知量(a,b,c)的系数
    _squareLaw squareLaw_x;
    _squareLaw squareLaw_y;
    for(int i=0;i<coordL.pixPoines.count();i++) {
    
    
        squareLaw_x.aa += pow(coordL.pixPoines.at(i).first,2)*2;
        squareLaw_x.bb += pow(coordL.pixPoines.at(i).second,2)*2;
        squareLaw_x.cc += 1*2;
        squareLaw_x.ab += coordL.pixPoines.at(i).first*coordL.pixPoines.at(i).second*2;
        squareLaw_x.ac += coordL.pixPoines.at(i).first*2;
        squareLaw_x.bc += coordL.pixPoines.at(i).second*2;
        squareLaw_x._a += coordL.pixPoines.at(i).first*coordL.physicsPoines.at(i).first*2;
        squareLaw_x._b += coordL.pixPoines.at(i).second*coordL.physicsPoines.at(i).first*2;
        squareLaw_x._c += coordL.physicsPoines.at(i).first*2;
    }

    for(int i=0;i<coordL.pixPoines.count();i++) {
    
    
        squareLaw_y.aa += pow(coordL.pixPoines.at(i).first,2)*2;
        squareLaw_y.bb += pow(coordL.pixPoines.at(i).second,2)*2;
        squareLaw_y.cc += 1*2;
        squareLaw_y.ab += coordL.pixPoines.at(i).first*coordL.pixPoines.at(i).second*2;
        squareLaw_y.ac += coordL.pixPoines.at(i).first*2;
        squareLaw_y.bc += coordL.pixPoines.at(i).second*2;
        squareLaw_y._a += coordL.pixPoines.at(i).first*coordL.physicsPoines.at(i).second*2;
        squareLaw_y._b += coordL.pixPoines.at(i).second*coordL.physicsPoines.at(i).second*2;
        squareLaw_y._c += coordL.physicsPoines.at(i).second*2;
    }

    //求导数  3元方程组系数
    _differentialCoefficient diff_x;
    _differentialCoefficient diff_y;
    diff_x.diff_a.append(squareLaw_x.aa);
    diff_x.diff_a.append(squareLaw_x.ab);
    diff_x.diff_a.append(squareLaw_x.ac);
    diff_x.diff_a.append(squareLaw_x._a);
    diff_x.diff_b.append(squareLaw_x.ab);
    diff_x.diff_b.append(squareLaw_x.bb);
    diff_x.diff_b.append(squareLaw_x.bc);
    diff_x.diff_b.append(squareLaw_x._b);
    diff_x.diff_c.append(squareLaw_x.ac);
    diff_x.diff_c.append(squareLaw_x.bc);
    diff_x.diff_c.append(squareLaw_x.cc);
    diff_x.diff_c.append(squareLaw_x._c);

    diff_y.diff_a.append(squareLaw_y.aa);
    diff_y.diff_a.append(squareLaw_y.ab);
    diff_y.diff_a.append(squareLaw_y.ac);
    diff_y.diff_a.append(squareLaw_y._a);
    diff_y.diff_b.append(squareLaw_y.ab);
    diff_y.diff_b.append(squareLaw_y.bb);
    diff_y.diff_b.append(squareLaw_y.bc);
    diff_y.diff_b.append(squareLaw_y._b);
    diff_y.diff_c.append(squareLaw_y.ac);
    diff_y.diff_c.append(squareLaw_y.bc);
    diff_y.diff_c.append(squareLaw_y.cc);
    diff_y.diff_c.append(squareLaw_y._c);

    //解方程 使用克莱默法则解方程
    //a11​a22​a33​+a12​a23​a31​+a13​a21​a32​ −a13​a22​a31​−a11​a23​a32​−a12​a21​a33​

    double D_x,Da,Db,Dc, D_y,Dd,De,Df;
    D_x = diff_x.diff_a.at(0)*diff_x.diff_b.at(1)*diff_x.diff_c.at(2) + diff_x.diff_a.at(1)*diff_x.diff_b.at(2)*diff_x.diff_c.at(0) +diff_x.diff_a.at(2)*diff_x.diff_b.at(0)*diff_x.diff_c.at(1)
            -diff_x.diff_a.at(2)*diff_x.diff_b.at(1)*diff_x.diff_c.at(0) - diff_x.diff_a.at(0)*diff_x.diff_b.at(2)*diff_x.diff_c.at(1) -diff_x.diff_a.at(1)*diff_x.diff_b.at(0)*diff_x.diff_c.at(2);
    Da = diff_x.diff_a.at(3)*diff_x.diff_b.at(1)*diff_x.diff_c.at(2) + diff_x.diff_a.at(1)*diff_x.diff_b.at(2)*diff_x.diff_c.at(3) +diff_x.diff_a.at(2)*diff_x.diff_b.at(3)*diff_x.diff_c.at(1)
            -diff_x.diff_a.at(2)*diff_x.diff_b.at(1)*diff_x.diff_c.at(3) - diff_x.diff_a.at(3)*diff_x.diff_b.at(2)*diff_x.diff_c.at(1) -diff_x.diff_a.at(1)*diff_x.diff_b.at(3)*diff_x.diff_c.at(2);
    Db = diff_x.diff_a.at(0)*diff_x.diff_b.at(3)*diff_x.diff_c.at(2) + diff_x.diff_a.at(3)*diff_x.diff_b.at(2)*diff_x.diff_c.at(0) +diff_x.diff_a.at(2)*diff_x.diff_b.at(0)*diff_x.diff_c.at(3)
            -diff_x.diff_a.at(2)*diff_x.diff_b.at(3)*diff_x.diff_c.at(0) - diff_x.diff_a.at(0)*diff_x.diff_b.at(2)*diff_x.diff_c.at(3) -diff_x.diff_a.at(3)*diff_x.diff_b.at(0)*diff_x.diff_c.at(2);
    Dc = diff_x.diff_a.at(0)*diff_x.diff_b.at(1)*diff_x.diff_c.at(3) + diff_x.diff_a.at(1)*diff_x.diff_b.at(3)*diff_x.diff_c.at(0) +diff_x.diff_a.at(3)*diff_x.diff_b.at(0)*diff_x.diff_c.at(1)
            -diff_x.diff_a.at(3)*diff_x.diff_b.at(1)*diff_x.diff_c.at(0) - diff_x.diff_a.at(0)*diff_x.diff_b.at(3)*diff_x.diff_c.at(1) -diff_x.diff_a.at(1)*diff_x.diff_b.at(0)*diff_x.diff_c.at(3);
    D_y = diff_y.diff_a.at(0)*diff_y.diff_b.at(1)*diff_y.diff_c.at(2) + diff_y.diff_a.at(1)*diff_y.diff_b.at(2)*diff_y.diff_c.at(0) +diff_y.diff_a.at(2)*diff_y.diff_b.at(0)*diff_y.diff_c.at(1)
            -diff_y.diff_a.at(2)*diff_y.diff_b.at(1)*diff_y.diff_c.at(0) - diff_y.diff_a.at(0)*diff_y.diff_b.at(2)*diff_y.diff_c.at(1) -diff_y.diff_a.at(1)*diff_y.diff_b.at(0)*diff_y.diff_c.at(2);
    Dd = diff_y.diff_a.at(3)*diff_y.diff_b.at(1)*diff_y.diff_c.at(2) + diff_y.diff_a.at(1)*diff_y.diff_b.at(2)*diff_y.diff_c.at(3) +diff_y.diff_a.at(2)*diff_y.diff_b.at(3)*diff_y.diff_c.at(1)
            -diff_y.diff_a.at(2)*diff_y.diff_b.at(1)*diff_y.diff_c.at(3) - diff_y.diff_a.at(3)*diff_y.diff_b.at(2)*diff_y.diff_c.at(1) -diff_y.diff_a.at(1)*diff_y.diff_b.at(3)*diff_y.diff_c.at(2);
    De = diff_y.diff_a.at(0)*diff_y.diff_b.at(3)*diff_y.diff_c.at(2) + diff_y.diff_a.at(3)*diff_y.diff_b.at(2)*diff_y.diff_c.at(0) +diff_y.diff_a.at(2)*diff_y.diff_b.at(0)*diff_y.diff_c.at(3)
            -diff_y.diff_a.at(2)*diff_y.diff_b.at(3)*diff_y.diff_c.at(0) - diff_y.diff_a.at(0)*diff_y.diff_b.at(2)*diff_y.diff_c.at(3) -diff_y.diff_a.at(3)*diff_y.diff_b.at(0)*diff_y.diff_c.at(2);
    Df = diff_y.diff_a.at(0)*diff_y.diff_b.at(1)*diff_y.diff_c.at(3) + diff_y.diff_a.at(1)*diff_y.diff_b.at(3)*diff_y.diff_c.at(0) +diff_y.diff_a.at(3)*diff_y.diff_b.at(0)*diff_y.diff_c.at(1)
            -diff_y.diff_a.at(3)*diff_y.diff_b.at(1)*diff_y.diff_c.at(0) - diff_y.diff_a.at(0)*diff_y.diff_b.at(3)*diff_y.diff_c.at(1) -diff_y.diff_a.at(1)*diff_y.diff_b.at(0)*diff_y.diff_c.at(3);

    _mat mat;
    mat.a = Da/D_x;
    mat.b = Db/D_x;
    mat.c = Dc/D_x;
    mat.d = Dd/D_y;
    mat.e = De/D_y;
    mat.f = Df/D_y;
    mat.g = 0;
    mat.h = 0;
    mat.i = 1;
    return mat;
}

O código completo implementa xxx.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class QTableWidgetItem;
QT_BEGIN_NAMESPACE
namespace Ui {
    
     class MainWindow; }
QT_END_NAMESPACE

//保存从界面获取的坐标数据
struct _coordList{
    
    
    QList<QPair<double,double>> pixPoines;//保存像素坐标
    QList<QPair<double,double>> physicsPoines;//保存物理坐标
};

//保存最小二乘法三个未知量(a,b,c)的结果
struct _squareLaw{
    
    
    double aa=0;
    double bb=0;
    double cc=0;
    double ab=0;
    double ac=0;
    double bc=0;
    double _a=0;
    double _b=0;
    double _c=0;
};
//导数3x4
struct _differentialCoefficient{
    
    
    QList<double> diff_a;
    QList<double> diff_b;
    QList<double> diff_c;
};

//矩阵3X3
struct _mat{
    
    
    double a=0;
    double b=0;
    double c=0;
    double d=0;
    double e=0;
    double f=0;
    double g=0;
    double h=0;
    double i=0;
};

class MainWindow : public QMainWindow
{
    
    
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    _mat calibration(_coordList);//标定

private slots:

    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_tableWidget_itemChanged(QTableWidgetItem *item);

    //void on_tableWidget_itemDoubleClicked(QTableWidgetItem *item);

    void on_pushButton_3_clicked();

private:
    Ui::MainWindow *ui;

    QString old_text;

};
#endif // MAINWINDOW_H

xxx.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTableWidgetItem>
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QFileDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);

    //设置列数
    ui->tableWidget->setColumnCount(4);
    //设置标题
    //表头标题用QStringList来表示
    QStringList headerText;
    headerText<<"像素X坐标"<<"像素Y坐标"<<"物理X坐标"<<"物理Y坐标";
    ui->tableWidget->setHorizontalHeaderLabels(headerText);
    old_text = "";
}

MainWindow::~MainWindow()
{
    
    
    delete ui;
}
//设置n点标定
void MainWindow::on_pushButton_clicked()
{
    
    
    //获取标定的个数
    quint32 transitionCount = ui->spinBox->value();

    int oldRow = ui->tableWidget->rowCount();
    //设置行数
    ui->tableWidget->setRowCount(transitionCount);

    int newRow = ui->tableWidget->rowCount();
    //生成表格,默认值为0
    if(newRow>oldRow) {
    
    
        for(int i = oldRow;i<newRow;i++) {
    
    
            for (int j=0;j<4;j++) {
    
    
                ui->tableWidget->setItem(i,j,new QTableWidgetItem("0"));
            }
        }
    }

}
//标定
_mat MainWindow::calibration(_coordList coordL)
{
    
    
    //保存未知量(a,b,c)的系数
    _squareLaw squareLaw_x;
    _squareLaw squareLaw_y;
    for(int i=0;i<coordL.pixPoines.count();i++) {
    
    
        squareLaw_x.aa += pow(coordL.pixPoines.at(i).first,2)*2;
        squareLaw_x.bb += pow(coordL.pixPoines.at(i).second,2)*2;
        squareLaw_x.cc += 1*2;
        squareLaw_x.ab += coordL.pixPoines.at(i).first*coordL.pixPoines.at(i).second*2;
        squareLaw_x.ac += coordL.pixPoines.at(i).first*2;
        squareLaw_x.bc += coordL.pixPoines.at(i).second*2;
        squareLaw_x._a += coordL.pixPoines.at(i).first*coordL.physicsPoines.at(i).first*2;
        squareLaw_x._b += coordL.pixPoines.at(i).second*coordL.physicsPoines.at(i).first*2;
        squareLaw_x._c += coordL.physicsPoines.at(i).first*2;
    }

    for(int i=0;i<coordL.pixPoines.count();i++) {
    
    
        squareLaw_y.aa += pow(coordL.pixPoines.at(i).first,2)*2;
        squareLaw_y.bb += pow(coordL.pixPoines.at(i).second,2)*2;
        squareLaw_y.cc += 1*2;
        squareLaw_y.ab += coordL.pixPoines.at(i).first*coordL.pixPoines.at(i).second*2;
        squareLaw_y.ac += coordL.pixPoines.at(i).first*2;
        squareLaw_y.bc += coordL.pixPoines.at(i).second*2;
        squareLaw_y._a += coordL.pixPoines.at(i).first*coordL.physicsPoines.at(i).second*2;
        squareLaw_y._b += coordL.pixPoines.at(i).second*coordL.physicsPoines.at(i).second*2;
        squareLaw_y._c += coordL.physicsPoines.at(i).second*2;
    }

    //求导数  3元方程组系数
    _differentialCoefficient diff_x;
    _differentialCoefficient diff_y;
    diff_x.diff_a.append(squareLaw_x.aa);
    diff_x.diff_a.append(squareLaw_x.ab);
    diff_x.diff_a.append(squareLaw_x.ac);
    diff_x.diff_a.append(squareLaw_x._a);
    diff_x.diff_b.append(squareLaw_x.ab);
    diff_x.diff_b.append(squareLaw_x.bb);
    diff_x.diff_b.append(squareLaw_x.bc);
    diff_x.diff_b.append(squareLaw_x._b);
    diff_x.diff_c.append(squareLaw_x.ac);
    diff_x.diff_c.append(squareLaw_x.bc);
    diff_x.diff_c.append(squareLaw_x.cc);
    diff_x.diff_c.append(squareLaw_x._c);

    diff_y.diff_a.append(squareLaw_y.aa);
    diff_y.diff_a.append(squareLaw_y.ab);
    diff_y.diff_a.append(squareLaw_y.ac);
    diff_y.diff_a.append(squareLaw_y._a);
    diff_y.diff_b.append(squareLaw_y.ab);
    diff_y.diff_b.append(squareLaw_y.bb);
    diff_y.diff_b.append(squareLaw_y.bc);
    diff_y.diff_b.append(squareLaw_y._b);
    diff_y.diff_c.append(squareLaw_y.ac);
    diff_y.diff_c.append(squareLaw_y.bc);
    diff_y.diff_c.append(squareLaw_y.cc);
    diff_y.diff_c.append(squareLaw_y._c);

    //解方程 使用克莱默法则解方程
    //a11​a22​a33​+a12​a23​a31​+a13​a21​a32​ −a13​a22​a31​−a11​a23​a32​−a12​a21​a33​

    double D_x,Da,Db,Dc, D_y,Dd,De,Df;
    D_x = diff_x.diff_a.at(0)*diff_x.diff_b.at(1)*diff_x.diff_c.at(2) + diff_x.diff_a.at(1)*diff_x.diff_b.at(2)*diff_x.diff_c.at(0) +diff_x.diff_a.at(2)*diff_x.diff_b.at(0)*diff_x.diff_c.at(1)
            -diff_x.diff_a.at(2)*diff_x.diff_b.at(1)*diff_x.diff_c.at(0) - diff_x.diff_a.at(0)*diff_x.diff_b.at(2)*diff_x.diff_c.at(1) -diff_x.diff_a.at(1)*diff_x.diff_b.at(0)*diff_x.diff_c.at(2);
    Da = diff_x.diff_a.at(3)*diff_x.diff_b.at(1)*diff_x.diff_c.at(2) + diff_x.diff_a.at(1)*diff_x.diff_b.at(2)*diff_x.diff_c.at(3) +diff_x.diff_a.at(2)*diff_x.diff_b.at(3)*diff_x.diff_c.at(1)
            -diff_x.diff_a.at(2)*diff_x.diff_b.at(1)*diff_x.diff_c.at(3) - diff_x.diff_a.at(3)*diff_x.diff_b.at(2)*diff_x.diff_c.at(1) -diff_x.diff_a.at(1)*diff_x.diff_b.at(3)*diff_x.diff_c.at(2);
    Db = diff_x.diff_a.at(0)*diff_x.diff_b.at(3)*diff_x.diff_c.at(2) + diff_x.diff_a.at(3)*diff_x.diff_b.at(2)*diff_x.diff_c.at(0) +diff_x.diff_a.at(2)*diff_x.diff_b.at(0)*diff_x.diff_c.at(3)
            -diff_x.diff_a.at(2)*diff_x.diff_b.at(3)*diff_x.diff_c.at(0) - diff_x.diff_a.at(0)*diff_x.diff_b.at(2)*diff_x.diff_c.at(3) -diff_x.diff_a.at(3)*diff_x.diff_b.at(0)*diff_x.diff_c.at(2);
    Dc = diff_x.diff_a.at(0)*diff_x.diff_b.at(1)*diff_x.diff_c.at(3) + diff_x.diff_a.at(1)*diff_x.diff_b.at(3)*diff_x.diff_c.at(0) +diff_x.diff_a.at(3)*diff_x.diff_b.at(0)*diff_x.diff_c.at(1)
            -diff_x.diff_a.at(3)*diff_x.diff_b.at(1)*diff_x.diff_c.at(0) - diff_x.diff_a.at(0)*diff_x.diff_b.at(3)*diff_x.diff_c.at(1) -diff_x.diff_a.at(1)*diff_x.diff_b.at(0)*diff_x.diff_c.at(3);
    D_y = diff_y.diff_a.at(0)*diff_y.diff_b.at(1)*diff_y.diff_c.at(2) + diff_y.diff_a.at(1)*diff_y.diff_b.at(2)*diff_y.diff_c.at(0) +diff_y.diff_a.at(2)*diff_y.diff_b.at(0)*diff_y.diff_c.at(1)
            -diff_y.diff_a.at(2)*diff_y.diff_b.at(1)*diff_y.diff_c.at(0) - diff_y.diff_a.at(0)*diff_y.diff_b.at(2)*diff_y.diff_c.at(1) -diff_y.diff_a.at(1)*diff_y.diff_b.at(0)*diff_y.diff_c.at(2);
    Dd = diff_y.diff_a.at(3)*diff_y.diff_b.at(1)*diff_y.diff_c.at(2) + diff_y.diff_a.at(1)*diff_y.diff_b.at(2)*diff_y.diff_c.at(3) +diff_y.diff_a.at(2)*diff_y.diff_b.at(3)*diff_y.diff_c.at(1)
            -diff_y.diff_a.at(2)*diff_y.diff_b.at(1)*diff_y.diff_c.at(3) - diff_y.diff_a.at(3)*diff_y.diff_b.at(2)*diff_y.diff_c.at(1) -diff_y.diff_a.at(1)*diff_y.diff_b.at(3)*diff_y.diff_c.at(2);
    De = diff_y.diff_a.at(0)*diff_y.diff_b.at(3)*diff_y.diff_c.at(2) + diff_y.diff_a.at(3)*diff_y.diff_b.at(2)*diff_y.diff_c.at(0) +diff_y.diff_a.at(2)*diff_y.diff_b.at(0)*diff_y.diff_c.at(3)
            -diff_y.diff_a.at(2)*diff_y.diff_b.at(3)*diff_y.diff_c.at(0) - diff_y.diff_a.at(0)*diff_y.diff_b.at(2)*diff_y.diff_c.at(3) -diff_y.diff_a.at(3)*diff_y.diff_b.at(0)*diff_y.diff_c.at(2);
    Df = diff_y.diff_a.at(0)*diff_y.diff_b.at(1)*diff_y.diff_c.at(3) + diff_y.diff_a.at(1)*diff_y.diff_b.at(3)*diff_y.diff_c.at(0) +diff_y.diff_a.at(3)*diff_y.diff_b.at(0)*diff_y.diff_c.at(1)
            -diff_y.diff_a.at(3)*diff_y.diff_b.at(1)*diff_y.diff_c.at(0) - diff_y.diff_a.at(0)*diff_y.diff_b.at(3)*diff_y.diff_c.at(1) -diff_y.diff_a.at(1)*diff_y.diff_b.at(0)*diff_y.diff_c.at(3);

    _mat mat;
    mat.a = Da/D_x;
    mat.b = Db/D_x;
    mat.c = Dc/D_x;
    mat.d = Dd/D_y;
    mat.e = De/D_y;
    mat.f = Df/D_y;
    mat.g = 0;
    mat.h = 0;
    mat.i = 1;
    return mat;
}
//执行标定
void MainWindow::on_pushButton_2_clicked()
{
    
    
    _coordList coordL;
    //获取界面坐标数据
    for(int i=0;i<ui->tableWidget->rowCount();i++) {
    
    
        QPair<double,double> pairPix;
        QPair<double,double> pairPhy;

        for(int j=0;j<4;j++) {
    
    
            switch (j) {
    
    
            case 0:
                pairPix.first = ui->tableWidget->item(i,j)->text().toDouble();
                break;
            case 1:
                pairPix.second = ui->tableWidget->item(i,j)->text().toDouble();
                break;
            case 2:
                pairPhy.first = ui->tableWidget->item(i,j)->text().toDouble();
                break;
            case 3:
                pairPhy.second = ui->tableWidget->item(i,j)->text().toDouble();
                break;
            default:
                break;

            }
        }
        coordL.pixPoines.append(pairPix);
        coordL.physicsPoines.append(pairPhy);
    }
    //执行标定,获取结果
    _mat mat = calibration(coordL);


    //显示标定结果
    ui->textEdit->append(QString::number(mat.a,'e',15)+" , "+QString::number(mat.b,'e',15)+" , "+QString::number(mat.c,'e',15));
    ui->textEdit->append(QString::number(mat.d,'e',15)+" , "+QString::number(mat.e,'e',15)+" , "+QString::number(mat.f,'e',15));
    ui->textEdit->append(QString::number(mat.g)+" , "+QString::number(mat.h)+" , "+QString::number(mat.i));
    ui->textEdit->append("\r\n");

}

//item没有字符时,双击触发
void MainWindow::on_tableWidget_itemChanged(QTableWidgetItem *item)
{
    
    

    //2、匹配正负整数、正负浮点数
    QString Pattern("(-?[1-9][0-9]+)|(-?[0-9])|(-?[1-9]\\d+\\.\\d+)|(-?[0-9]\\.\\d+)");
    QRegExp  reg(Pattern);

    //3.获取修改的新的单元格内容
    QString str=item->text();

    if(str.isEmpty()) {
    
    
        return;
    }
    //匹配失败,返回原来的字符
    if(!reg.exactMatch(str)){
    
    
        QMessageBox::information(this,"匹配失败","请输入小数和整数!");
        item->setText("0");  //更换之前的内容
    }
    //1、记录旧的单元格内容
    old_text = item->text();

}



//打开文件-》从文件读取坐标
void MainWindow::on_pushButton_3_clicked()
{
    
    
    QString fileName = QFileDialog::getOpenFileName(this,tr("文件对话框!"), "",tr("文件(*.csv *.txt)"));
    if(!fileName.isEmpty()) {
    
    
        QFile file(fileName);
        quint32 line=0;
        if(file.open(QIODevice::ReadOnly|QIODevice::Text)) {
    
    
            for (;;) {
    
    
                QString data = file.readLine();
                if(data.isEmpty()) {
    
    
                    QMessageBox::information(this,"完成","数据读取完成!");
                    return;
                }
                QStringList sL = data.split(",");
                if(sL.count()!=4) {
    
    
                    QMessageBox::information(this,"错误","请确定每行数据为4个并且以,分割!");
                    return;
                }
                for(int i=0;i<sL.count();i++) {
    
    
                    bool isOk;
                    sL.at(i).toDouble(&isOk);
                    sL.at(i).toULongLong(&isOk);
                    if(isOk) {
    
    
                        //设置行数
                        ui->tableWidget->setRowCount(line+1);
                        ui->tableWidget->setItem(line,i,new QTableWidgetItem(sL.at(i)));
                    }else {
    
    
                        QMessageBox::information(this,"错误","数据转换double失败!");
                    }
                }

                line++;
            }


        }

    }

}

insira a descrição da imagem aqui

2: Link externo

Método dos mínimos quadrados
Transformação afim
Regra de Cramer
Método de cálculo de determinantes
Matriz de transformação de pontos em sistema de coordenadas 2D

Guess you like

Origin blog.csdn.net/weixin_43763292/article/details/126881396