Qt + halcon MLP分类器

15 篇文章 6 订阅
9 篇文章 5 订阅

1.项目目的:1.halcon实现图像的MLP分类器 2.Qt作界面

2.项目环境:Qt5.14       halcon18         Win10

3.运行结果图

 

 

4.创建一个新的Qt项目

 项目配置文件halcon_mlp.pro

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 += \
    MLP.cpp \
    main.cpp \
    widget.cpp

HEADERS += \
    MLP.h \
    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
}

MLP.h

#ifndef MLP_H
#define MLP_H
#include "halconcpp/HalconCpp.h"
#include "Halcon.h"
using namespace HalconCpp;

class MLP
{
public:
    static void gen_features (HObject ho_Image, HTuple *hv_FeatureVector);
    static void gen_sobel_features (HObject ho_Image, HTuple hv_Features, HTuple *hv_FeaturesExtended);
};

#endif // MLP_H

MLP.cpp

#include "MLP.h"

void MLP::gen_sobel_features(HObject ho_Image, HTuple hv_Features, HTuple *hv_FeaturesExtended){
    // Local iconic variables
      HObject  ho_EdgeAmplitude;

      // Local control variables
      HTuple  hv_Energy, hv_Correlation, hv_Homogeneity;
      HTuple  hv_Contrast, hv_AbsoluteHistoEdgeAmplitude;

      //Coocurrence matrix for 90 deg:
      CoocFeatureImage(ho_Image, ho_Image, 6, 90, &hv_Energy, &hv_Correlation, &hv_Homogeneity,
          &hv_Contrast);
      //Absolute histogram of edge amplitudes:
      SobelAmp(ho_Image, &ho_EdgeAmplitude, "sum_abs", 3);
      GrayHistoAbs(ho_EdgeAmplitude, ho_EdgeAmplitude, 8, &hv_AbsoluteHistoEdgeAmplitude);
      //
      //You could of course compute more features:
      //Entropy and anisotropy:
      //entropy_gray (Image, Image, Entropy, Anisotropy)
      //Absolute histogram of gray values:
      //gray_histo_abs (Image, Image, 8, AbsoluteHistoImage)
      //Add features to feature vector:
      (*hv_FeaturesExtended).Clear();
      (*hv_FeaturesExtended).Append(hv_Features);
      (*hv_FeaturesExtended).Append(hv_Energy);
      (*hv_FeaturesExtended).Append(hv_Correlation);
      (*hv_FeaturesExtended).Append(hv_Homogeneity);
      (*hv_FeaturesExtended).Append(hv_Contrast);
      (*hv_FeaturesExtended) = (*hv_FeaturesExtended).TupleConcat(hv_AbsoluteHistoEdgeAmplitude);
      //Activate the following lines to add the additional features you activated:
      //FeaturesExtended := [FeaturesExtended,Entropy,Anisotropy]
      //FeaturesExtended := [FeaturesExtended,AbsoluteHistoImage]
      return;
}

void MLP::gen_features(HObject ho_Image, HTuple *hv_FeatureVector){
    // Local iconic variables
      HObject  ho_Zoomed1;

      (*hv_FeatureVector) = HTuple();
      //Compute features.
      gen_sobel_features(ho_Image, (*hv_FeatureVector), &(*hv_FeatureVector));
      //Downscale the image (image pyramid) and compute features.
      ZoomImageFactor(ho_Image, &ho_Zoomed1, 0.5, 0.5, "constant");
      gen_sobel_features(ho_Zoomed1, (*hv_FeatureVector), &(*hv_FeatureVector));
      //Uncomment lines to use further pyramid levels:
      //zoom_image_factor (Zoomed1, Zoomed2, 0.5, 0.5, 'constant')
      //gen_sobel_features (Zoomed2, FeatureVector, FeatureVector)
      //zoom_image_factor (Zoomed2, Zoomed3, 0.5, 0.5, 'constant')
      //gen_sobel_features (Zoomed3, FeatureVector, FeatureVector)
      //zoom_image_factor (Zoomed3, Zoomed4, 0.5, 0.5, 'constant')
      //gen_sobel_features (Zoomed4, FeatureVector, FeatureVector)
      (*hv_FeatureVector) = (*hv_FeatureVector).TupleReal();
      return;
}

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 <QMessageBox>
#include <QTimer>
#include <QMouseEvent>
#include <QLineEdit>

#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;

    QPushButton *btn_ROI;

    bool DrawROI;

    QSpinBox *spinBox_classNo;
    QSpinBox *spinBox_classNum;
    QPushButton *btn_classNum;
    QPushButton *btn_AddImg;
    QPushButton *btn_TrainMLP;
    QPushButton *btn_Classify;

    QTableWidget *tableWidget;


    QPoint SPoint;
    QPoint EPoint;

    QPoint sPoint;
    QPoint ePoint;
    HObject ROIContour;
    HTuple  hv_rows, hv_cols;

    HObject ho_ImageReduced;
    HObject ho_Rectangle;

    HObject  ho_Images;
    HTuple  hv_Index;
    HTuple  hv_MLPHandle;
    HTuple hv_NumClasses;
    bool isClassify;//是否识别
    void Classify();
private slots:
    void on_btn_OpenImage_clicked();
    void on_btn_OpenCamera_clicked();
    void on_btn_CloseCamera_clicked();
    void camera();
    void on_btn_ROI_clicked();
    void on_btn_AddImg_clicked();
    void on_btn_classNum_clicked();
    void on_btn_TrainMLP_clicked();
    void on_btn_Classify_clicked();


protected:

    void mousePressEvent(QMouseEvent * e);
    void mouseMoveEvent(QMouseEvent * e);
    void mouseReleaseEvent(QMouseEvent * e);


};
#endif // WIDGET_H

Widget.cpp

#include "widget.h"
#include "MLP.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    createWidget();
    timer = new QTimer(this);
    DrawROI = false;
    GenEmptyObj(&ho_Images);
    hv_Index = HTuple();
    isClassify = false;

    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_ROI,SIGNAL(clicked()),this,SLOT(on_btn_ROI_clicked()));
    connect(btn_AddImg,SIGNAL(clicked()),this,SLOT(on_btn_AddImg_clicked()));
    connect(btn_classNum,SIGNAL(clicked()),this,SLOT(on_btn_classNum_clicked()));
    connect(btn_Classify,SIGNAL(clicked()),this,SLOT(on_btn_Classify_clicked()));
    connect(btn_TrainMLP,SIGNAL(clicked()),this,SLOT(on_btn_TrainMLP_clicked()));

}

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, "参数0");
    tabwidget->addTab(tab1, "参数1");

    tabwidget->setGeometry(20, 20, 250, 462);
    tabwidget->setTabShape(QTabWidget::Triangular);


    btn_ROI = new QPushButton(tab0);
    btn_ROI->setGeometry(70,20,100,30);
    btn_ROI->setText("设置ROI");

    QLabel *label0 = new QLabel(tab0);
    label0->setGeometry(20,70,80,30);
    label0->setText("种类数:");
    label0->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    spinBox_classNum = new QSpinBox(tab0);
    spinBox_classNum->setRange(1,99);
    spinBox_classNum->setValue(1);
    spinBox_classNum->setGeometry(100,70,50,30);
    btn_classNum =new QPushButton(tab0);
    btn_classNum->setGeometry(160,70,50,30);
    btn_classNum->setText("确认");


    QLabel *label1 = new QLabel(tab0);
    label1->setGeometry(20,120,80,30);
    label1->setText("类别编号:");
    label1->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
    spinBox_classNo = new QSpinBox(tab0);
    //spinBox_classNo->setRange(0,99);
    spinBox_classNo->setValue(0);
    spinBox_classNo->setGeometry(100,120,50,30);
    //禁用,待种类数确认后改可用
    spinBox_classNo->setEnabled(false);
    btn_AddImg =new QPushButton(tab0);
    btn_AddImg->setGeometry(160,120,50,30);
    btn_AddImg->setText("添加");
    //禁用,待种类数确认后改可用
    btn_AddImg->setEnabled(false);

    btn_TrainMLP = new QPushButton(tab0);
    btn_TrainMLP->setGeometry(50,170,150,30);
    btn_TrainMLP->setText("训练神经网络");

    btn_Classify = new QPushButton(tab0);
    btn_Classify->setGeometry(50,220,150,30);
    btn_Classify->setText("识别图像");



    tableWidget = new QTableWidget(tab0);
    tableWidget->setRowCount(0);
    tableWidget->setColumnCount(3);
    //page2->addWidget();
    tableWidget->setGeometry(0,250,244,187);
    tableWidget->verticalHeader()->setVisible(false); //隐藏列表头
    //tableWidget->horizontalHeader()->setVisible(false); //隐藏行表头
    //tableWidget->setSelectionBehavior ( QAbstractItemView::SelectRows); //设置选择行为,以行为单位
    //tableWidget->setSelectionMode ( QAbstractItemView::SingleSelection); //设置选择模式,选择单行
    tableWidget->horizontalHeader()->setSectionResizeMode(0,QHeaderView::ResizeToContents);
    //tableWidget->horizontalHeader()->setSectionResizeMode(1,QHeaderView::ResizeToContents);
    tableWidget->setColumnWidth(1, 70);

    tableWidget->horizontalHeader()->setSectionResizeMode(2,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() << "读取图片";
    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());
        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());
        }
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
        //qDebug() << "0";
    }
}

void Widget::on_btn_OpenCamera_clicked(){
    qDebug() << "打开相机";
    //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);
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }
}

void Widget::on_btn_CloseCamera_clicked(){
    qDebug() << "关闭相机";
    //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()
{
    try {
        GrabImage(&ho_Image, hv_AcqHandle);
        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());
        }
        if(DrawROI){
            //ClearWindow(hv_WindowHandle);
            SetColor(HDevWindowStack::GetActive(),"green");
            SetLineWidth(HDevWindowStack::GetActive(),4);
            DispObj(ROIContour,HDevWindowStack::GetActive());
            GenRectangle1(&ho_Rectangle, sPoint.y(), sPoint.x(), ePoint.y(), ePoint.x());
            //对ROI区域进行裁剪
            ReduceDomain(ho_Image, ho_Rectangle, &ho_ImageReduced);
            //qDebug()<<"成功截取感兴趣区域";
            //
            if(isClassify){
                Classify();
            }
        }
    }
    catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }
}

void Widget::on_btn_ROI_clicked()
{
    DrawROI = !DrawROI;
    qDebug() << "DrawROI"<<QString::number(DrawROI);
    ClearWindow(HDevWindowStack::GetActive());

    if(DrawROI){
        btn_ROI->setText("取消ROI");
        try
        {
            if (HDevWindowStack::IsOpen()){
                SetColor(HDevWindowStack::GetActive(),"green");
                SetLineWidth(HDevWindowStack::GetActive(),4);
                DispObj(ho_Image, HDevWindowStack::GetActive());
                DispObj(ROIContour,HDevWindowStack::GetActive());
                GenRectangle1(&ho_Rectangle, sPoint.y(), sPoint.x(), ePoint.y(), ePoint.x());
                //对ROI区域进行裁剪
                ReduceDomain(ho_Image, ho_Rectangle, &ho_ImageReduced);
                qDebug()<<"成功截取感兴趣区域";
            }
        }catch (HException &HDevExpDefaultException)
        {
            HTuple  hv_Exception;
            HDevExpDefaultException.ToHTuple(&hv_Exception);
            qDebug() <<"错误";
        }
    }
    else{
        btn_ROI->setText("设置ROI");
        try {
            if (HDevWindowStack::IsOpen()){
                DispObj(ho_Image, HDevWindowStack::GetActive());
            }
        } catch (HException &HDevExpDefaultException)
        {
            HTuple  hv_Exception;
            HDevExpDefaultException.ToHTuple(&hv_Exception);
            qDebug() <<"错误";
        }
    }

}


//鼠标 点击
void Widget::mousePressEvent(QMouseEvent *e)
{
    //获取点击的下标
    if(DrawROI){
        if(label_ImageShow->geometry().contains(this->mapFromGlobal(QCursor::pos())) //鼠标是否在界面上
                    &&e->button()==Qt::LeftButton)
        {
            qDebug() << "左键" ;
            SPoint.setX(e->x());
            SPoint.setY(e->y());
            qDebug() <<"SX:"<< SPoint.x();
            qDebug() <<"SY:"<< SPoint.y();
        }

    }

}

//鼠标 移动
void Widget::mouseMoveEvent(QMouseEvent * e)
{
    if(DrawROI){
        if(label_ImageShow->geometry().contains(this->mapFromGlobal(QCursor::pos())))//鼠标是否在界面上
        {
            qDebug() << "左键位置移动到" ;
            EPoint.setX(e->x());
            EPoint.setY(e->y());
            qDebug() <<"EX:"<< SPoint.x();
            qDebug() <<"EY:"<< SPoint.y();
        }


        double scale_x;
        double scale_y;

        try
        {

            GetImageSize(ho_Image, &hv_Width, &hv_Height);
            scale_x = (double)hv_Width / label_ImageShow->width();
            scale_y = (double)hv_Height / label_ImageShow->height();


            sPoint.setX((SPoint.x()-label_ImageShow->geometry().x())*scale_x);
            sPoint.setY((SPoint.y()-label_ImageShow->geometry().y())*scale_y);

            qDebug() <<"sX:"<< sPoint.x();
            qDebug() <<"sY:"<< sPoint.y();

            ePoint.setX((EPoint.x()-label_ImageShow->geometry().x())*scale_x);
            ePoint.setY((EPoint.y()-label_ImageShow->geometry().y())*scale_y);

            qDebug() <<"eX:"<< ePoint.x();
            qDebug() <<"eY:"<< ePoint.y();


            //HObject ROIContour;
            //HTuple  hv_rows, hv_cols;
            hv_rows.Clear();
            hv_rows[0] = sPoint.y();
            hv_rows[1] = ePoint.y();
            hv_rows[2] = ePoint.y();
            hv_rows[3] = sPoint.y();
            hv_rows[4] = sPoint.y();
            hv_cols.Clear();
            hv_cols[0] = sPoint.x();
            hv_cols[1] = sPoint.x();
            hv_cols[2] = ePoint.x();
            hv_cols[3] = ePoint.x();
            hv_cols[4] = sPoint.x();
            GenContourPolygonXld(&ROIContour, hv_rows, hv_cols);
            ClearWindow(HDevWindowStack::GetActive());
            SetColor(HDevWindowStack::GetActive(),"green");
            SetLineWidth(HDevWindowStack::GetActive(),4);
            DispObj(ho_Image, HDevWindowStack::GetActive());
            DispObj(ROIContour,HDevWindowStack::GetActive());
        }
        catch (HException &HDevExpDefaultException)
        {
            HTuple  hv_Exception;
            HDevExpDefaultException.ToHTuple(&hv_Exception);
            qDebug() <<"错误";
        }
    }

}


//鼠标 松开
void Widget::mouseReleaseEvent(QMouseEvent * e)
{
    if(DrawROI){
        try{
            GenRectangle1(&ho_Rectangle, sPoint.y(), sPoint.x(), ePoint.y(), ePoint.x());
            //对ROI区域进行裁剪
            ReduceDomain(ho_Image, ho_Rectangle, &ho_ImageReduced);
            qDebug()<<"成功截取感兴趣区域";
        }
        catch (HException &HDevExpDefaultException)
        {
            HTuple  hv_Exception;
            HDevExpDefaultException.ToHTuple(&hv_Exception);
            //qle_result->setText("创建模板失败");
            //DispObj(ho_Image, HDevWindowStack::GetActive());
        }
    }
}

void Widget::on_btn_AddImg_clicked(){
    qDebug()<<"添加训练图像";
    /*
    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);//内容居中
    */
    //将当前截取图像添加进图像集合

    //建立索引,即每张图像的种类编号的组合
    /*
    index :=[]
    classNo := 0
    tuple_insert (index, |index|, classNo, index)
    classNo := 1
    tuple_insert (index, |index|, classNo, index)
    classNo := 2
    tuple_insert (index, |index|, classNo, index)
    classNo := 1
    tuple_insert (index, |index|, classNo, index)
    classNo := 2
    tuple_insert (index, |index|, classNo, index)
    classNo := 2
    tuple_insert (index, |index|, classNo, index)
    tuple_find (index, 0, Indices0)
    tuple_find (index, 1, Indices1)
    tuple_find (index, 2, Indices2)
     */
    TupleInsert(hv_Index, hv_Index.TupleLength(), spinBox_classNo->value(), &hv_Index);
    qDebug()<<"hv_Index个数"<<hv_Index.TupleLength().I();

    //将roi截图添加入hv_images集合中
    ConcatObj(ho_Images, ho_ImageReduced, &ho_Images);
    HTuple hv_Number;
    CountObj(ho_Images, &hv_Number);
    qDebug()<<"ho_Images个数"<<hv_Number.I();
    //qDebug()<<"hv_Index:"<<hv_Index.I();
    /*
    for(int i =0;i<hv_Index.TupleLength().I();i++){
        //hv_a = ((const HTuple&)hv_Indices1)[1];
        qDebug()<<"hv_Index:"<<(((const HTuple&)hv_Index)[i]).I();
    }
    */

    //确认每个种类的个数

    for(int i = 0; i<spinBox_classNum->value(); i++){
        HTuple hv_Indices;
        TupleFind(hv_Index, i, &hv_Indices);
        //qDebug()<<"数值"+QString::number(i)+"个数:"<<hv_Indices.TupleLength().I();有问题,如果没有找到会赋值-1,个数会变成1
        /*

        QTableWidgetItem *item2 = new QTableWidgetItem(QString::number(hv_Indices.TupleLength().I()));
        item2->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
        tableWidget->setItem(i, 2, item2);
        */
        if (0 != (int(hv_Indices==-1)))//hv_Indices<0或hv_Indices==-1
          {
            qDebug()<<"数值"+QString::number(i)+"个数:0";
            QTableWidgetItem *item2 = new QTableWidgetItem(QString::number(0));
            item2->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
            tableWidget->setItem(i, 2, item2);
          }
        else{
            qDebug()<<"数值"+QString::number(i)+"个数:"+QString::number(hv_Indices.TupleLength().I());
            QTableWidgetItem *item2 = new QTableWidgetItem(QString::number(hv_Indices.TupleLength().I()));
            item2->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
            tableWidget->setItem(i, 2, item2);
        }

    }

}

void Widget::on_btn_classNum_clicked(){
    qDebug()<<"确认图像种类数";
    spinBox_classNo->setEnabled(true);
    btn_AddImg->setEnabled(true);
    spinBox_classNo->setRange(0,spinBox_classNum->value()-1);
    tableWidget->setRowCount(spinBox_classNum->value());
    //添加表格的数据,添加前先清除数据
    tableWidget->clearContents();
    for(int i = 0; i<spinBox_classNum->value(); i++){
        QTableWidgetItem *item0 = new QTableWidgetItem(QString::number(i));
        item0->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
        item0->setFlags(item0->flags() & (~Qt::ItemIsEditable)); //可选中,但是不可编辑
        tableWidget->setItem(i, 0, item0);

        QTableWidgetItem *item1 = new QTableWidgetItem();
        //table_item.setItem(row, column, QTableWidgetItem(str(value)))
        //item1->setFixedWidth(50);
        //item1->setFlags(Qt::ItemIsEditable);
        tableWidget->setItem(i,1,item1);

        QTableWidgetItem *item2 = new QTableWidgetItem(QString::number(0));
        item2->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//内容居中
        item0->setFlags(item2->flags() & (~Qt::ItemIsEditable)); //可选中,但是不可编辑
        tableWidget->setItem(i, 2, item2);
    }
}


void Widget::on_btn_Classify_clicked(){
    qDebug()<<"识别图像";
    //qDebug()<<tableWidget->item(0,1)->text();
    isClassify = !isClassify;//取反
}


void Widget::on_btn_TrainMLP_clicked(){
    qDebug()<<"训练网络";
    //训练前先清除mlp
    ClearClassMlp(hv_MLPHandle);
    //HTuple  hv_FeatureVector;
    //MLP::gen_features(ho_ImageReduced, &hv_FeatureVector);
    //MLP::gen_features(ho_ImageReduced, &hv_FeatureVector);
    HTuple hv_Number;
    CountObj(ho_Images, &hv_Number);
    HTuple  hv_FeatureVector;
    for (int i=1;i<=hv_Number;i++) {

        MLP::gen_features(ho_Images[i], &hv_FeatureVector);
        qDebug()<<"图像特征长度:"+QString::number(hv_FeatureVector.TupleLength().I());
        //果然都是72长度
    }
    HTuple hv_NumFeatures;
    hv_NumFeatures = hv_FeatureVector.TupleLength();
    HTuple hv_classes;
    for (int i =0; i <tableWidget->rowCount();i++) {
        TupleInsert(hv_classes, hv_classes.TupleLength(), i, &hv_classes);
    }
    //HTuple hv_NumClasses;
    hv_NumClasses = hv_classes.TupleLength();
    HTuple hv_NumHidden;
    hv_NumHidden = 15;

    CreateClassMlp(hv_NumFeatures, hv_NumHidden, hv_NumClasses, "softmax", "normalization",
                   10, 42, &hv_MLPHandle);

    //给不同Classes的截取添加到MLP中
    for (int i = 0;i <hv_NumClasses;i++) {
        int currentclass;
        currentclass = hv_classes[i];//其实和i值相同
        HTuple hv_Indices;
        hv_Indices = HTuple();
        TupleFind(hv_Index, currentclass, &hv_Indices);//获得图像种类的索引标号
        //首先判断hv_Indices是否为-1
        if (0 != (int(hv_Indices==-1)))//hv_Indices<0或hv_Indices==-1
          {
            //什么也事务也不处理
            qDebug()<<"种类"+QString::number(currentclass)+"个数为0";
          }
        else{
            qDebug()<<"种类"+QString::number(currentclass)+"个数为"+QString::number(hv_Indices.TupleLength().I());
            //执行添加操作
            for (int j =0;j<hv_Indices.TupleLength().I();j++) {
                HTuple currentindex;
                currentindex = hv_Indices[j];
                //qDebug()<<"1";
                //ho_Images[currentindex];
                qDebug()<<QString::number(currentindex.I());
                MLP::gen_features(ho_Images[currentindex.I()+1], &hv_FeatureVector);
                //qDebug()<<"2";
                AddSampleClassMlp(hv_MLPHandle, hv_FeatureVector,HTuple(currentclass));
                //qDebug()<<"3";
            }

        }

    }
    //训练MLP
    HTuple  hv_Error, hv_ErrorLog;
    TrainClassMlp(hv_MLPHandle, 200, 1, 0.01, &hv_Error, &hv_ErrorLog);
    qDebug()<<"训练完成";
}

void Widget::Classify(){
    HTuple hv_FeatureVector_test;
    MLP::gen_features(ho_ImageReduced, &hv_FeatureVector_test);
    HTuple  hv_FoundClassIDs, hv_Confidence;
    ClassifyClassMlp(hv_MLPHandle, hv_FeatureVector_test, hv_NumClasses, &hv_FoundClassIDs, &hv_Confidence);
    //显示识别结果
    try {
        SetColor(HDevWindowStack::GetActive(),"blue");
        SetLineWidth(HDevWindowStack::GetActive(),6);
        HTuple  hv_Font, hv_FontWithSize;
        QueryFont(HDevWindowStack::GetActive(), &hv_Font);
        hv_FontWithSize = HTuple(hv_Font[0])+"-20";

        SetFont(HDevWindowStack::GetActive(), hv_FontWithSize);
        //SetFont(HDevWindowStack::GetActive(), HTuple("黑体-20"));
        //SetFont("黑体-20");
        SetTposition(HDevWindowStack::GetActive(), 20, 20);
        WriteString(HDevWindowStack::GetActive(), "种类编号:"+hv_FoundClassIDs[0]);
        SetTposition(HDevWindowStack::GetActive(), 40, 20);
        //qDebug()<<tableWidget->item(0,1)->text();
        QString str = tableWidget->item(hv_FoundClassIDs[0].I(),1)->text();
        //qDebug()<<str;
        //str = "类别:"+str;
        //WriteString(HDevWindowStack::GetActive(), str.toLatin1().data());
        WriteString(HDevWindowStack::GetActive(), "类别:");
        SetTposition(HDevWindowStack::GetActive(), 40, 100);
        WriteString(HDevWindowStack::GetActive(), str.toLatin1().data());
        SetTposition(HDevWindowStack::GetActive(), 60, 20);
        WriteString(HDevWindowStack::GetActive(), "确信值:"+hv_Confidence[0]);
    }catch (HException &HDevExpDefaultException)
    {
        HTuple  hv_Exception;
        HDevExpDefaultException.ToHTuple(&hv_Exception);
    }

}

//

/

/

附录halcon杂代码

index :=[]
classNo := 0
tuple_insert (index, |index|, classNo, index)
classNo := 1
tuple_insert (index, |index|, classNo, index)
classNo := 2
tuple_insert (index, |index|, classNo, index)
classNo := 1
tuple_insert (index, |index|, classNo, index)
classNo := 2
tuple_insert (index, |index|, classNo, index)
classNo := 2
tuple_insert (index, |index|, classNo, index)
tuple_find (index, 0, Indices0)
tuple_find (index, 1, Indices1)
tuple_find (index, 2, Indices2)


create_class_mlp (72, 16, 2, 'softmax', \
                  'normalization', 1, 42, MLPHandle)

train_class_mlp (MLPHandle, 100, 1, 0.01, Error, ErrorLog)
write_class_mlp (MLPHandle, 'classifier.mlp')
read_samples_class_mlp (MLPHandle, 'samples.mtf')

*将MLP模型写入文件
write_class_mlp (MLPHandle, 'classifier.mlp')
*从文件中读入一个MLP模型
read_class_mlp ('classifier.mlp', MLPHandle1)
*清除MLP
clear_class_mlp (MLPHandle1)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值