欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

VS+Qt+Halcon 顯示圖片,實(shí)現(xiàn)鼠標(biāo)縮放、移動(dòng)圖片

 更新時(shí)間:2021年08月26日 08:37:41   作者:唯有自己強(qiáng)大  
本篇博文記錄一下,用VS+Qt+Halcon實(shí)現(xiàn)對(duì)圖片的讀取以及鼠標(biāo)縮放,移動(dòng)(鼠標(biāo)事件調(diào)用了halcon自帶的算子)的過(guò)程。感興趣的可以了解一下

摘要

本篇博文記錄一下,用VS+Qt+Halcon實(shí)現(xiàn)對(duì)圖片的讀取以及鼠標(biāo)縮放,移動(dòng)(鼠標(biāo)事件調(diào)用了halcon自帶的算子)的過(guò)程。以及遇到的坑.....😑😑

先來(lái)看一下動(dòng)態(tài)效果圖:

主要控件:

  • 添加一個(gè)Label控件,對(duì)象名設(shè)為label,用于顯示圖片,并將背景設(shè)為黑色,設(shè)置方法為:選中Label控件,在屬性編輯器中找到styleSheet屬性,在其后的值中輸入background-color:black即可;
  • 添加四個(gè)Push Button控件,如上圖所示從左至右,對(duì)象名依次為:btn_prePic、btn_openPic、btn_nextPic,btn_resetPic,用于打開(kāi)圖片和前后瀏覽,以及恢復(fù)原圖;
  • 添加一個(gè)Label,對(duì)象名設(shè)為label_status,用于實(shí)時(shí)顯示坐標(biāo)和灰度值;
  • 將label_show控件提升為CMyLabel類(lèi),用于接收鼠標(biāo)事件。

代碼例程

在Visual Studio中新建一個(gè)Qt GUI項(xiàng)目,名稱(chēng)設(shè)為BrowsePic,并新建Mylabel類(lèi)(繼承自QLabel)用于label控件的提升。

Mylabel.h

#pragma once
#include "qlabel.h"
#include"QWheelEvent"
#include<HalconCpp.h>
using namespace HalconCpp;

class Mylabel :
    public QLabel
{
    Q_OBJECT

public:
    Mylabel(QWidget* parent = Q_NULLPTR);
    ~Mylabel();
    //設(shè)置Halcon圖像和Halcon窗口句柄,用戶(hù)響應(yīng)鼠標(biāo)事件后實(shí)時(shí)更新圖像
    void setHalconWnd(HObject img, HTuple hHalconID, QLabel* label);
    //鼠標(biāo)滾輪縮放事件
    void wheelEvent(QWheelEvent* ev);
    //鼠標(biāo)按下事件
    void mousePressEvent(QMouseEvent* ev);
    //鼠標(biāo)釋放事件
    void mouseReleaseEvent(QMouseEvent* ev);
    //鼠標(biāo)移動(dòng)事件
    void mouseMoveEvent(QMouseEvent* ev);
public:
    HTuple m_labelID;            //Qt標(biāo)簽句柄
    HTuple m_hHalconID;            //Halcon窗口句柄
    HObject m_currentImg;        //當(dāng)前的圖像
    //主界面顯示坐標(biāo)的標(biāo)簽
    QLabel* m_label;
    //鼠標(biāo)按下的位置 
    HTuple m_tMouseDownRow;
    HTuple m_tMouseDownCol;
    bool m_bIsMove;                //是否移動(dòng)圖像標(biāo)識(shí)
};

Mylabel.cpp

#include "Mylabel.h"
//定義單步放大倍率
#define ZOOMRATIO 2.0

Mylabel::Mylabel(QWidget* parent)
    : QLabel(parent)
{
    m_bIsMove = false;
    this->setMouseTracking(true);
    
}
Mylabel::~Mylabel()
{

}

//設(shè)置Halcon圖像和Halcon窗口句柄,用戶(hù)響應(yīng)鼠標(biāo)事件后實(shí)時(shí)更新圖像
void Mylabel::setHalconWnd(HObject img, HTuple hHalconID, QLabel* label)
{
    m_hHalconID = hHalconID;
    m_currentImg = img;
    m_label = label;
}

//鼠標(biāo)滾輪縮放事件,用于縮放圖像
void Mylabel::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 = ZOOMRATIO;
    }
    else//否則縮小
    {
        Zoom = 1 / ZOOMRATIO;
    }
    //獲取光標(biāo)在原圖上的位置,注意是原圖坐標(biāo),不是Label下的坐標(biāo)
    HTuple  hv_Exception, hv_ErrMsg;
     try
     {
         GetMposition(m_hHalconID, &mouseRow, &mouseCol, &Button);

     }
     catch (HException& HDevExpDefaultException)
     {
         return;
     }
     //獲取原圖顯示的部分,注意也是原圖坐標(biāo)
     GetPart(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf);
     //縮放前顯示的圖像寬高
     Ht = endRowBf - startRowBf;
     Wt = endColBf - startColBf;
     //普通版halcon能處理的圖像最大尺寸是32K*32K。如果無(wú)限縮小原圖像,導(dǎo)致顯示的圖像超出限制,則會(huì)造成程序崩潰
     if (Ht*Wt<20000*20000||Zoom==ZOOMRATIO)
     {
         //計(jì)算縮放后的圖像區(qū)域
         startRowAft = mouseRow - ((mouseRow - startRowBf) / Zoom);
         startColAft = mouseCol - ((mouseCol - startColBf) / Zoom);
         endRowAft = startRowAft + (Ht / Zoom);
         endColAft = startColAft + (Wt / Zoom);
         //如果放大過(guò)大,則返回
         if (endRowAft - startRowAft < 2)
         {
             return;
         }

         if (m_hHalconID != NULL)
         {
             //如果有圖像,則先清空?qǐng)D像
             DetachBackgroundFromWindow(m_hHalconID);
         }
         SetPart(m_hHalconID, startRowAft, startColAft, endRowAft, endColAft);
         AttachBackgroundToWindow(m_currentImg, m_hHalconID);    
     }
}

void Mylabel::mousePressEvent(QMouseEvent* ev)
{
    HTuple mouseRow, mouseCol, Button;
    try
    {
        GetMposition(m_hHalconID, &mouseRow, &mouseCol, &Button);

    }
    catch (HException)
    {
        return;
    }
    //鼠標(biāo)按下時(shí)的行列坐標(biāo)
    m_tMouseDownRow = mouseRow;
    m_tMouseDownCol = mouseCol;
    m_bIsMove = true;
}
//鼠標(biāo)釋放事件
void Mylabel::mouseReleaseEvent(QMouseEvent* ev)
{
    m_bIsMove = false;
}
//鼠標(biāo)移動(dòng)事件
void Mylabel::mouseMoveEvent(QMouseEvent* ev)
{
    HTuple startRowBf, startColBf, endRowBf, endColBf, mouseRow, mouseCol, Button;
    try
    {
        GetMposition(m_hHalconID, &mouseRow, &mouseCol, &Button);

    }
    catch (HException)
    {
        return;
    }
    //鼠標(biāo)按下并移動(dòng)時(shí),移動(dòng)圖像,否則只顯示坐標(biāo)
    if (m_bIsMove)
    {
        //計(jì)算移動(dòng)值
        double RowMove = mouseRow[0].D() - m_tMouseDownRow[0].D();
        double ColMove = mouseCol[0].D() - m_tMouseDownCol[0].D();
        //得到當(dāng)前的窗口坐標(biāo)
        GetPart(m_hHalconID, &startRowBf, &startColBf, &endRowBf, &endColBf);
        //移動(dòng)圖像
        if (m_hHalconID!=NULL)
        {
            //如果有圖像,則先清空?qǐng)D像
            DetachBackgroundFromWindow(m_hHalconID);
        }
        SetPart(m_hHalconID, startRowBf - RowMove, startColBf - ColMove, endRowBf - RowMove, endColBf - ColMove);
        AttachBackgroundToWindow(m_currentImg, m_hHalconID);
    }
    //獲取灰度值
    HTuple pointGray;
    try
    {
        GetGrayval(m_currentImg, mouseRow, mouseCol, &pointGray);
    }
    catch (HException)
    {
        m_label->setText(QString::fromLocal8Bit("X坐標(biāo):-    Y坐標(biāo):-    灰度值:-"));

        return;
    }
    //設(shè)置坐標(biāo)
    m_label->setText(QString::fromLocal8Bit("X坐標(biāo):%1    Y坐標(biāo):%2    灰度值:%3").arg(mouseCol[0].D()).arg(mouseRow[0].D()).arg(pointGray[0].D()));
}

BrowsePic.h

#pragma once

#include <QtWidgets/QWidget>
#include "ui_BrowsePic.h"
#include<HalconCpp.h>
#include"qtoolbar.h"
using namespace HalconCpp;
#pragma execution_character_set("utf-8");

class BrowsePic : public QWidget
{
    Q_OBJECT

public:
    BrowsePic(QWidget *parent = Q_NULLPTR);
    ~BrowsePic();
    //初始化
    void init();

    //顯示圖像
    void showImg();
    int currentIndex;
    //顯示圖像的控件id
    HTuple m_hLabelID;            //QLabel控件句柄
    HTuple m_hHalconID;            //Halcon顯示窗口句柄

    //原始圖像的尺寸
    HTuple m_imgWidth, m_imgHeight;

    //圖片路徑列表
    HTuple m_imgFiles;

    //當(dāng)前圖像
    HObject m_hCurrentImg;
    //縮放后的圖像
    HObject m_hResizedImg;
    //縮放系數(shù)
    HTuple m_hvScaledRate;
    //縮放后圖像的大小
    HTuple m_scaledHeight, m_scaledWidth;
    QToolBar* m_toolBar;
public slots:

    //打開(kāi)圖片
    void on_btn_openPic_clicked();

    //瀏覽前一張
    void on_btn_prePic_clicked();

    //瀏覽后一張
    void on_btn_nextPic_clicked();

    //恢復(fù)圖片
    void on_btn_resetPic_clicked();
private:
    Ui::BrowsePicClass ui;
};

BrowsePic.cpp

#include "browsepic.h"
#include"Mylabel.h"
#include <QFileDialog>
#include <QFileInfo>
BrowsePic::BrowsePic(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    init();

}
BrowsePic::~BrowsePic()
{

}

void BrowsePic::init()
{
    //設(shè)置halcon的文件路徑為utf8,解決中文亂碼
    SetSystem("filename_encoding", "utf8");
    //生成空?qǐng)D像
    GenEmptyObj(&m_hCurrentImg);
    m_hHalconID = NULL;
    m_hLabelID = (Hlong)ui.label->winId();
    currentIndex = -1;
}
//顯示圖像
void BrowsePic::showImg()
{
    if (m_hHalconID!=NULL)
    {
        //如果有圖像,則先清空?qǐng)D像
        DetachBackgroundFromWindow(m_hHalconID);
        
    }
    else
    {
        //打開(kāi)窗口
        OpenWindow(0, 0, ui.label->width(), ui.label->height(), m_hLabelID, "visible", "", &m_hHalconID);
    }
    ui.label-> setHalconWnd(m_hCurrentImg, m_hHalconID, ui.label_status);

    //獲取圖像大小
    GetImageSize(m_hCurrentImg, &m_imgWidth, &m_imgHeight);
    //獲取縮放系數(shù)
    TupleMin2(1.0 * ui.label->width() / m_imgWidth, 1.0 * ui.label->height() / m_imgHeight, &m_hvScaledRate);
    //縮放圖像
    ZoomImageFactor(m_hCurrentImg, &m_hResizedImg, m_hvScaledRate, m_hvScaledRate, "constant");
    //獲取縮放后的大小
    GetImageSize(m_hResizedImg, &m_scaledWidth, &m_scaledHeight);
    //打開(kāi)窗口
    if (1.0 * ui.label->width() / m_imgWidth < 1.0 * ui.label->height() / m_imgHeight)
    {
        SetWindowExtents(m_hHalconID, ui.label->height() / 2.0 - m_scaledHeight / 2.0, 0, ui.label->width(), m_scaledHeight);
    }
    else
    {
        SetWindowExtents(m_hHalconID, 0, ui.label->width() / 2.0 - m_scaledWidth / 2.0, m_scaledWidth, ui.label->height());

    }
    SetPart(m_hHalconID, 0, 0, m_imgHeight - 1, m_imgWidth - 1);
    AttachBackgroundToWindow(m_hCurrentImg, m_hHalconID);
}

//打開(kāi)圖片
void BrowsePic::on_btn_openPic_clicked()
{
    QString path = QFileDialog::getOpenFileName(this, "加載圖像", "./", "圖像文件(*.bmp *.png *.jpg)");
    QFileInfo fileInfo(path);
    QString dir = fileInfo.path();

    if (!path.isEmpty())
    {
        ListFiles(dir.toStdString().c_str(), "files", &m_imgFiles);

        TupleRegexpSelect(m_imgFiles, HTuple("\\.bmp|png|jpg").Append("ignore_case"), &m_imgFiles);


        for (int i = 0; i < m_imgFiles.Length(); i++)
        {

            QString currentPath = m_imgFiles[i];
            currentPath.replace("\\", "/");

            if (currentPath == path)
            {
                currentIndex = i;
                ReadImage(&m_hCurrentImg, m_imgFiles[i]);
                showImg();
            }

        }
    }

}

//瀏覽前一張
void BrowsePic::on_btn_prePic_clicked()
{
    if (currentIndex > 0)
    {
        currentIndex--;
        ReadImage(&m_hCurrentImg, m_imgFiles[currentIndex]);
        showImg();

    }
}
//瀏覽后一張
void BrowsePic::on_btn_nextPic_clicked()
{
    if (currentIndex >= 0 && currentIndex < m_imgFiles.Length() - 1)
    {
        currentIndex++;
        ReadImage(&m_hCurrentImg, m_imgFiles[currentIndex]);
        showImg();
    }
}
//恢復(fù)圖片
void BrowsePic::on_btn_resetPic_clicked()
{
    showImg();
}

關(guān)鍵代碼解釋

Qt函數(shù)與Halcon算子獲取的文件路徑字符串的區(qū)別

Halcon算子獲取的文件路徑格式

list_files()的原型如下:

第一個(gè)參數(shù)為路徑,提取的文件路徑格式與參數(shù)Directory的形式有關(guān),在HDevelop中測(cè)試:

–Directory以"\\"分隔時(shí),即list_files ('E:\\TEST', 'files', Files)

–Directory以“/”分隔時(shí),即list_files ('E:/TEST', 'files', Files)

可以發(fā)現(xiàn)兩種方式提取的文件路徑字符串的區(qū)別。

Qt函數(shù)獲取的文件路徑格式

getOpenFileName()獲得的路徑:

如何將二者路徑保持一致?

先讀取halcon算子獲取的路徑:

 QString currentPath = m_imgFiles[i];

然后將" \ "全部換成" /":

 currentPath.replace("\\", "/");

2️⃣在VS中使用Halcon時(shí)的編碼及中文亂碼問(wèn)題

默認(rèn)條件下,可使用以下C++語(yǔ)句獲取Halcon的文件名編碼:

HTuple codeType;
get_system("filename_encoding", &codeType);
QString strCodeType = codeType[0].S();

可以發(fā)現(xiàn)默認(rèn)的編碼是locale,此時(shí)用Halcon算子list_files獲取的文件路徑中如果包含中文,則會(huì)出現(xiàn)亂碼

解決方法:將Halcon的文件名編碼格式設(shè)置為utf8,代碼如下:

set_system("filename_encoding", "utf8");

參考鏈接:

(4條消息) VS+Qt應(yīng)用開(kāi)發(fā)-使用Halcon算子實(shí)現(xiàn)從文件夾打開(kāi)圖片、前后瀏覽、縮放居中顯示_羽士的博客-CSDN博客

到此這篇關(guān)于VS+Qt+Halcon 顯示圖片,實(shí)現(xiàn)鼠標(biāo)縮放、移動(dòng)圖片的文章就介紹到這了,更多相關(guān)VS+Qt+Halcon鼠標(biāo)縮放、移動(dòng)圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ const關(guān)鍵字的實(shí)例用法

    C++ const關(guān)鍵字的實(shí)例用法

    在本篇文章里小編給大家整理的是一篇關(guān)于C++ const關(guān)鍵字的實(shí)例用法,需要的朋友們可以學(xué)習(xí)下。
    2020-02-02
  • C語(yǔ)言入門(mén)之浮點(diǎn)數(shù)

    C語(yǔ)言入門(mén)之浮點(diǎn)數(shù)

    這篇文章主要為大家介紹了C語(yǔ)言的浮點(diǎn)數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單學(xué)生成績(jī)管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++使用tinyxml庫(kù)處理XML文件

    C++使用tinyxml庫(kù)處理XML文件

    TinyXML是一個(gè)開(kāi)源的解析XML的解析庫(kù),能夠用于C++,能夠在Windows或Linux中編譯,這個(gè)解析庫(kù)的模型通過(guò)解析XML文件,然后在內(nèi)存中生成DOM模型,從而讓我們很方便的遍歷這棵XML樹(shù),本文為大家介紹的是使用tinyxml庫(kù)處理XML文件,需要的可以參考一下
    2023-07-07
  • C語(yǔ)言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié)

    C語(yǔ)言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié)

    這篇文章主要介紹了C語(yǔ)言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié),是C語(yǔ)言入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C/C++實(shí)現(xiàn)推箱子小游戲

    C/C++實(shí)現(xiàn)推箱子小游戲

    這篇文章主要為大家詳細(xì)介紹了C/C++實(shí)現(xiàn)推箱子小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C++實(shí)現(xiàn)LeetCode(123.買(mǎi)股票的最佳時(shí)間之三)

    C++實(shí)現(xiàn)LeetCode(123.買(mǎi)股票的最佳時(shí)間之三)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(123.買(mǎi)股票的最佳時(shí)間之三),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++簡(jiǎn)單集合類(lèi)的實(shí)現(xiàn)方法

    C++簡(jiǎn)單集合類(lèi)的實(shí)現(xiàn)方法

    如何使用C++實(shí)現(xiàn)一個(gè)簡(jiǎn)單的集合類(lèi),這篇文章主要介紹了C++簡(jiǎn)單集合類(lèi)的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2016-07-07
  • C++基于easyx實(shí)現(xiàn)迷宮游戲

    C++基于easyx實(shí)現(xiàn)迷宮游戲

    這篇文章主要為大家詳細(xì)介紹了C++基于easyx實(shí)現(xiàn)迷宮游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • bloom filter概念講解以及代碼分析

    bloom filter概念講解以及代碼分析

    Bloom filter 優(yōu)點(diǎn)就是它的插入和查詢(xún)時(shí)間都是常數(shù),另外它查詢(xún)?cè)貐s不保存元素本身,具有良好的安全性
    2013-09-09

最新評(píng)論