当前位置: 首页 > news >正文

Halcon联合QT ROI绘制

文章目录

  • Halcon 操纵界面代码
  • 窗口代码

在这里插入图片描述

Halcon 操纵界面代码

#pragma once#include <QLabel>#include <halconcpp/HalconCpp.h>
#include <qtimer.h>
#include <qevent.h>
using namespace HalconCpp;#pragma execution_character_set("utf-8")class CHalconLabel  : public QLabel
{Q_OBJECTpublic:CHalconLabel(QWidget* parent);~CHalconLabel();protected:void resizeEvent(QResizeEvent* ev);            //显示界面---尺寸更改事件void wheelEvent(QWheelEvent* ev);              //显示界面---鼠标滚轮缩放事件void mousePressEvent(QMouseEvent* ev);         //显示界面---鼠标按下事件void mouseReleaseEvent(QMouseEvent* ev);       //显示界面---鼠标释放事件void mouseMoveEvent(QMouseEvent* ev);          //显示界面---鼠标移动事件(有三种情况)//获取ROI区域public:void SetID();                                  //设置ID与显示窗口void SetPixelTracke(bool);                     //开启/关闭实时获取图像像素坐标下的灰度值void DisplayImage(HObject  hDisplayImage);     //显示图像(只显示图像)void ResetDisplayImage();                      //恢复显示(只显示图像)void DrawCircles();                             //绘制圆void DrawRectangles();                          //绘制矩形void DrawRotateRectangles();                    //绘制旋转矩形void DrawEllipses();                            //绘制椭圆void ClearROI();                               //清空所有的ROI区域void DispalyImageROI();                        //显示图像(同时显示图像和ROI区域)void DisplayRegion();                          //只显示ROI区域内的图像HObject GetRegion();private:HTuple   m_hLabelID;						//当前QLabel控件idHTuple   m_hHalconID = NULL;				//Halcon显示窗口idHObject  m_drawnRegion;						//绘图区域HObject  ho_ImageZoom;						//缩放的图像HObject  hCurrentImage;						//当前显示的图像HTuple m_tMouseDownRow, m_tMouseDownCol;	//鼠标按下时的行列坐标bool m_bIsMove;								//是否按下鼠标,未按下移动,实时获取坐标值,按下移动,移动显示图像bool m_bIsDrawROI;							//绘制ROI区域时不再响应移动绘图事件HObject ho_Image;};
#include "CHalconLabel.h"CHalconLabel::CHalconLabel(QWidget* parent): QLabel(parent), m_bIsMove(false), m_bIsDrawROI(false)
{//初始化图像GenEmptyObj(&hCurrentImage);//初始化ROI区域GenEmptyObj(&m_drawnRegion);//设置文本位置---居中且上方,设置文本颜色this->setAlignment(Qt::AlignTop | Qt::AlignHCenter);this->setStyleSheet("color: red;");}CHalconLabel::~CHalconLabel()
{
}void CHalconLabel::resizeEvent(QResizeEvent * ev)
{if (m_hHalconID != NULL){//防止窗口闪烁SetSystem("flush_graphic", "false");//重新显示//显示二,维持原有图像比例且居中显示	ClearWindow(m_hHalconID);DetachBackgroundFromWindow(m_hHalconID);int labelWidth = this->width();  //窗口尺寸int labelHeight = this->height();HTuple imgWidth, imgHeight;                 //原图尺寸HTuple m_scaledWidth, m_scaledHeight;       //缩放后的尺寸HTuple m_hvScaledRate;                      //缩放比例GetImageSize(hCurrentImage, &imgWidth, &imgHeight);//获取缩放系数TupleMin2(1.0 * labelWidth / imgWidth, 1.0 * labelHeight / imgHeight, &m_hvScaledRate);//进行图像缩放ZoomImageFactor(hCurrentImage, &ho_ImageZoom, m_hvScaledRate, m_hvScaledRate, "constant");GetImageSize(ho_ImageZoom, &m_scaledWidth, &m_scaledHeight);if (1.0 * labelWidth / imgWidth < 1.0 * labelHeight / imgHeight){SetWindowExtents(m_hHalconID, labelHeight / 2.0 - m_scaledHeight / 2.0, 0, labelWidth, m_scaledHeight);}else{SetWindowExtents(m_hHalconID, 0, labelWidth / 2.0 - m_scaledWidth / 2.0, m_scaledWidth, labelHeight);}SetPart(m_hHalconID, 0, 0, imgHeight - 1, imgWidth - 1);AttachBackgroundToWindow(hCurrentImage, m_hHalconID);SetSystem("flush_graphic", "true");DetachBackgroundFromWindow(m_hHalconID);AttachBackgroundToWindow(hCurrentImage, m_hHalconID);DispObj(hCurrentImage, m_hHalconID);AttachBackgroundToWindow(hCurrentImage, m_hHalconID);DispObj(m_drawnRegion, m_hHalconID);  // 添加此行以重新显示ROI}
}void CHalconLabel::wheelEvent(QWheelEvent* ev)
{double Zoom;   //放大或缩小倍率HTuple  mouseRow, mouseCol, Button;HTuple startRowBf, startColBf, endRowBf, endColBf, Ht, Wt, startRowAft, startColAft, endRowAft, endColAft;//滚轮前滑,放大if (ev->delta() > 0){Zoom = 2.0;//单步放大倍率}else//否则缩小{Zoom = 1 / 2.0;}//获取光标在原图上的位置,注意是原图坐标,不是Label下的坐标HTuple  hv_Exception, hv_ErrMsg;try{GetMposition(m_hHalconID, &mouseRow, &mouseCol, &Button);}catch (HException& HDevExpDefaultException){return;}//获取原图显示的部分,注意也是原图坐标GetPart(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf);//缩放前显示的图像宽高Ht = endRowBf - startRowBf;Wt = endColBf - startColBf;//普通版halcon能处理的图像最大尺寸是32K*32K。如果无限缩小原图像,导致显示的图像超出限制,则会造成程序崩溃if (Ht * Wt < 20000 * 20000 || Zoom == 2.0){//计算缩放后的图像区域startRowAft = mouseRow - ((mouseRow - startRowBf) / Zoom);startColAft = mouseCol - ((mouseCol - startColBf) / Zoom);endRowAft = startRowAft + (Ht / Zoom);endColAft = startColAft + (Wt / Zoom);//如果放大过大,则返回if (endRowAft - startRowAft < 2){return;}if (m_hHalconID != NULL){//如果有图像,则先清空图像DetachBackgroundFromWindow(m_hHalconID);}SetPart(m_hHalconID, startRowAft, startColAft, endRowAft, endColAft);AttachBackgroundToWindow(hCurrentImage, m_hHalconID);}AttachBackgroundToWindow(hCurrentImage, m_hHalconID);DispObj(m_drawnRegion, m_hHalconID);  // 添加此行以重新显示ROI
}void CHalconLabel::mousePressEvent(QMouseEvent* ev)
{HTuple mouseRow, mouseCol, Button;try{GetMposition(m_hHalconID, &mouseRow, &mouseCol, &Button);}catch (HException){return;}//鼠标按下时的行列坐标m_tMouseDownRow = mouseRow;m_tMouseDownCol = mouseCol;m_bIsMove = true;
}void CHalconLabel::mouseReleaseEvent(QMouseEvent* ev)
{m_bIsMove = false;}void CHalconLabel::mouseMoveEvent(QMouseEvent* ev)
{//情况一:鼠标绘制ROI区域时,不响应鼠标移动事件if (m_bIsDrawROI) {this->setCursor(Qt::ArrowCursor);   //指针设置为普通类型return;}//情况二:鼠标按下并移动时,只移动图像HTuple startRowBf, startColBf, endRowBf, endColBf, mouseRow, mouseCol, Button;try{SetCheck("~give_error");    //不要报错GetMposition(m_hHalconID, &mouseRow, &mouseCol, &Button);if (mouseCol.Length() <= 0 || mouseRow.Length() < 0){return;}SetCheck("give_error");//在绘图显示界面上显示坐标//this->setText(QString("X坐标:%1    Y坐标:%2    ").arg(mouseCol[0].D()).arg(mouseRow[0].D()));}catch (HException){return;}if (m_bIsMove){this->setCursor(Qt::PointingHandCursor);   //设置鼠标样式为手型指针//计算移动值double RowMove = mouseRow[0].D() - m_tMouseDownRow[0].D();double ColMove = mouseCol[0].D() - m_tMouseDownCol[0].D();//得到当前的窗口坐标GetPart(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf);//移动图像if (m_hHalconID != NULL){//如果有图像,则先清空图像DetachBackgroundFromWindow(m_hHalconID);}SetPart(m_hHalconID, startRowBf - RowMove, startColBf - ColMove, endRowBf - RowMove, endColBf - ColMove);SetCheck("~give_error");AttachBackgroundToWindow(hCurrentImage, m_hHalconID);//当光标不在Halcon窗口内时返回,否则会报错SetCheck("give_error");}//情况三:鼠标未按下移动时,实时获取当前图像坐标else {this->setCursor(Qt::ArrowCursor);   //指针设置为普通类型HTuple pointGray;try{SetCheck("~give_error");    //不要报错GetGrayval(hCurrentImage, mouseRow, mouseCol, &pointGray);//当光标不在Halcon窗口内时返回,否则会报错if (mouseCol.Length() <= 0 || pointGray[0].D() < 0){return;}SetCheck("give_error");    //不要报错}catch (HException){// 设置文本的颜色为红色// this->setText(QString("X坐标:-    Y坐标:-    灰度值:-"));return;}//在绘图显示界面上显示坐标//this->setText(QString("X坐标:%1    Y坐标:%2    灰度值:%3").arg(mouseCol[0].D()).arg(mouseRow[0].D()).arg(pointGray[0].D()));}AttachBackgroundToWindow(hCurrentImage, m_hHalconID);DispObj(m_drawnRegion, m_hHalconID);  // 添加此行以重新显示ROI
}void CHalconLabel::DrawCircles()
{//绘制的过程中,不能鼠标移动图像,不响应鼠标移动事件m_bIsDrawROI = true;HObject currentRegion;HTuple Row, Column, Radius;DrawCircle(m_hHalconID, &Row, &Column, &Radius);GenCircle(&currentRegion, Row, Column, Radius);Union2(m_drawnRegion, currentRegion, &m_drawnRegion);//设置ROI边缘线SetColor(m_hHalconID, "red");SetDraw(m_hHalconID, "margin");SetLineWidth(m_hHalconID, 2);DispObj(m_drawnRegion, m_hHalconID);//绘制结束以后,实时获取当前图像的像素坐标m_bIsDrawROI = false;
}void CHalconLabel::DrawRectangles()
{m_bIsDrawROI = true;HObject currentRegion;HTuple R1, C1, R2, C2;DrawRectangle1(m_hHalconID, &R1, &C1, &R2, &C2);GenRectangle1(&currentRegion, R1, C1, R2, C2);Union2(m_drawnRegion, currentRegion, &m_drawnRegion);//设置ROI边缘线SetColor(m_hHalconID, "red");SetDraw(m_hHalconID, "margin");SetLineWidth(m_hHalconID, 2);DispObj(m_drawnRegion, m_hHalconID);m_bIsDrawROI = false;
}void CHalconLabel::DrawRotateRectangles()
{m_bIsDrawROI = true;HObject currentRegion;HTuple Row, Column, Phi, Length1, Length2;DrawRectangle2(m_hHalconID, &Row, &Column, &Phi, &Length1, &Length2);GenRectangle2(&currentRegion, Row, Column, Phi, Length1, Length2);Union2(m_drawnRegion, currentRegion, &m_drawnRegion);//设置ROI边缘线SetColor(m_hHalconID, "red");SetDraw(m_hHalconID, "margin");SetLineWidth(m_hHalconID, 2);DispObj(m_drawnRegion, m_hHalconID);m_bIsDrawROI = false;
}void CHalconLabel::DrawEllipses()
{m_bIsDrawROI = true;HObject currentRegion;HTuple Row, Column, Phi, Radius1, Radius2;DrawEllipse(m_hHalconID, &Row, &Column, &Phi, &Radius1, &Radius2);GenEllipse(&currentRegion, Row, Column, Phi, Radius1, Radius2);Union2(m_drawnRegion, currentRegion, &m_drawnRegion);//设置ROI边缘线SetColor(m_hHalconID, "red");SetDraw(m_hHalconID, "margin");SetLineWidth(m_hHalconID, 2);DispObj(m_drawnRegion, m_hHalconID);m_bIsDrawROI = false;
}void CHalconLabel::ClearROI()
{//直接清空GenEmptyRegion(&m_drawnRegion);
}void CHalconLabel::DispalyImageROI()
{DisplayImage(hCurrentImage);HObject emptyRegion;HTuple isEqual;GenEmptyRegion(&emptyRegion);TestEqualRegion(emptyRegion, m_drawnRegion, &isEqual);if (isEqual == 0) {DispObj(m_drawnRegion, m_hHalconID);}
}void CHalconLabel::DisplayRegion()
{HObject image;HObject emptyRegion;HTuple isEqual;GenEmptyRegion(&emptyRegion);TestEqualRegion(emptyRegion, m_drawnRegion, &isEqual);if (isEqual != 0) {return;}ReduceDomain(hCurrentImage, m_drawnRegion, &image);ClearWindow(m_hHalconID);DisplayImage(image);
}HObject CHalconLabel::GetRegion()
{return m_drawnRegion;
}void CHalconLabel::SetID()
{if (m_hHalconID == NULL) {SetWindowAttr("background_color", "black");     //设置背景色m_hLabelID = (Hlong)this->winId();OpenWindow(0, 0, this->width(), this->height(), m_hLabelID, "visible", "", &m_hHalconID);}
}void CHalconLabel::SetPixelTracke(bool ret)
{//设置鼠标追踪,可以实时响应鼠标移动事件this->setMouseTracking(ret);}void CHalconLabel::DisplayImage(HObject hDisplayImage)
{//隔离数据CopyImage(hDisplayImage, &hCurrentImage);//显示二,维持原有图像比例且居中显示	ClearWindow(m_hHalconID);DetachBackgroundFromWindow(m_hHalconID);int labelWidth = this->width();  //窗口尺寸int labelHeight = this->height();HTuple imgWidth, imgHeight;                 //原图尺寸HTuple m_scaledWidth, m_scaledHeight;       //缩放后的尺寸HTuple m_hvScaledRate;                      //缩放比例GetImageSize(hCurrentImage, &imgWidth, &imgHeight);//获取缩放系数TupleMin2(1.0 * labelWidth / imgWidth, 1.0 * labelHeight / imgHeight, &m_hvScaledRate);//进行图像缩放ZoomImageFactor(hCurrentImage, &ho_ImageZoom, m_hvScaledRate, m_hvScaledRate, "constant");GetImageSize(ho_ImageZoom, &m_scaledWidth, &m_scaledHeight);if (1.0 * labelWidth / imgWidth < 1.0 * labelHeight / imgHeight){SetWindowExtents(m_hHalconID, labelHeight / 2.0 - m_scaledHeight / 2.0, 0, labelWidth, m_scaledHeight);}else{SetWindowExtents(m_hHalconID, 0, labelWidth / 2.0 - m_scaledWidth / 2.0, m_scaledWidth, labelHeight);}SetPart(m_hHalconID, 0, 0, imgHeight - 1, imgWidth - 1);AttachBackgroundToWindow(hCurrentImage, m_hHalconID);}void CHalconLabel::ResetDisplayImage()
{ClearWindow(m_hHalconID);DetachBackgroundFromWindow(m_hHalconID);int labelWidth = this->width();  //窗口尺寸int labelHeight = this->height();HTuple imgWidth, imgHeight;                 //原图尺寸HTuple m_scaledWidth, m_scaledHeight;       //缩放后的尺寸HTuple m_hvScaledRate;                      //缩放比例GetImageSize(hCurrentImage, &imgWidth, &imgHeight);//获取缩放系数TupleMin2(1.0 * labelWidth / imgWidth, 1.0 * labelHeight / imgHeight, &m_hvScaledRate);//进行图像缩放ZoomImageFactor(hCurrentImage, &ho_ImageZoom, m_hvScaledRate, m_hvScaledRate, "constant");GetImageSize(ho_ImageZoom, &m_scaledWidth, &m_scaledHeight);if (1.0 * labelWidth / imgWidth < 1.0 * labelHeight / imgHeight){SetWindowExtents(m_hHalconID, labelHeight / 2.0 - m_scaledHeight / 2.0, 0, labelWidth, m_scaledHeight);}else{SetWindowExtents(m_hHalconID, 0, labelWidth / 2.0 - m_scaledWidth / 2.0, m_scaledWidth, labelHeight);}SetPart(m_hHalconID, 0, 0, imgHeight - 1, imgWidth - 1);AttachBackgroundToWindow(hCurrentImage, m_hHalconID);
}

窗口代码

#pragma once#include <QtWidgets/QMainWindow>#include "CHalconLabel.h"#include "ui_HalconMain.h"
#include <qpushbutton.h>
#include <qfiledialog.h>class HalconMain : public QMainWindow
{Q_OBJECTpublic:HalconMain(QWidget *parent = nullptr);~HalconMain();public:void InitWidget();private slots:void on_readImageBtn();void on_drawCircleBtn();void on_drawRectangleBtn();void on_drawRotateBtn();void on_drawEllipseBtn();void on_clearROIBtn();void on_resetImageBtn();private:Ui::HalconMainClass ui;CHalconLabel* displayLabel;
};
HalconMain::HalconMain(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);InitWidget();//connect(ui.pb, &QPushButton::clicked, this, &HalconMain::on_readImageBtn);connect(ui.pb_readImg, &QPushButton::clicked, this, &HalconMain::on_readImageBtn);connect(ui.pb_drawcircle, &QPushButton::clicked, this, &HalconMain::on_drawCircleBtn);connect(ui.pb_drawrectangle, &QPushButton::clicked, this, &HalconMain::on_drawRectangleBtn);connect(ui.pb_clearroi, &QPushButton::clicked, this, &HalconMain::on_clearROIBtn);connect(ui.pb_recoverimg, &QPushButton::clicked, this, &HalconMain::on_resetImageBtn);}HalconMain::~HalconMain()
{
}void HalconMain::InitWidget()
{displayLabel = new CHalconLabel(this);ui.layout->addWidget(displayLabel);
}void HalconMain::on_drawCircleBtn()
{displayLabel->DrawCircles();
}void HalconMain::on_drawRectangleBtn()
{displayLabel->DrawRectangles();
}void HalconMain::on_drawRotateBtn()
{}void HalconMain::on_drawEllipseBtn()
{
}void HalconMain::on_clearROIBtn()
{displayLabel->ClearROI();displayLabel->DispalyImageROI();
}void HalconMain::on_resetImageBtn()
{displayLabel->DispalyImageROI();
}void HalconMain::on_readImageBtn()
{HObject hImage;displayLabel->SetID();  //最好不要在主界面的构造函数内调用这个函数QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), ".", tr("Image Files (*.png *.jpg *.bmp)"));if (fileName.isEmpty()) {return;}//显示图像HTuple hFileName(fileName.toStdString().c_str());ReadImage(&hImage, hFileName);displayLabel->DisplayImage(hImage);displayLabel->SetPixelTracke(false);
}

在这里插入图片描述

相关文章:

  • Spring Boot事务失效场景及解决方案
  • 超大规模模型训练中的 ZeRO 优化器与混合精度通信压缩技术
  • 【JavaSE】枚举和注解学习笔记
  • 编程日志5.27
  • AI情感陪伴在医疗领域的核心应用潜力
  • 彻底理解一个知识点的具体步骤
  • 西门子-队列
  • 第1章 Redis 概述
  • 【C++】类和对象(上)
  • 每日算法 -【Swift 算法】实现回文数判断!
  • endnote2025安装教程以及激活文件
  • 软考 系统架构设计师系列知识点之杂项集萃(77)
  • 修复SSH 服务支持弱加密算法漏洞
  • 【实战】Tennis-Tracking 安装与运行完整教程(含 CUDA/TF 报错解决)
  • C++优先队列(priority_queue)使用详解
  • SQL 查询慢的常见原因分析
  • STL容器使用中的常见问题解析
  • 【调试】【原理理解】ldm 和 diffusers 库的区别
  • 院校机试刷题第十三天:代码随想录算法训练营第七天
  • VectorNet:自动驾驶中的向量魔法
  • 外贸网站建设免费/发软文的平台
  • 做守望同人的网站/百度首页排名优化服务
  • 赤峰做网站公司/百度推广销售话术
  • 盐城哪有做网站建设的/百度推广一个点击多少钱
  • 鹿城做网站/网络公司主要做哪些
  • 多个网站如何做301/第一设计