Qt + halcon混合编程 相机标定

本文档介绍了一个使用Qt5.14和Halcon18开发的图像处理项目,该项目可在Windows和Ubuntu上运行。代码展示了如何根据不同操作系统配置Halcon库,并创建了一个包含图像显示、相机控制、参数调整和标定功能的用户界面。通过Qt的信号槽机制实现了按钮事件处理,如打开图片、打开相机、关闭相机、标定和校正等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.项目环境:Qt 5.14       halcon18      win10/ubuntu20

2.运行效果图:

 

3.创建一个Qt项目,修改项目文件(Qt的跨平台是指代码跨平台,在windows和linux下,需要重新编译运行。并且halcon的库文件在不同系统下也不同。本项目在此处将在不同系统下配置不同的库文件。halcon文件实际上只需要配置头几头也行,xl的配置文件事超尺寸图像,一般用不到。)

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

win32:{
   #halcon配置代码,已经将include、lib拷贝到项目之下
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhalcon
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhalconc
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhalconcpp
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhalconcppxl
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhalconcxl
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhalconxl
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhdevenginecpp
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -lhdevenginecppxl
   LIBS += -L$$PWD/halcon/win/lib/x64-win64/ -llibiomp5md

   #INCLUDEPATH += $$PWD/halcon/win/include
   #DEPENDPATH += $$PWD/halcon/win/include

   INCLUDEPATH += $$PWD/halcon/linux/include
   DEPENDPATH += $$PWD/halcon/linux/include
}


unix:{
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhalcon
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhalconc
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhalconcpp
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhalconcppxl
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux/ -lhalconcxl
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhalconxl
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhdevenginecpp
   LIBS += -L$$PWD/halcon/linux/lib/x64-linux -lhdevenginecppxl

   INCLUDEPATH += $$PWD/halcon/linux/include
   DEPENDPATH += $$PWD/halcon/linux/include
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QStyle>
#include <QFileDialog>
#include <QDebug>
#include <QTabWidget>
#include <QTableWidget>
#include <QHeaderView>
#include <QTableWidgetItem>
#include <QSpinBox>
#include <QLineEdit>
#include <QDoubleSpinBox>
#include <QTimer>
#include <QMessageBox>

#include "halconcpp/HalconCpp.h"
#include "Halcon.h"

using namespace HalconCpp;

#pragma execution_character_set("utf-8") //支持中文

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private:
    void createWidget();

    QTimer *timer;

    QLabel *label_ImageShow;
    QPushButton *btn_OpenImage;

    QPushButton *btn_OpenCamera;
    QPushButton *btn_CloseCamera;


    HTuple  hv_WindowHandle;
    HTuple hv_AcqHandle;
    HObject  ho_Image;
    HTuple  hv_Width, hv_Height;
    Hlong  MainWndID;

    QSpinBox *spinBox_XNum;
    QSpinBox *spinBox_YNum;
    QDoubleSpinBox *doubleSpinBox_MarkDist;
    QDoubleSpinBox *doubleSpinBox_DiameterRatio;

    QPushButton *btn_AddImage;

    QPushButton *btn_RemoveImage;
    QPushButton *btn_Calibration;
    QPushButton *btn_Rectification;
    QPushButton *btn_ClearImage;

    QDoubleSpinBox *doubleSpinBox_FocalDistance;
    QDoubleSpinBox *doubleSpinBox_Kappa;
    QDoubleSpinBox *doubleSpinBox_PixelWidth;
    QDoubleSpinBox *doubleSpinBox_PixelHeight;

    QTableWidget *tableWidget;

    int RowSelected;
    void RefreshTableWidget();
    //标定板参数
    int XNum;
    int YNum;
    double MarkDist;
    double DiameterRatio;
    //相机参数
    double FocalDistance;
    double Kappa;
    double PixelWidth;
    double PixelHeight;

    //
    HObject  ho_Images;
    HTuple hv_Number;

    HTuple  hv_StartCamPar;
    HTuple  hv_CalibDataID;

    void SetCalibCamParam();
    void SetCalibObject();
    void DetectionMark();

    QString detectionResult;

    HTuple  hv_Error, hv_CamParam;
    HObject  ho_ImageMapped, ho_Map;
    bool IsMapIamge;
    HTuple  hv_CameraParameters;

private slots:
    void on_btn_OpenImage_clicked();
    void on_btn_OpenCamera_clicked();
    void on_btn_CloseCamera_clicked();
    void camera();
    void on_btn_AddImage_clicked();
    void on_btn_RemoveImage_clicked();
    void on_btn_Calibration_clicked();
    void on_btn_Rectification_clicked();
    void on_btn_ClearImage_clicked();
    void on_tableCell_clicked(int, int);

    void value0Changed(int);
    void value1Changed(int);
    void value2Changed(double);
    void value3Changed(double);
    void value4Changed(double);
    void value5Changed(double);
    void value6Changed(double);
    void value7Changed(double);

};
#endif // WIDGET_H

widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //初始化数值
    XNum=7;
    YNum=7;
    MarkDist=0.0125;
    DiameterRatio=0.5;
    FocalDistance=0.00385;
    Kappa=0;
    PixelWidth = 0.00000375;
    PixelHeight = 0.00000375;

    detectionResult = "检测失败";
    IsMapIamge = false;

    GenEmptyObj(&ho_Images);

    //初始化一个相机参数
    hv_StartCamPar.Clear();
    hv_StartCamPar[0] = 0.00385;
    hv_StartCamPar[1] = 0;
    hv_StartCamPar[2] = 0.00000375;
    hv_StartCamPar[3] = 0.00000375;
    hv_StartCamPar[4] = 640;
    hv_StartCamPar[5] = 360;
    hv_StartCamPar[6] = 1280;
    hv_StartCamPar[7] = 720;

    //建立一个CalibDataID,该参数相当于标定对象的集合,包含相机标定所需的信息
    CreateCalibData("calibration_object", 1, 1, &hv_CalibDataID);
    SetCalibCamParam();
    SetCalibObject();


    createWidget();

    timer = new QTimer(this);

    connect(btn_OpenImage,SIGNAL(clicked()),this,SLOT(on_btn_OpenImage_clicked()));
    connect(btn_OpenCamera,SIGNAL(clicked()),this,SLOT(on_btn_OpenCamera_clicked()));
    connect(btn_CloseCamera,SIGNAL(clicked()),this,SLOT(on_btn_CloseCamera_clicked()));
    connect(timer,SIGNAL(timeout()),this,SLOT(camera()));
    connect(btn_AddImage,SIGNAL(clicked()),this,SLOT(on_btn_AddImage_clicked()));
    connect(btn_RemoveImage,SIGNAL(clicked()),this,SLOT(on_btn_RemoveImage_clicked()));
    connect(btn_Calibration,SIGNAL(clicked()),this,SLOT(on_btn_Calibration_clicked()));
    connect(btn_Rectification,SIGNAL(clicked()),this,SLOT(on_btn_Rectification_clicked()));
    connect(btn_ClearImage,SIGNAL(clicked()),this,SLOT(on_btn_ClearImage_clicked()));

    //connect(tableWidget, SIGNAL(cellClicked(int, int)), this, SLOT(on_tableCell_clicked(int, int)));
    connect(tableWidget, SIGNAL(cellClicked(int, int)), this, SLOT(on_tableCell_clicked(int, int)));

    connect(spinBox_XNum,SIGNAL(valueChanged(int)),this,SLOT(value0Changed(int)));
    connect(spinBox_YNum,SIGNAL(valueChanged(int)),this,SLOT(value1Changed(int)));
    connect(doubleSpinBox_MarkDist,SIGNAL(valueChanged(double)),this,SLOT(value2Changed(double)));
    connect(doubleSpinBox_DiameterRatio,SIGNAL(valueChanged(double)),this,SLOT(value3Changed(double)));

    connect(doubleSpinBox_FocalDistance,SIGNAL(valueChanged(double)),this,SLOT(value4Changed(double)));
    connect(doubleSpinBox_Kappa,SIGNAL(valueChanged(double)),this,SLOT(value5Changed(double)));
    connect(doubleSpinBox_PixelWidth,SIGNAL(valueChanged(double)),this,SLOT(value6Changed(double)));
    connect(doubleSpinBox_PixelHeight,SIGNAL(valueChanged(double)),this,SLOT(value7Changed(double)));

}

Widget::~Widget()
{
}

void Widget::createWidget(){
    this->setFixedSize(916,547);

    btn_OpenImage = new QPushButton(this);
    btn_OpenImage->setGeometry(350,495,100,40);
    btn_OpenImage->setText("打开图片");


    btn_OpenCamera = new QPushButton(this);
    btn_OpenCamera->setGeometry(630,495,100,40);
    btn_OpenCamera->setText("打开相机");

    btn_CloseCamera = new QPushButton(this);
    btn_CloseCamera->setGeometry(780,495,100,40);
    btn_CloseCamera->setText("关闭相机");

    btn_OpenCamera->setEnabled(true);
    btn_CloseCamera->setEnabled(false);


    label_ImageShow =new QLabel(this);
    label_ImageShow->setGeometry(290,20,611,461);
    MainWndID = (Hlong)this->label_ImageShow->winId();
    SetWindowAttr("background_color","gray");//设置背景为灰色
    OpenWindow(0, 0, label_ImageShow->width(), label_ImageShow->height(), MainWndID,
               "visible", "", &hv_WindowHandle);
    HDevWindowStack::Push(hv_WindowHandle);


    QTabWidget *tabwidget = new QTabWidget(this);
    QWidget *tab0 = new QWidget;
    QWidget *tab1 = new QWidget;
    tabwidget->addTab(tab0, "标定板参数");
    tabwidget->addTab(tab1, "相机初始参数");
    tabwidget->setGeometry(20, 20, 250, 200);
    tabwidget->setTabShape(QTabWidget::Triangular);


    QLabel *label0 = new QLabel(tab0);
    label0->setGeometry(20,20,50,30);
    label0->setText("XNum:");
    label0->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    spinBox_XNum = new QSpinBox(tab0);
    spinBox_XNum->setRange(1,99);
    spinBox_XNum->setValue(7);
    spinBox_XNum->setGeometry(70,20,50,30);


    QLabel *label1 = new QLabel(tab0);
    label1->setGeometry(125,20,50,30);
    label1->setText("YNum:");
    label1->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    spinBox_YNum = new QSpinBox(tab0);
    spinBox_YNum->setRange(1,99);
    spinBox_YNum->setValue(7);
    spinBox_YNum->setGeometry(175,20,50,30);


    QLabel *label2 = new QLabel(tab0);
    label2->setGeometry(20,70,100,30);
    label2->setText("MarkDist:");
    label2->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    //ledit2 = new QLineEdit(tab0);
    //ledit2->setGeometry(120,70,100,30);
    doubleSpinBox_MarkDist = new QDoubleSpinBox(tab0);
    doubleSpinBox_MarkDist->setGeometry(120,70,100,30);
    doubleSpinBox_MarkDist->setRange(0, 1);  // 范围
    doubleSpinBox_MarkDist->setDecimals(4);  // 精度
    doubleSpinBox_MarkDist->setSingleStep(0.0005); // 步长
    doubleSpinBox_MarkDist->setValue(0.0125);  // 当前值
    //doubleSpinBox_MarkDist->setPrefix("$ ");  // 前缀
    doubleSpinBox_MarkDist->setSuffix(" m");  // 后缀
    //doubleSpinBox_MarkDist->setWrapping(true);  // 开启循环
    //doubleSpinBox_MarkDist->setSpecialValueText(tr("Automatic")); // 特殊文本值



    QLabel *label3 = new QLabel(tab0);
    label3->setGeometry(20,110,100,50);
    label3->setText("Diameter\nRatio:");
    label3->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    //ledit3 = new QLineEdit(tab0);
    //ledit3->setGeometry(120,120,100,30);
    doubleSpinBox_DiameterRatio = new QDoubleSpinBox(tab0);
    doubleSpinBox_DiameterRatio->setGeometry(120,120,100,30);
    doubleSpinBox_DiameterRatio->setRange(0, 1);  // 范围
    doubleSpinBox_DiameterRatio->setDecimals(2);  // 精度
    doubleSpinBox_DiameterRatio->setSingleStep(0.05); // 步长
    doubleSpinBox_DiameterRatio->setValue(0.50);  // 当前值
    //doubleSpinBox_MarkDist->setPrefix("$ ");  // 前缀
    //doubleSpinBox_DiameterRatio->setSuffix(" m");  // 后缀

    //
    QLabel *label4 = new QLabel(tab1);
    label4->setGeometry(20,10,100,30);
    label4->setText("镜头焦距:");
    label4->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    doubleSpinBox_FocalDistance = new QDoubleSpinBox(tab1);
    doubleSpinBox_FocalDistance->setGeometry(120,10,100,30);
    doubleSpinBox_FocalDistance->setRange(0, 1000);  // 范围
    doubleSpinBox_FocalDistance->setDecimals(2);  // 精度
    doubleSpinBox_FocalDistance->setSingleStep(0.05); // 步长
    doubleSpinBox_FocalDistance->setValue(3.85);  // 当前值
    doubleSpinBox_FocalDistance->setSuffix(" mm");  // 后缀

    QLabel *label5 = new QLabel(tab1);
    label5->setGeometry(20,50,100,30);
    label5->setText("畸变系数:");
    label5->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    doubleSpinBox_Kappa = new QDoubleSpinBox(tab1);
    doubleSpinBox_Kappa->setGeometry(120,50,100,30);
    doubleSpinBox_Kappa->setRange(-9999, 9999);  // 范围
    doubleSpinBox_Kappa->setDecimals(2);  // 精度
    doubleSpinBox_Kappa->setSingleStep(0.05); // 步长
    doubleSpinBox_Kappa->setValue(0);  // 当前值
    doubleSpinBox_Kappa->setSuffix(" m^-2");  // 后缀

    QLabel *label6 = new QLabel(tab1);
    label6->setGeometry(20,90,100,30);
    label6->setText("单个像元的宽:");
    label6->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    doubleSpinBox_PixelWidth = new QDoubleSpinBox(tab1);
    doubleSpinBox_PixelWidth->setGeometry(120,90,100,30);
    doubleSpinBox_PixelWidth->setRange(0, 1000);  // 范围
    doubleSpinBox_PixelWidth->setDecimals(2);  // 精度
    doubleSpinBox_PixelWidth->setSingleStep(0.01); // 步长
    doubleSpinBox_PixelWidth->setValue(3.75);  // 当前值
    doubleSpinBox_PixelWidth->setSuffix(" μm");  // 后缀
    \

    QLabel *label7 = new QLabel(tab1);
    label7->setGeometry(20,130,100,30);
    label7->setText("单个像元的高:");
    label7->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    doubleSpinBox_PixelHeight = new QDoubleSpinBox(tab1);
    doubleSpinBox_PixelHeight->setGeometry(120,130,100,30);
    doubleSpinBox_PixelHeight->setRange(0, 1000);  // 范围
    doubleSpinBox_PixelHeight->setDecimals(2);  // 精度
    doubleSpinBox_PixelHeight->setSingleStep(0.01); // 步长
    doubleSpinBox_PixelHeight->setValue(3.75);  // 当前值
    doubleSpinBox_PixelHeight->setSuffix(" μm");  // 后缀



    btn_AddImage = new QPushButton(this);
    btn_AddImage->setGeometry(20,235,30,30);
    btn_AddImage->setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton));
    btn_RemoveImage = new QPushButton(this);
    btn_RemoveImage->setGeometry(60,235,30,30);
    btn_RemoveImage->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
    btn_RemoveImage->setEnabled(false);
    btn_ClearImage = new QPushButton(this);
    btn_ClearImage->setGeometry(100,235,30,30);
    btn_ClearImage->setIcon(style()->standardIcon(QStyle::SP_DialogResetButton));
    //btn_ClearImage->setEnabled(false);

    btn_Calibration = new QPushButton(this);
    btn_Calibration->setGeometry(150,235,50,30);
    btn_Calibration->setText("标定");

    btn_Rectification = new QPushButton(this);
    btn_Rectification->setGeometry(220,235,50,30);
    btn_Rectification->setText("校正");
    //btn_Rectification->setEnabled(false);

    //QTableWidget *tableWidget = new QTableWidget(this);
    tableWidget = new QTableWidget(this);
    tableWidget->setRowCount(0);
    tableWidget->setColumnCount(2);
    //page2->addWidget();
    tableWidget->setGeometry(20,280,250,200);
    //tableWidget->resizeColumnsToContents();
    //tableWidget->resizeRowsToContents();
    //tableWidget->setColumnWidth(3,200);

    //tableWidget->setRowHeight(3,60);

    //tableWidget->setColumnWidth(0,100);
    //tableWidget->setColumnWidth(1,140);
    tableWidget->verticalHeader()->setVisible(false); //隐藏列表头
    //tableWidget->horizontalHeader()->setVisible(false); //隐藏行表头
    tableWidget->setSelectionBehavior ( QAbstractItemView::SelectRows); //设置选择行为,以行为单位
    tableWidget->setSelectionMode ( QAbstractItemView::SingleSelection); //设置选择模式,选择单行
    //tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//单元格不可编辑
    //tableWidget->horizontalHeader()->setResizeMode( ResizeMode mode )
    tableWidget->horizontalHeader()->setSectionResizeMode(0,QHeaderView::ResizeToContents);
    tableWidget->horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch);

    tableWidget->show();
    QStringList headerText;
    headerText<<"序号"<<"结果";
    tableWidget->setHorizontalHeaderLabels(headerText);
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tableWidget->horizontalHeader()->setDisabled(true);//禁止用户拖动改变列宽
    tableWidget->verticalHeader()->setDisabled(true);//设置行不能拖动

}

void Widget::on_btn_OpenImage_clicked(){
    qDebug() << "按下了0号按钮,读取图片";
    ClearWindow(hv_WindowHandle);
    QString file_name = QFileDialog::getOpenFileName(this,tr("open  file"),"."
    ,tr("Video Files(*.bmp *.jpg *.pbm *.pgm *.png *.ppm *.xbm *.xpm *.jpeg)"));
    try
    {
        ReadImage(&ho_Image,file_name.toLatin1().data());
        if(!IsMapIamge){
            //ReadImage(&ho_Image,file_name.toLatin1().data());
            GetImageSize(ho_Image, &hv_Width, &hv_Height);
            SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);

            if (HDevWindowStack::IsOpen())
            {
                ClearWindow(HDevWindowStack::GetActive());
                DispObj(ho_Image, HDevWindowStack::GetActive());
            }

            //DispObj(ho_Image, HDevWindowStack::GetActive());
            SetCalibCamParam();
            DetectionMark();

        }else{
            //ReadImage(&ho_Image,file_name.toLatin1().data());

            GetImageSize(ho_Image, &hv_Width, &hv_Height);
            SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);
            MapImage(ho_Image, ho_Map, &ho_ImageMapped);
            if(HDevWindowStack::IsOpen())
            {
                DispObj(ho_Image,HDevWindowStack::GetActive());
            }

        }

    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
        //qDebug() << "0";
    }



}

void Widget::on_btn_OpenCamera_clicked(){
    qDebug() << "按下了1号按钮,打开相机";
    //qle->setText("打开相机");
    ClearWindow(hv_WindowHandle);
    timer->start(20);//定时器开始工作,参数影响帧率
    try
    {
        OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false",
                         "default", "[0]", 0, -1, &hv_AcqHandle);//只会打开序号0的相机,修改"[0]",改变连接上的相机
        GrabImageStart(hv_AcqHandle, -1);
        //在openwindow前先抓取一帧图片
        GrabImage(&ho_Image, hv_AcqHandle);
        GetImageSize(ho_Image, &hv_Width, &hv_Height);
        btn_CloseCamera->setEnabled(true);
        btn_OpenCamera->setEnabled(false);
        btn_OpenImage->setEnabled(false);
        SetCalibCamParam();
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }
}

void Widget::on_btn_CloseCamera_clicked(){
    qDebug() << "按下了2号按钮,关闭相机";
    //qle->setText("关闭相机");
    timer->stop();
    CloseFramegrabber(hv_AcqHandle);
    ClearWindow(hv_WindowHandle);
    btn_CloseCamera->setEnabled(false);
    btn_OpenCamera->setEnabled(true);
    btn_OpenImage->setEnabled(true);
}

void Widget::camera()
{
    if(!IsMapIamge){
        GrabImage(&ho_Image, hv_AcqHandle);
        GetImageSize(ho_Image, &hv_Width, &hv_Height);
        SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);
        if(HDevWindowStack::IsOpen())
        {
            DispObj(ho_Image,HDevWindowStack::GetActive());
        }
        //WaitSeconds(0.1);
        DetectionMark();

    }else{
        GrabImage(&ho_Image, hv_AcqHandle);

        GetImageSize(ho_Image, &hv_Width, &hv_Height);
        SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);
        MapImage(ho_Image, ho_Map, &ho_ImageMapped);
        if(HDevWindowStack::IsOpen())
        {
            DispObj(ho_ImageMapped,HDevWindowStack::GetActive());
        }
    }


}

void Widget::on_btn_AddImage_clicked(){
    qDebug() << "按下了3号按钮,添加图像";
    try
    {
        ConcatObj(ho_Images, ho_Image, &ho_Images);
        CountObj(ho_Images, &hv_Number);
        tableWidget->setRowCount(hv_Number.I());//hv_Number[0].I()
        QTableWidgetItem *item0 = new QTableWidgetItem(QString::number(hv_Number.I()-1));
        item0->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
        tableWidget->setItem(hv_Number.I()-1, 0, item0);

        QTableWidgetItem *item1 = new QTableWidgetItem(QString(detectionResult));
        item1->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
        tableWidget->setItem(hv_Number.I()-1, 1, item1);

        CountObj(ho_Images, &hv_Number);

    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }

}
void Widget::on_btn_RemoveImage_clicked(){
    qDebug() << "移除图像";
    //qDebug() <<"RowSelected:"<<RowSelected;
    try
    {
        RemoveObj(ho_Images, &ho_Images, RowSelected+1);
        tableWidget->removeRow(RowSelected);
        //(RowSelected+1).toLatin1().data()
        btn_RemoveImage->setEnabled(false);
        RefreshTableWidget();
        CountObj(ho_Images, &hv_Number);
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }
}
void Widget::on_btn_Calibration_clicked(){
    qDebug() << "标定";
    //GenCaltab(7, 7, 0.0125, 0.5, "caltab.descr", "caltab.ps");
    ClearCalibData(hv_CalibDataID);
    //建立一个CalibDataID,该参数相当于标定对象的集合,包含相机标定所需的信息
    CreateCalibData("calibration_object", 1, 1, &hv_CalibDataID);
    SetCalibCamParam();
    SetCalibObject();
    try {
        qDebug()<<"hv_Number"<<hv_Number.I();
        for (int i = 0;i < hv_Number;i++) {
             FindCalibObject(ho_Image, hv_CalibDataID, 0, 0, HTuple(i+1), HTuple(), HTuple());
             //获得标定板外框轮廓
             HObject ho_Caltab;
             GetCalibDataObservContours(&ho_Caltab, hv_CalibDataID, "caltab", 0, 0, HTuple(i+1));
             //获取标定板标志轮廓
             HObject ho_Marks;
             GetCalibDataObservContours(&ho_Marks, hv_CalibDataID, "marks", 0, 0, HTuple(i+1));
        }
        //qDebug()<<"123";
        CalibrateCameras(hv_CalibDataID, &hv_Error);
        GetCalibData(hv_CalibDataID, "camera", 0, "params", &hv_CamParam);
        qDebug()<<"标定成功";
        //GetCalibData(hv_CalibDataID, "calib_obj_pose", (HTuple(0).Append(1)), "pose", &hv_Pose);
        //btn_Rectification->setEnabled(true);

        //clear_calib_data (hv_CalibDataID);

    } catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
        qDebug()<<"标定失败";
        QMessageBox::warning(this,"消息","标记失败");
        //btn_Rectification->setEnabled(false);
    }
}
void Widget::on_btn_Rectification_clicked(){
    qDebug() << "校正";
    try {
    //CameraParameters为相机的内部参数
    //HTuple  hv_CameraParameters;
    hv_CameraParameters = hv_CamParam.TupleSelectRange(1,8);
    HTuple  hv_CarParamVirtualFixed;
    ChangeRadialDistortionCamPar("adaptive", hv_CameraParameters, 0, &hv_CarParamVirtualFixed);
    GenRadialDistortionMap(&ho_Map, hv_CameraParameters, hv_CarParamVirtualFixed, "bilinear");
    //MapImage(ho_Image, ho_Map, &ho_ImageMapped);、
    //CountObj(hv_CameraParameters, &hv_Number);hv_CameraParameters
    qDebug() << "校正成功";
    for (int i=0;i<8;i++) {
        double param = hv_CameraParameters[i].D();
        qDebug()<<param;
    }
    IsMapIamge = !IsMapIamge;
    if(IsMapIamge){
        btn_Rectification->setText("已校");
    }else{
        btn_Rectification->setText("校正");
    }
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
        qDebug() << "校正失败";
        //QMessageBox::information(this,"消息","校正失败");
        QMessageBox::warning(this,"消息","校正失败");
    }


    try
    {
        if(!IsMapIamge){
            GetImageSize(ho_Image, &hv_Width, &hv_Height);
            SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);

            if (HDevWindowStack::IsOpen())
            {
                ClearWindow(HDevWindowStack::GetActive());
                DispObj(ho_Image, HDevWindowStack::GetActive());
            }

            //DispObj(ho_Image, HDevWindowStack::GetActive());
            SetCalibCamParam();
            DetectionMark();

        }else{
            GetImageSize(ho_Image, &hv_Width, &hv_Height);
            SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);
            MapImage(ho_Image, ho_Map, &ho_ImageMapped);
            if(HDevWindowStack::IsOpen())
            {
                DispObj(ho_ImageMapped,HDevWindowStack::GetActive());
            }

        }
     }catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }

}
void Widget::on_btn_ClearImage_clicked(){
    qDebug() << "按下了7号按钮,清空表格";
    tableWidget->clearContents();
    //imageNum=0;
    ho_Images.Clear();
    //ho_Images被清空后需要重新初始化
    GenEmptyObj(&ho_Images);
    CountObj(ho_Images, &hv_Number);

    tableWidget->setRowCount(hv_Number.I());
    qDebug() << "hv_Number:"<<hv_Number.I();
}
void Widget::on_tableCell_clicked(int row, int col){
    qDebug() << "按下了talbleCell第"<<row<<"行";
    btn_RemoveImage->setEnabled(true);
    RowSelected = row;
}

void Widget::RefreshTableWidget(){
    qDebug() << "刷新tableWiget序号";
    for(int i = 0;i<tableWidget->rowCount();i++){
        QTableWidgetItem *item0 = new QTableWidgetItem(QString::number(i));
        item0->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
        tableWidget->setItem(i, 0, item0);
    }
}

void Widget::value0Changed(int value){
    qDebug() << "参数0:"<<value;
    XNum=value;
    qDebug()<<"XNum"<<XNum;
    SetCalibObject();
}
void Widget::value1Changed(int value){
    qDebug() << "参数1:"<<value;
    YNum=value;
    qDebug()<<"YNum"<<YNum;
    SetCalibObject();
}
void Widget::value2Changed(double value){
    qDebug() << "参数2:"<<value;
    MarkDist=value;
    qDebug()<<"MarkDist"<<MarkDist;
    SetCalibObject();
}
void Widget::value3Changed(double value){
    qDebug() << "参数3:"<<value;
    DiameterRatio=value;
    qDebug()<<"DiameterRatio"<<DiameterRatio;
    SetCalibObject();
}
void Widget::value4Changed(double value){
    qDebug() << "参数4:"<<value;
    FocalDistance=value/1000;
    hv_StartCamPar[0] = HTuple(FocalDistance);
    qDebug()<<"FocalDistance"<<FocalDistance;
    SetCalibCamParam();
}
void Widget::value5Changed(double value){
    qDebug() << "参数5:"<<value;
    Kappa=value;
    hv_StartCamPar[1] = HTuple(Kappa);
    qDebug()<<"Kappa"<<Kappa;
    SetCalibCamParam();
}
void Widget::value6Changed(double value){
    qDebug() << "参数6:"<<value;
    PixelWidth=value/1000000;
    hv_StartCamPar[2] = HTuple(PixelWidth);
    qDebug()<<"PixelWidth"<<PixelWidth;
    SetCalibCamParam();
}
void Widget::value7Changed(double value){
    qDebug() << "参数7:"<<value;
    PixelHeight=value/1000000;
    hv_StartCamPar[3] = HTuple(PixelHeight);
    qDebug()<<"PixelHeight"<<PixelHeight;
    SetCalibCamParam();
}

void Widget::SetCalibCamParam(){
    try {
        hv_StartCamPar[4] = hv_Width/2;
        hv_StartCamPar[5] = hv_Height/2;
        hv_StartCamPar[6] = hv_Width;
        hv_StartCamPar[7] = hv_Height;
        //设置相机的类型
        SetCalibDataCamParam(hv_CalibDataID, 0, "area_scan_division", hv_StartCamPar);
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }
}

void Widget::SetCalibObject(){
    try {
        //生成设置标定板文件
        GenCaltab(HTuple(XNum), HTuple(YNum), HTuple(MarkDist), HTuple(DiameterRatio),
                  "caltab.descr", "caltab.ps");
        //读取标定板信息
        SetCalibDataCalibObject(hv_CalibDataID, 0, "caltab.descr");
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }

}

void Widget::DetectionMark(){
    try {
        //寻找标定板
        FindCalibObject(ho_Image, hv_CalibDataID, 0, 0, 0, HTuple(), HTuple());
        //获得标定板外框轮廓
        HObject ho_Caltab;
        //GetCalibDataObservContours (Caltab, hv_CalibDataID, 'caltab', 0, 0, 1);
        GetCalibDataObservContours(&ho_Caltab, hv_CalibDataID, "caltab", 0, 0, 0);
        //获取标定板标志轮廓
        HObject ho_Marks;
        GetCalibDataObservContours(&ho_Marks, hv_CalibDataID, "marks", 0, 0, 0);
        //ClearWindow(HDevWindowStack::GetActive());
        if (HDevWindowStack::IsOpen())
        {
            SetColor(HDevWindowStack::GetActive(),"blue");
            SetLineWidth(HDevWindowStack::GetActive(),4);
            //DispObj(ho_Image, HDevWindowStack::GetActive());
            //显示标定板外框轮廓
            DispObj(ho_Caltab, HDevWindowStack::GetActive());
            //显示标志版标志轮廓
            DispObj(ho_Marks, HDevWindowStack::GetActive());
            //SetTposition(hv_WindowHandle, 20, 20);
            SetTposition(HDevWindowStack::GetActive(), 20, 20);
            //SetFont(hv_WindowHandle, 5);
            HTuple  hv_Font, hv_FontWithSize;
            //QueryFont(hv_WindowHandle, &hv_Font);
            QueryFont(HDevWindowStack::GetActive(), &hv_Font);
            //Specify font name and size
            hv_FontWithSize = HTuple(hv_Font[0])+"-20";
            //SetFont(hv_WindowHandle, hv_FontWithSize);
            SetFont(HDevWindowStack::GetActive(), hv_FontWithSize);
            //WriteString(hv_WindowHandle, "检测到标定信息");
            WriteString(HDevWindowStack::GetActive(), "检测到标定信息");

        }
        detectionResult = "检测成功";
    } catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
        //qDebug() << "1";
        SetColor(HDevWindowStack::GetActive(),"red");
        SetTposition(HDevWindowStack::GetActive(), 20, 20);
        //SetFont(hv_WindowHandle, 5);
        HTuple  hv_Font, hv_FontWithSize;
        //QueryFont(hv_WindowHandle, &hv_Font);
        QueryFont(HDevWindowStack::GetActive(), &hv_Font);
        //Specify font name and size
        hv_FontWithSize = HTuple(hv_Font[0])+"-20";
        //SetFont(hv_WindowHandle, hv_FontWithSize);
        //DispObj(ho_Image, HDevWindowStack::GetActive());
        SetFont(HDevWindowStack::GetActive(), hv_FontWithSize);
        WriteString(HDevWindowStack::GetActive(), "未检测标定信息");
        //表格信息error
        detectionResult = "检测失败";
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值