本文涉及面較廣,因此很難在所有方面都講解得很詳細,故適合具有一定Halcon開發經驗的人閱讀。
1、Halcon二次開發的兩種方式
① 使用C#的語法方式逐句改寫Halcon代碼
優點:各種變量的類型清楚,可讀性強,改寫后代碼行數幾乎不會增加多少。
缺點:改寫工作量大,容易出錯,如果Halcon代碼量大,后期將難以更新維護。
② 封裝成函數導出 (推薦)
優點:操作簡單,對開發人員編程能力要求低,工作量少,且便於維護。
缺點:Halcon函數導出的代碼可讀性極低,一旦丟失原Halcon文件,二次開發程序將難以更新維護。
建議:主二副一。
2、Halcon聯合C#開發必備的設置步驟(Halcon 12 + Visual studio 2013)
① 在項目“引用”中添加halcondotnet.dll。其一般路徑如下:
C:\Program Files\MVTec\HALCON-12.0\bin\dotnet35\halcondotnet.dll
② 在“工具箱”的“選擇項”中添加hWindowControl控件,這是Halcon 12唯一提供的控件
③ 在用到Halcon代碼的類頂部添加using HalconDotNet;
④ 在“屬性”——“生成”中將目標平台由“Any CPU”改為“x64”(計算機推薦使用64位系統)
⑤ 如果安裝Halcon時不是安裝在默認路徑,可能需要將halcon.dll文件復制到當前項目的輸出路徑下,halcon.dll的路徑為:C:\Program Files\MVTec\HALCON-12.0\bin\x64-win64\halcon.dll
3、Halcon圖形元素的顯示
hWindowControl1.HalconWindow.DispObj(image);//顯示圖像、Region、Xld
hWindowControl1.HalconWindow.SetDraw("margin");//設置填充的模式
hWindowControl1.HalconWindow.SetColor("green");//設置顯示顏色
4、系統全局參數設置(非必要,但建議設置)
HOperatorSet.SetSystem("do_low_error", "false");//少報錯
HOperatorSet.SetSystem("clip_region", "false");//region在圖像外不切掉
HOperatorSet.SetSystem("border_shape_models", "true");//依然匹配邊緣的圖形
5、調試
C#中Halcon部分代碼的調試不太方便,但也不是毫無辦法。
① 調試時HTuple類型的變量可以直接查看值。
② Image、Region、Xld的變量一般只能通過“保存文件到本地”來查看變量情況。
HOperatorSet.WriteImage(image, "jpg", 0x000000, "1.jpg");//彩色圖像
HOperatorSet.WriteImage(image, "jpg", 0, "1.jpg");//灰度圖像
HOperatorSet.WriteRegion(ho_RegionUnion, "1.hobj");//后綴用.reg也行
HOperatorSet.WriteContourXldDxf(contours,"1.dxf");
③ 安裝Halcon的變量檢查插件到Visual Studio。該安裝文件所在的默認路徑為:
C:\Program Files\MVTec\HALCON-12.0\misc\HALCON_Variable_Inspect.vsix
6、在hWindowControl控件中顯示文字
以下兩個函數的內容由Halcon中的set_display_font和disp_message算子導出,可完成控件中的文字顯示。
set_display_font(windowHandle, hv_TextSize, "mono", "true", "false");
disp_message(windowHandle, hv_Text, "window", row, col, hv_Color,"true");
7、格式轉換
① HTuple兼容int、double等數據類型
② HObject類型的圖像兼容HImage類型的圖像
③ Bitmap轉Himage(24位或8位的)的方法如下:
1 public static HImage Bitmap2HImage_24(Bitmap bImage) 2 { 3 Bitmap bImage24; 4 BitmapData bmData = null; 5 Rectangle rect; 6 IntPtr pBitmap; 7 IntPtr pPixels; 8 HImage hImage = new HImage(); 9 rect = new Rectangle(0, 0, bImage.Width, bImage.Height); 10 bImage24 = new Bitmap(bImage.Width, bImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 11 System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bImage24); 12 g.DrawImage(bImage, rect); 13 g.Dispose(); 14 bmData = bImage24.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); 15 pBitmap = bmData.Scan0; 16 pPixels = pBitmap; 17 hImage.GenImageInterleaved(pPixels, "bgr", bImage.Width, bImage.Height, -1, "byte", 0, 0, 0, 0, -1, 0); 18 bImage24.UnlockBits(bmData); 19
20 return hImage; 21 }
1 public static HImage Bitmap2HImage_8(Bitmap bImage) 2 { 3 Bitmap bImage8; 4 BitmapData bmData = null; 5 Rectangle rect; 6 IntPtr pBitmap; 7 IntPtr pPixels; 8 var hImage = new HImage(); 9 rect = new Rectangle(0, 0, bImage.Width, bImage.Height); 10 bmData = bImage.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); 11 pBitmap = bmData.Scan0; 12 pPixels = pBitmap; 13 hImage.GenImage1("byte", bImage.Width, bImage.Height, pPixels); 14 bImage.UnlockBits(bmData); 15 //formathimage = hImage;
16 return hImage; 17 }
8、在hWindowControl控件中縮放圖像
在hWindowControl中鼠標位置可用GetMposition獲得,SetPart可改變窗口中顯示的圖像部分。
HOperatorSet.GetMposition(hWHandle, out mouseY, out mouseX, out mbutton);
HOperatorSet.SetPart(hWHandle, mRow1, mCol1, mRow2, mCol2);
set_part:用於修改窗口中顯示的圖像部分。(Row1,Column1) 表示要顯示的圖像部分的左上角, (Row2,Column2)表示要顯示的圖像部分的右下角。(詳見dev_set_part和set_part的幫助文檔)
9、Halcon圖形元素與其他圖像算法庫數據的交互
Halcon的Region、Xld是自己的特有格式,它們與外界是不通用的。目前我研究出來的主要是通過將坐標點作為橋梁來與外界進行數據交互。
Region轉化為坐標點:get_region_polygon(Region : : Tolerance : Rows, Columns)
坐標點轉化為Region:gen_region_polygon_filled( : Region : Rows, Columns : )
Xld轉化為坐標點 :get_contour_xld(Contour : : : Row, Col)
坐標點轉化為Xld :gen_contour_polygon_xld( : Contour : Row, Col : )