狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#使用Halcon開發(fā)視覺檢測程序

admin
2023年3月10日 16:55 本文熱度 766

簡介

本文的初衷是希望幫助那些有其它平臺視覺算法開發(fā)經(jīng)驗(yàn)的人能快速轉(zhuǎn)入Halcon平臺下,通過文中的示例開發(fā)者能快速了解一個(gè)Halcon項(xiàng)目開發(fā)的基本步驟,讓開發(fā)者能把精力完全集中到算法的開發(fā)上面。

首先,你需要安裝Halcon,HALCON 18.11.0.1的安裝包會放在文章末尾。安裝包分開發(fā)和運(yùn)行時(shí)兩個(gè)版本,運(yùn)行時(shí)版本一般用于生產(chǎn)環(huán)境。

注:開發(fā)版本自帶運(yùn)行時(shí)可替代運(yùn)行時(shí)版本,但安裝的東西會比較多。

然后,你需要學(xué)會查看Halcon的幫助手冊,這是很重要的一件事

本文涉及到幫助文檔的主要章節(jié)如下:

原文 HALCON 18.11.0.1 / Programmer's Guide / Programming With HALCON/.NET
翻譯 HALCON 18.11.0.1/程序員指南/使用 HALCON/.NET 編程

原文 HALCON 18.11.0.1 / HALCON Operator Reference
翻譯 HALCON 18.11.0.1/ HALCON 運(yùn)算符參考

文中的示例是我第一次接觸Halcon時(shí)的學(xué)習(xí)測試用例,在電腦里面躺了一年,最近才有時(shí)間整理一下發(fā)出來,希望能對你有所幫助。

注:運(yùn)行本文示例程序前至少安裝Halcon的運(yùn)行時(shí),否則Halcon的dll無法正常使用

將 HALCON/.NET 添加到應(yīng)用程序

添加控件

右鍵單擊工具箱,然后選擇“選擇項(xiàng)”,彈出的對話框選擇“**.NET Framework組件”,單擊下面的“瀏覽”,導(dǎo)航到HALCON安裝目錄下的\bin\dotnet35(VS2008以下版本的選擇dotnet20) ,然后選擇halcondotnet.dll**。

完成上述操作后,HSmartWindowControl和HWindowControl控件就會出現(xiàn)在工具箱中,其中HWindowControl控件已經(jīng)過時(shí)官方不再推薦使用。

與HWindowControl相比,HSmartWindowControl控件具有以下幾個(gè)優(yōu)點(diǎn):

  • 可以像任何其他控件一樣使用
  • 提供預(yù)定義的鼠標(biāo)交互(移動(dòng)窗口內(nèi)容并使用鼠標(biāo)滾輪進(jìn)行縮放), 可以通過雙擊窗口來重置視圖
  • 控件會自動(dòng)重新縮放,而不會閃爍

注:與HSmartWindowControlWPF 相反,HSmartWindowControl需要一個(gè)回調(diào)才能使用鼠標(biāo)滾輪進(jìn)行縮放

引用dll

在HALCON安裝目錄下的**\bin\dotnet35**中,引用以下dll:

  • hdevenginedotnet.dll
  • halcondotnet.dll

注:使用 HALCON XL 開發(fā)應(yīng)用程序時(shí),必須選擇以xl結(jié)尾的dll,hhdevelop xl適用于大分辨率的圖像(大于 32k x 32k )。

引用以下命名空間:

  • HalconDotNet:控件所在的命名空間
  • HalconTypeLineRectangle2等數(shù)據(jù)類型所在的命名空間

調(diào)用Halcon算子

ReadImage操作為例,函數(shù)原型如下:

static void HOperatorSet.ReadImage(out HObject image, HTuple fileName)

public HImage(HTuple fileName)

public HImage(string fileName)

void HImage.ReadImage(HTuple fileName)

void HImage.ReadImage(string fileName)

注:這些內(nèi)容幫助手冊上都有,在文章開頭列出來的章節(jié)。

在C#調(diào)用HALCON 算子有兩種選擇:函數(shù)式對象式,前值通過HOperatorSet調(diào)用算子并通過out關(guān)鍵字傳入關(guān)鍵對象,后者直接在關(guān)鍵對象上調(diào)用對應(yīng)的方法。兩種方法完全等價(jià),C#是一門面向?qū)ο蟮恼Z言,建議使用對象式的方式調(diào)用算子會好一點(diǎn)。

程序示例

本示例只實(shí)現(xiàn)下面幾種關(guān)鍵功能:

  • 加載、保存圖片
  • 畫線、框并保存
  • 抓邊算法、測寬算法

先新建一個(gè)Winform項(xiàng)目,界面設(shè)計(jì)如下:


注:項(xiàng)目的解決方案平臺不能使用AnyCPU,只能根據(jù)安裝的Halcon位數(shù)選擇x64x86,我使用的是x64平臺。

HSmartWindowControl控件使用

將HSmartWindowControl控件拖入主界面即可,在窗體類里面定義一個(gè)HWindow類型的成員引用控件內(nèi)部的窗體,同時(shí)設(shè)置控件的回調(diào)函數(shù)(WPF則不需要)。

代碼如下:

//窗口實(shí)例
private HWindow hwindow;
       
public Form1()
{
    InitializeComponent();
    hwindow = hSmartWindowControl1.HalconWindow;//初始化窗口變量
    hSmartWindowControl1.MouseWheel += HSmartWindow_MouseWheel;
}

//鼠標(biāo)滾輪回調(diào)
private void HSmartWindow_MouseWheel(object sender, MouseEventArgs e)
{
    Point pt = this.Location;
    MouseEventArgs newe = new MouseEventArgs(e.Button, e.Clicks, e.X - pt.X, e.Y - pt.Y, e.Delta);
    hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, newe);
}

加載、保存圖像

加載、保存圖像也比較簡單,我們需要先定義一個(gè)HImage實(shí)例,然后按鈕單擊事件在該實(shí)例上調(diào)用對應(yīng)的算子,代碼如下:

//圖片變量
private HImage image = new HImage();
//加載圖片
private void button_ReadImage_Click(object sender, EventArgs e)
{           
    string imagePath = "TestRead.bmp";
    image.ReadImage(imagePath);
    hwindow.DispImage(image);
    //自動(dòng)適應(yīng)圖片(相當(dāng)于控件上面的雙擊操作)
    hwindow.SetPart(00-2-2);
}
//保存圖片
private void button_WriteImage_Click(object sender, EventArgs e)
{
    string imagePath = "TestWrite.bmp";
    image.WriteImage("bmp"0, imagePath);
    hwindow.DispImage(image);
}

上面代碼是從程序啟動(dòng)目下加載TestRead.bmp圖片,保存圖片到程序啟動(dòng)目下的TestWrite.bmp,實(shí)際路徑可以根據(jù)項(xiàng)目情況自己定義。

上面的圖片是自己生成的,不是生產(chǎn)環(huán)境下的產(chǎn)品圖片,僅用于程序演示。

擴(kuò)展:加載相機(jī)圖像

大部分項(xiàng)目都是從相機(jī)加載圖片,但這涉及到相機(jī)驅(qū)動(dòng)的一些知識,全部介紹一邊會偏移文章主題。簡單來說,加載相機(jī)圖像分兩步:

  • 將相機(jī)圖像保存到內(nèi)存
  • 將內(nèi)存中的圖像傳入Halcon

將相機(jī)圖像保存到內(nèi)存是相機(jī)驅(qū)動(dòng)的工作,下面只討論怎么將內(nèi)存中的圖像傳入Halcon,代碼如下:

private void GenImageByPtr()
{
    //這三個(gè)參數(shù)都可以通過相機(jī)驅(qū)動(dòng)得到
    byte[] imageBuf = null;   //圖像緩存數(shù)組
    int width = 0;            //圖像寬度
    int heigth = 0;           //圖像高度
    //獲取內(nèi)存圖像中間的指針
    IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(imageBuf, 0);
    //加載內(nèi)存中的圖像
    image.GenImage1("byte", width, heigth, ptr);
    hwindow.DispImage(image);
}

這里只列一個(gè)簡單的示例,類似的算子還有copy_imagegen_image3等。

畫線、畫框并保存

在圖像上畫線、框是機(jī)器視覺里面常見的需求,根據(jù)線、框確定算法搜索的區(qū)域和特征。

在窗體類中定義一個(gè)HDrawingObject對象并附加到現(xiàn)有窗口用于交互,同時(shí)定義好Line對象、Rectangle2對象用于保存繪圖的結(jié)果。

先在圖像窗口上面畫出線和框,然后再用鼠標(biāo)手動(dòng)調(diào)整大小、位置,代碼如下:

//繪圖對象
private HDrawingObject drawingObject = new HDrawingObject();
//線ROI
private Line line = new Line();
//框ROI
private Rectangle2 rectangle2 = new Rectangle2();

private void button_DrawLine_Click(object sender, EventArgs e)
{
    drawingObject.createDrawingObjectLine(100100200200);
    //將繪圖對象關(guān)聯(lián)到Halcon窗口
    hwindow.AttachDrawingObjectToWindow(drawingObject);
}
private void button_SaveLine_Click(object sender, EventArgs e)
{
    HTuple paramName, param;            
    paramName = new HTuple(new string[] { "row1""column1""row2""column2" });
    param = drawingObject.GetDrawingObjectParams(paramName);
    //保存參數(shù)
    line.SetValue(param.ToDArr());
    paramName.Dispose();
    param.Dispose();
    //清除繪圖內(nèi)容
    drawingObject.ClearDrawingObject();         
}
private void button_DrawRect_Click(object sender, EventArgs e)
{
    drawingObject.createDrawingObjectRectangle2(3004000300200);
    //將繪圖對象關(guān)聯(lián)到Halcon窗口
    hwindow.AttachDrawingObjectToWindow(drawingObject);
}
private void button_SaveRect_Click(object sender, EventArgs e)
{
    HTuple paramName, param;
    paramName = new HTuple(new string[] { "row""column""phi""length1""length2" });
    param = drawingObject.GetDrawingObjectParams(paramName);
    //保存參數(shù)
    rectangle2.SetValue(param.ToDArr());
    paramName.Dispose();
    param.Dispose();
    //清除繪圖內(nèi)容
    drawingObject.ClearDrawingObject();
}

上面的paramName可以取以下值,里面包含了LineRectangle2類屬性名:

"color""column""column1""column2""end_angle""font""length1""length2""line_style"
"line_width""phi""radius""radius1""radius2""row""row1""row2""start_angle""string""type"

檢測算法

用Halcon開發(fā)檢測算法一般有兩種方法:

  • 根據(jù)直接調(diào)用Halcon在對應(yīng)語言平臺下的算子接口
  • 用Halcon自帶的腳本語言開發(fā)算法然后轉(zhuǎn)成C#類

第一種自由度比較高,代碼看起來也比較簡潔易懂,但上手比較困難。第二種更簡單,但生成的類很難看,而且與程序集成的時(shí)候需要做一些改動(dòng)。兩種方法并不是絕對對立的,一般會先用Halcon驗(yàn)證算法,然后參考導(dǎo)出的C#類實(shí)現(xiàn)自己的檢測算法。

抓邊算法


2D測量模型

簡述一下2D 測量的使用步驟:

  • 創(chuàng)建測量模型并指定圖像大小:首先必須使用create_metrology_model創(chuàng)建測量模型,然后使用set_metrology_model_image_size指定測量結(jié)果所在的圖像的大小。

  • 提供近似值:將測量對象添加到測量模型中,每個(gè)測量對象由圖像中相應(yīng)對象的近似形狀參數(shù)控制測量的參數(shù)組成,控制測量的參數(shù)包括例如指定測量區(qū)域的尺寸和分布的參數(shù),測量對象有以下幾種:

    • :add_metrology_object_circle_measure
    • 橢圓:add_metrology_object_ellipse_measure
    • 矩形:add_metrology_object_rectangle2_measure
    • :add_metrology_object_line_measure
    • 使用一個(gè)運(yùn)算符創(chuàng)建不同形狀:add_metrology_object_generic

要直觀檢查定義的度量對象,可以使用運(yùn)算符get_metrology_object_model_contour訪問其XLD輪廓。要直觀檢查創(chuàng)建的測量區(qū)域,可以使用運(yùn)算符get_metrology_object_measures訪問其XLD輪廓。


  • 修改模型參數(shù):如果已執(zhí)行相機(jī)校準(zhǔn),則可以使用set_metrology_model_param,沒有就忽略(本示例沒有使用)。
  • 修改對象參數(shù):當(dāng)將測量對象添加到測量模型時(shí),可以設(shè)置許多參數(shù),之后還可以使用運(yùn)算符set_metrology_object_param修改其中的一些(本示例是在添加時(shí)設(shè)置的參數(shù),所以沒有此步驟)。
  • 調(diào)整測量模型:在執(zhí)行下一次測量之前平移和旋轉(zhuǎn)測量模型,可以使用操作員align_metrology_model。通常使用基于形狀的匹配來獲得對準(zhǔn)參數(shù),相當(dāng)于測量前的位置就糾偏(本示例比較簡單沒有此步驟)。
  • 應(yīng)用測量:使用apply_metrology_model執(zhí)行測量過程。
  • 訪問結(jié)果:測量后,可以使用get_metrology_object_result訪問結(jié)果,也可以使用get_metrology_object_measures獲取定位邊的行坐標(biāo)和列坐標(biāo)再進(jìn)一步處理(本示例使用前者)。

代碼實(shí)現(xiàn)

抓變算法的C#代碼如下:

private void button_FindEdge_Click(object sender, EventArgs e)
{
    //創(chuàng)建測量對象
    HMetrologyModel hMetrologyModely = new HMetrologyModel();
    //設(shè)置圖片大小            
    image.GetImageSize(out int width, out int height);
    hMetrologyModely.SetMetrologyModelImageSize(width, height);
    //添加直線測量
    double measureLength1= 30, measureLength2=30, measureSigma=1, measureThreshold=30;
    HTuple genParamName = new HTuple(), genParamValue = new HTuple();
    hMetrologyModely.AddMetrologyObjectLineMeasure(line.Row1, line.Column1,line.Row2, line.Column2, measureLength1, measureLength2, measureSigma, measureThreshold, genParamName, genParamValue);
    //執(zhí)行并獲取結(jié)果
    hMetrologyModely.ApplyMetrologyModel(image);
    //獲取測量區(qū)域
    HTuple mRow = new HTuple(), mCol = new HTuple();
    HXLDCont mContours = hMetrologyModely.GetMetrologyObjectMeasures("all""all"out mRow, out mCol); //檢測區(qū)域輪廓
    HXLDCont mmContours = hMetrologyModely.GetMetrologyObjectModelContour("all"1);    //測量對象輪廓
    //參數(shù)順序 ["row_begin", "column_begin", "row_end", "column_end"]
    HTuple  lineRet =hMetrologyModely.GetMetrologyObjectResult("all""all""result_type""all_param");
    double[] retAry = lineRet.DArr;
    //打印結(jié)果
    hwindow.SetLineWidth(2);
    hwindow.SetColor("green");
    hwindow.DispLine(retAry[0], retAry[1], retAry[2], retAry[3]);
    hwindow.SetColor("blue");
    hwindow.DispXld(mContours);
    hwindow.SetColor("yellow");
    hwindow.DispXld(mmContours);
    //清空測量對象
    hMetrologyModely.ClearMetrologyModel();
    //清理對象
    hMetrologyModely?.Dispose();
    genParamName?.Dispose();
    genParamValue?.Dispose();
    mRow.Dispose();
    mCol.Dispose();
    mContours.Dispose();
    mmContours.Dispose();
}

Halcon的代碼如下:

*讀取圖片
read_image (Image, 'D:/test.bmp')
dev_get_window (WindowHandle)

*畫線
Row1:=1218.79
Column1:=1002.95
Row2:=1242.07
Column2:=2786.18
*draw_line (WindowHandle, Row1, Column1, Row2, Column2)
*gen_region_line (RegionLines, Row1, Column1, Row2, Column2)

*創(chuàng)建測量幾何形狀所需的數(shù)據(jù)結(jié)構(gòu)
create_metrology_model (MetrologyHandle)
get_image_size (Image, Width, Height)
set_metrology_model_image_size (MetrologyHandle, Width, Height)
add_metrology_object_line_measure (MetrologyHandle, Row1, Column1, Row2, Column2, 100, 50, 1, 30, [], [], Index)

apply_metrology_model (Image, MetrologyHandle)

get_metrology_object_result (MetrologyHandle, 'all', 'all', 'result_type','all_param', Parameter)

get_metrology_object_measures(Contours, MetrologyHandle, 'all', 'all', Row, Column)

get_metrology_object_model_contour (Contour, MetrologyHandle, 0, 1.5)

*清空測量對象,否則會導(dǎo)致內(nèi)存泄露
clear_metrology_model (MetrologyHandle)

*可視化
dev_clear_window ()
dev_display(Image)
dev_set_color('green')
dev_set_line_width(1)
disp_line (WindowHandle, Parameter[0], Parameter[1], Parameter[2], Parameter[3])
dev_display (Contours)
dev_display (Contour)

使用方法

直接在界面上點(diǎn)擊“打開圖片”->“畫線ROI”(默認(rèn)位置我都調(diào)好了,你也可以自己調(diào)整大小、位置)->“抓邊”,過程如下:



測寬算法

測寬算法使用一維測量中的measure_pairs算子提取直邊對,然后計(jì)算兩個(gè)直邊的距離。代碼太長這里就不貼了,完整的項(xiàng)目源碼會在文章末尾給出。

需要注意,measure_pairs算子的搜索框必須和目標(biāo)邊緣完全垂直,否則寬度數(shù)據(jù)會不準(zhǔn)確,算子原理如下:


直接在界面上點(diǎn)擊“打開圖片”->“畫框ROI”(默認(rèn)位置我都調(diào)好了,你也可以自己調(diào)整大小、位置)->“測寬”,過程如下:



上面的箭頭就是框的方向,測量邊必須與框的方向接近垂直否則會運(yùn)算失敗,實(shí)際項(xiàng)目中還是建議用2D測量單獨(dú)抓兩個(gè)邊來測寬度。

源碼里面顯示邊緣的DispEdgeMarker方法,是直接從measure_pairs算子示例里面導(dǎo)出轉(zhuǎn)C#的,所以風(fēng)格會比較奇怪。


附件

  • HalconTest

https://pan.baidu.com/s/1Ff6D8jhA2rVFdJa016wpRw提取碼: scy2

  • HALCON 18.11.0.1

https://pan.baidu.com/s/1U-KostYwBFd7dbIpw4gRXQ提取碼: 2i3u


該文章在 2023/3/10 16:55:42 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved