Halcon11與VS2010聯合開發

来源:http://www.cnblogs.com/oucsheep/archive/2016/09/12/5866471.html
-Advertisement-
Play Games

剛開始學習Halcon,需要使用Halcon與C++聯合開發軟體,查了網上的資料都是Halcon10的,我用的是Halcon11和VS2010的開發環境,實踐了一下發現有一些問題,於是把自己的配置的過程寫出來共用一下。 首先新建一個Halcon工程,這裡用個讀入圖片的簡單例子。 新建一個Halcon... ...


剛開始學習Halcon,需要使用Halcon與C++聯合開發軟體,查了網上的資料都是Halcon10的,我用的是Halcon11和VS2010的開發環境,實踐了一下發現有一些問題,於是把自己的配置的過程寫出來共用一下。

首先新建一個Halcon工程,這裡用個讀入圖片的簡單例子。

新建一個Halcon 程式,輸入以下代碼:

read_image (Image, 'C:/Users/lenovo/Desktop/test.jpg')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_clear_window ()
dev_display (Image)

其實就是打開一個視窗並顯示桌面上的一幅畫

然後將Halcon程式導出為C++程式

在halcon中點擊菜單欄的文件->導出。

導出之後就能在桌面上看到一個Halcon.cpp文件,這個文件的內容如下:

先聲明並給出了函數dev_open_window_fit_imageImage 2 的定義:

void dev_open_window_fit_image (HObject ho_Image, HTuple hv_Row, HTuple hv_Column,
    HTuple hv_WidthLimit, HTuple hv_HeightLimit, HTuple *hv_WindowHandle);

然後是函數Action的定義,Action里的代碼對應著剛纔Halcon中的代碼,簡單地說,就是把Halcon語言翻譯成C++了。

// Main procedure 
void action()
{
  // Local iconic variables 
  HObject  ho_Image;
  // Local control variables 
  HTuple  hv_WindowHandle;
  ReadImage(&ho_Image, "C:/Users/lenovo/Desktop/test.jpg");
  dev_open_window_fit_image(ho_Image, 0, 0, -1, -1, &hv_WindowHandle);
  if (HDevWindowStack::IsOpen())
    ClearWindow(HDevWindowStack::GetActive());
  if (HDevWindowStack::IsOpen())
    DispObj(ho_Image, HDevWindowStack::GetActive());
}

配置VS2010

為了一勞永逸的配置好VS2010,讓我們在以後每次新建工程的時候都不用重新添加這些亂七八糟的配置項,需要採用以下的技巧。首先新建一個基於對話框的MFC程式,然後點擊菜單欄的視圖->屬性管理器,在左側的屬性管理器中,預設會有32位的Debug和Release屬性。對64位的系統(現在電腦一般都是64位系統),需要點擊菜單欄的生成->配置管理器,把平臺選項改為x64,這樣生成的文件就可以在64位系統下運行了。

Image 3

改完之後,屬性管理器還不會立馬變化,關閉項目再重新開啟就能看到新增的x64屬性了。

image

下麵以64位的Debug屬性為例,介紹一下halcon 11的配置。

在User屬性上點擊右鍵,選擇屬性,進入屬性頁面。

image

向通用屬性下的VC++目錄中的包含目錄中添加如下目錄,據說halcon11需要包含halconcpp這個文件夾就夠了,halcon10則是cpp。我用的是halcon11,打開安裝目錄之後發現兩個文件夾都有,於是就把倆目錄都添加進去了。

image

下一步是VC++目錄中的庫目錄。

image

目錄中的環境變數HALCONROOT是安裝Halcon時自動寫入到系統環境變數中的。

繼續,在C/C++目錄中,為附加包含目錄添加下麵兩項(當然也可以添加$(HALCONROOT)\include\cpp這一項,並無影響)

image

最有一項,配置鏈接器。在常規項的附加庫目錄中添加$(HALCONROOT)\lib\$(HALCONARCH),同樣,HALCONARCH是環境變數。

image

為輸入的附加依賴項添加halconcpp.lib。

image

至此,配置完畢。

註意,採用這種方式配置,以後新建的工程都會繼承這些配置,無需重新配置,非常方便。

MFC程式

點擊菜單欄中的視圖->資源視圖,併在資源視圖中打開對話框。

image

為了實現顯示圖片的功能,在對話框中添加一個按鈕,並雙擊按鈕進入事件響應函數,空空如也,待我們填寫。

void CHalconVCDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控制項通知處理程式代碼
}

首先在HalconVCDlg.h中添加頭文件及命名空間,因為等會要在這個頭文件里添加halcon函數的聲明。然後在HalconVCDlg.cpp中也添加上述頭文件及命名空間,因為要在這裡調用halcon的函數。

#include "halconcpp.h" 

using namespace HalconCpp;

打開剛剛導出的Halcon.cpp,為了能夠在MFC中調用dev_open_window_fit_image 這個函數,需要把它的聲明和定義都放進MFC程式中。聲明拷貝到HalconVCDlg.h中,註意要放在對話框類聲明外面,定義拷貝到HalconVCDlg.cpp中。

下麵進行最重要的一部,把Action中的代碼拷貝到OnBnClickedButton1() 中,這樣點擊按鈕就會執行在halcon中實現的顯示圖片功能了。

Action函數中定義了兩個變數
HObject ho_Image;
HTuple hv_WindowHandle; 
為了在Button1的響應函數中使用這兩個變數,之前博文中的作法是將其定義為HalconVCDlg.h中對話框類的成員變數,事實上,直接定義在void CHalconVCDlg::OnBnClickedButton1() 函數中或者是HalconVCDlg.cpp文件中也是沒有問題的,但是定義在HalconVCDlg.h中作為HalconVCDlg的類外變數卻不行
瞭解到這一點,我們就可以直接把Action函數中所有東西一起拷貝進OnBnClickedButton1()了。
  // Local iconic variables 
  HObject  ho_Image;
  // Local control variables 
  HTuple  hv_WindowHandle;
  ReadImage(&ho_Image, "C:/Users/lenovo/Desktop/test.jpg");
  dev_open_window_fit_image(ho_Image, 0, 0, -1, -1, &hv_WindowHandle);
  if (HDevWindowStack::IsOpen())
    ClearWindow(HDevWindowStack::GetActive());
  if (HDevWindowStack::IsOpen())
    DispObj(ho_Image, HDevWindowStack::GetActive());

運行結果

每點擊一次Button1就會彈出一個視窗顯示我們的圖片(沒錯,這是一張我桌面的截圖)

image

全部程式代碼

MFC程式中HalconVCDlg.h

// HalconVCDlg.h : 頭文件
#pragma once

//與halcon有關的頭文件
#include "halconcpp.h"
using namespace HalconCpp;

// CHalconVCDlg 對話框
class CHalconVCDlg : public CDialogEx
{
// 構造
public:
	CHalconVCDlg(CWnd* pParent = NULL);	// 標準構造函數
	//Halcon中用到的變數,為何要定義為類中的變數
	//HObject  ho_Image;
	//HTuple  hv_WindowHandle;
// 對話框數據
	enum { IDD = IDD_HALCONVC_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

// 實現
protected:
	HICON m_hIcon;

	// 生成的消息映射函數
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedButton1();
};
void dev_open_window_fit_image (HObject ho_Image, HTuple hv_Row, HTuple hv_Column, 
    HTuple hv_WidthLimit, HTuple hv_HeightLimit, HTuple *hv_WindowHandle);
MFC程式中HalconVCDlg.cpp
// HalconVCDlg.cpp : 實現文件
#include "stdafx.h"
#include "HalconVC.h"
#include "HalconVCDlg.h"
#include "afxdialogex.h"
//與halcon有關的頭文件
#include "halconcpp.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

using namespace HalconCpp;
中間省略一堆系統生成的函數,下麵是我們主要的改動
 
// Procedures 
// Chapter: Develop
// Short Description: Open a new graphics window that preserves the aspect ratio of the given image. 
void dev_open_window_fit_image (HObject ho_Image, HTuple hv_Row, HTuple hv_Column, 
    HTuple hv_WidthLimit, HTuple hv_HeightLimit, HTuple *hv_WindowHandle)
{

  // Local control variables 
  HTuple  hv_MinWidth, hv_MaxWidth, hv_MinHeight;
  HTuple  hv_MaxHeight, hv_ResizeFactor, hv_ImageWidth, hv_ImageHeight;
  HTuple  hv_TempWidth, hv_TempHeight, hv_WindowWidth, hv_WindowHeight;

  //This procedure opens a new graphics window and adjusts the size
  //such that it fits into the limits specified by WidthLimit
  //and HeightLimit, but also maintains the correct image aspect ratio.
  //
  //If it is impossible to match the minimum and maximum extent requirements
  //at the same time (f.e. if the image is very long but narrow),
  //the maximum value gets a higher priority,
  //
  //Parse input tuple WidthLimit
  if (0 != (HTuple((hv_WidthLimit.TupleLength())==0).TupleOr(hv_WidthLimit<0)))
  {
    hv_MinWidth = 500;
    hv_MaxWidth = 800;
  }
  else if (0 != ((hv_WidthLimit.TupleLength())==1))
  {
    hv_MinWidth = 0;
    hv_MaxWidth = hv_WidthLimit;
  }
  else
  {
    hv_MinWidth = ((const HTuple&)hv_WidthLimit)[0];
    hv_MaxWidth = ((const HTuple&)hv_WidthLimit)[1];
  }
  //Parse input tuple HeightLimit
  if (0 != (HTuple((hv_HeightLimit.TupleLength())==0).TupleOr(hv_HeightLimit<0)))
  {
    hv_MinHeight = 400;
    hv_MaxHeight = 600;
  }
  else if (0 != ((hv_HeightLimit.TupleLength())==1))
  {
    hv_MinHeight = 0;
    hv_MaxHeight = hv_HeightLimit;
  }
  else
  {
    hv_MinHeight = ((const HTuple&)hv_HeightLimit)[0];
    hv_MaxHeight = ((const HTuple&)hv_HeightLimit)[1];
  }
  //
  //Test, if window size has to be changed.
  hv_ResizeFactor = 1;
  GetImageSize(ho_Image, &hv_ImageWidth, &hv_ImageHeight);
  //First, expand window to the minimum extents (if necessary).
  if (0 != (HTuple(hv_MinWidth>hv_ImageWidth).TupleOr(hv_MinHeight>hv_ImageHeight)))
  {
    hv_ResizeFactor = (((hv_MinWidth.TupleReal())/hv_ImageWidth).TupleConcat((hv_MinHeight.TupleReal())/hv_ImageHeight)).TupleMax();
  }
  hv_TempWidth = hv_ImageWidth*hv_ResizeFactor;
  hv_TempHeight = hv_ImageHeight*hv_ResizeFactor;
  //Then, shrink window to maximum extents (if necessary).
  if (0 != (HTuple(hv_MaxWidth<hv_TempWidth).TupleOr(hv_MaxHeight<hv_TempHeight)))
  {
    hv_ResizeFactor = hv_ResizeFactor*((((hv_MaxWidth.TupleReal())/hv_TempWidth).TupleConcat((hv_MaxHeight.TupleReal())/hv_TempHeight)).TupleMin());
  }
  hv_WindowWidth = hv_ImageWidth*hv_ResizeFactor;
  hv_WindowHeight = hv_ImageHeight*hv_ResizeFactor;
  //Resize window
  SetWindowAttr("background_color","black");
  OpenWindow(hv_Row,hv_Column,hv_WindowWidth,hv_WindowHeight,0,"","",&(*hv_WindowHandle));
  HDevWindowStack::Push((*hv_WindowHandle));
  if (HDevWindowStack::IsOpen())
    SetPart(HDevWindowStack::GetActive(),0, 0, hv_ImageHeight-1, hv_ImageWidth-1);
  return;
}

void CHalconVCDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控制項通知處理程式代碼
	HObject  ho_Image;
	HTuple  hv_WindowHandle;
	ReadImage(&ho_Image, "C:/Users/lenovo/Desktop/test.jpg");
   dev_open_window_fit_image(ho_Image, 0, 0, -1, -1, &hv_WindowHandle);
	//open_window(0,0,600,600,0,"","",&hv_WindowHandle);
  if (HDevWindowStack::IsOpen())
    ClearWindow(HDevWindowStack::GetActive());
  if (HDevWindowStack::IsOpen())
    DispObj(ho_Image, HDevWindowStack::GetActive());
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 從微軟推出第一個版本的.NET Framework的時候,就在“System.Diagnostics”命名空間中提供了Debug和Trace兩個類幫助我們完成針對調試和跟蹤信息的日誌記錄。在.NET Framework 2.0中,微軟引入了TraceSource並對跟蹤日誌系統進行了優化,優化後的跟... ...
  • 將特定用戶代理的別名添加到用戶代理別名的內部集合中。 來自 <https://msdn.microsoft.com/zh-cn/library/6379d90d(v=vs.110).aspx> 用戶代理別名的集合指示 ASP.NET 伺服器控制項應為其呈現內容的目標用戶代理。其信息可以在Page.Cl ...
  • Google的ProtoBuf序列化器性能的牛逼已經有目共睹了,可以把它應用到Socket通訊,隊列,Wcf中,身為dotnet程式員一邊期待著不久後Grpc對dotnet core的支持更期待著Wcf有一天能在Linux平臺上閃瞎所有人。現在簡單表述下Wcf中應用ProtoBuf替代預設的序列化器 ...
  • 前言 面向對象的思想已經非常成熟,而使用C 的程式員對面向對象也是非常熟悉,所以我就不對面向對象進行介紹了,在這篇文章中將只會介紹面向對象在F 中的使用。 F 是支持面向對象的函數式編程語言,所以你用C 能做的,用F 也可以做,而且通常代碼還會更為 簡潔 。我們先看下麵這個用C 定義的類,然後用F ...
  • 1、目標 1、目標 代碼編寫規範、整齊、整潔、可讀。 無錯誤 無警告 2、排版 2、排版 安裝PowerCommands擴展 “工具”-“擴展管理庫”,搜索安裝。 設置選中Format document on save和Remove and Sort Usings on save 這樣代碼保存時會自 ...
  • 走進非同步編程的世界 - 剖析非同步方法(下) 序 感謝大家的支持,這是昨天發佈《走進非同步編程的世界 - 剖析非同步方法(上)》的補充篇。 目錄 異常處理 在調用方法中同步等待任務 在非同步方法中非同步等待任務 Task.Delay() 暫停執行 一、異常處理 await 表達式也可以使用 try...cat ...
  • 不知道可能稱的上是ORM,其實就是一個DBHelper。看到網上不少人寫自己的ORM,但我覺得都不太好。 我這個ORM,學習成本非常低,常用的方法僅有幾個,在使用的過程中,你不需要有太多要註意的地方,也不會有“我怎樣實現連表查詢”的疑問。反射犧牲一些性能,但是降低了實現和使用的複雜度。 支持Orac ...
  • 一、前言 MD5驗證主要用於更新文件功能方面,伺服器告知客戶端要下載哪些更新文件並提供給客戶端其MD5值,客戶端從伺服器將更新文件下載到本地並計算下載文件的MD5值,將本地接收的MD5值與伺服器提供的MD5值進行比對,如果相同則說明下載的文件與伺服器提供的文件是一致的,如果不相同則說明下載後文件可能 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...