Halcon/C++提供了構(gòu)造函數(shù),主要基于適合的Halcon算子。比如說HImage和HBarCode基于read_image and create_bar_code_model。
請注意當前的Halcon版本針對不同的算子構(gòu)造函數(shù)的功能不同。如下我們介紹了一些最常用的Halcon算子,而一個完整的構(gòu)造函數(shù)列表可以在%HALCONROOT%\include\cpp中找到。
- Images:
HImage基于算子read_image,gen_image1,gen_image1_extern,and gen_image_const提供了構(gòu)造器。
在通過HImage使用其構(gòu)造函數(shù)時請注意以下的陷阱:與直覺正好相反,該算子并不能修改調(diào)用它的實例,相反,被創(chuàng)建好的圖像需要通過算子返回值返回。這樣,我們看如下的代碼,事實上并沒有初始化圖像.
HImage image;
image.ReadImage("barcode/ean13/ean1301"); // incorrect
正確的方法是:
image = HImage::ReadImage("barcode/ean13/ean1301"); // correct
從上面可以看出ReadImage是靜態(tài)成員函數(shù)。
注意: HImage作為輸出參數(shù)出現(xiàn)的任何算子都要注意這種陷阱,例如GrabImage.
- Regions:
類HRegion提供了基于像gen_rectangle2 or gen_circle生成的構(gòu)造函數(shù)。并且,也提供了直接的派生類HRectangle2 or HCircle.
請注意HRegion也表現(xiàn)了和HImage一樣的陷阱。比如像GenRectangle2并不能直接修改調(diào)用它的實例HRegion,但是可以返回生成的初始化region.
XLDs:
XLDs(HXLD,HXLDCont等等)沒有提供相應(yīng)的構(gòu)造函數(shù)。Windows:
類HWindow提供了基于open_window and new_extern_window的構(gòu)造函數(shù).注意:前者(指open_window)對于所有的參數(shù)可以使用默認值實現(xiàn),這樣就可以生成默認的構(gòu)造器,因此一旦創(chuàng)建即打開。
當然了,你可以選擇使用CloseWindow關(guān)閉窗口,然后使用OpenWindow再次打開它。
與圖形化參數(shù)不同,你可以用一個直觀的方式使用HWindow實例調(diào)用“類構(gòu)造器”樣的算子如OpenWindow。因此,對應(yīng)的句柄被返回。
- Other Handle Classes:
其他封裝了句柄的類,如HBarCode 和 HFramegrabber,更系統(tǒng)地提供了構(gòu)造函數(shù):如果類作為輸入?yún)?shù)出現(xiàn)在算子中,則自動存在一個基于此算子的構(gòu)造函數(shù)。這樣 ,基于create_bar_code_model創(chuàng)建了HBarcode,基于create_shape_model創(chuàng)建了HShapeModel,基于open_framegrabber創(chuàng)建了HFramegrabber.
與圖形化的參數(shù)不同,句柄類允許用一個直觀的方式使用類實例調(diào)用“類構(gòu)造器”樣的算子,并且調(diào)用對象被修改。比如,你可以創(chuàng)建一個帶有默認構(gòu)造器的HBarCode對象,并且使用CreateBarCodeModel初始化它。
HBarCode barcode;
barcode.CreateBarCodeModel(HTuple(), HTuple());
如果對象已經(jīng)被初始化,在調(diào)用和重新初始化之前,原先的數(shù)據(jù)將自動銷毀。
2.4 析構(gòu)函數(shù)和Halcon算子
所有的HALCON/C++類都提供了默認的析構(gòu)函數(shù)用來自動銷毀對應(yīng)的內(nèi)存。對于某些類,析構(gòu)函數(shù)基于適合的算子:
Windows:
HWindow類的析構(gòu)函數(shù)基于close_window關(guān)閉窗口。注意:算子本身不是析構(gòu)器。你可以選擇調(diào)用CloseWindow關(guān)閉窗口,并且使用OpenWindow再次打開它。Other Handle Classes:
其他句柄類的默認析構(gòu)函數(shù),如HShapeModel or HFramegrabber ,相應(yīng)地應(yīng)用了像clear_shape_model and close_framegrabber算子。與close_window不同,這些算子不能通過類對象調(diào)用,這個對于clear_all_shape_models一樣適用。事實上,你沒必要調(diào)用調(diào)用它,直接重新初始化即可,如5.2節(jié)描述的那樣。
請注意: 你不能調(diào)用適用類對象來調(diào)用如下的算子:clear_shape_model,clear_all_shape_models, or close_framegrabber
2.5 Tuple模式
所謂tuple模式就是HALCON算子被調(diào)用。用這種模式,你可以使用一個簡單的調(diào)用區(qū)處理許多圖像或者區(qū)域。標準情況下,用一張單獨的照片去調(diào)用一個算子叫做簡單模式。一個算子是否支持這種tuple模式可以在查詢手冊中查詢。比如,看下圖5.5,展現(xiàn)了算子char_threshold的用法。
觀察算子的說明,參數(shù)Image被描述成一個image(-array);這表明你可以應(yīng)用此算子一次性到多個圖片。
如果你使用多張圖片調(diào)用算子char_threshold,比如說,用一個圖像數(shù)組,那么輸出參數(shù)也自動變?yōu)閿?shù)組。因此,參數(shù)Characters and Threshold被描述成region(-array)和integer(-array).
注意觀察圖5.5的算子簽名,我們發(fā)現(xiàn)面向過程的方法,調(diào)用char_threshold的簡單模式和數(shù)組模式僅僅在輸出參數(shù)Threshold上不同:一個指向long的指針,一個指向long的數(shù)組的指針。
面向?qū)ο蟮姆椒ǎ唵文J胶蛿?shù)組模式關(guān)于圖形化參數(shù)使用了不同的類:HImage and HRegion vs.HImageArray and HRegionArray.正如面向過程的方法一樣,控制參數(shù)可以是基本類型(僅僅簡單模式)或者HTuple類型(簡單和數(shù)組模式)
在看了理論上的介紹后,我們來看一個簡單的例子。圖5.6,char_threshold被應(yīng)用于簡單模式,即一幅單個的圖片,圖5.7 一次性應(yīng)用于兩張圖片。
HImageArray images;
HRegionArray regions;
HTuple thresholds;
for (int i=1; i<=2; i++)
{
images[i-1] = HImage::ReadImage(HTuple("alpha") + i);
}
regions = images.CharThreshold(images[0].GetDomain(), 2, 95, &thresholds);
for (int i=0; i<images.Num(); i++)
{
images[i].Display(window);
regions[i].Display(window);
cout << "Threshold for 'alpha" << i+1 << "': " << thresholds[i].L();
window.Click();
Hobject images, image;
Hobject regions, region;
long num;
HTuple thresholds;
gen_empty_obj(&images);
for (int i=1; i<=2; i++)
{
read_image(&image, HTuple("alpha") + i);
concat_obj(images, image, &images);
}
char_threshold(images, image, ®ions, 2, 95, &thresholds);
count_obj(images, &num);
for (int i=0; i<num; i++)
{
select_obj(images, &image, i+1);
disp_obj(image, window);
select_obj(regions, ®ion, i+1);
disp_obj(region, window);
cout << "Threshold for 'alpha" << i+1 << "': " << thresholds[i].L();
}
Figure 5.7: Using CharThreshold in tuple mode, via HImageArray, or in the procedural approach (declaration and opening of window omitted).
兩個例子都使用面向?qū)ο蠛兔嫦蜻^程的方法實現(xiàn)。例子中概括了以下幾個有趣的點:
圖形化數(shù)組的創(chuàng)建和初始化:
在面向?qū)ο蟮姆椒ㄖ校瑘D像數(shù)組可以通過眾所周知的運算符[]來創(chuàng)建。而面向過程的方法,你必須使用gen_empty_obj創(chuàng)建一個空的對象(即數(shù)組),然后通過concat_obj增加圖像。訪問圖形化對象
正如所期望的那樣,在面向?qū)ο蟮姆椒ㄖ校瑔蝹€圖像和區(qū)域可以通過[]來訪問;數(shù)組的個數(shù)可以通過方法Num()來獲得。而面向過程的方法中,對象必須顯式地使用算子select_obj來獲得;個數(shù)必須通過count_obj獲得。Hobject的多態(tài)性:(part I)
正如已經(jīng)提到的那樣,Hobject的實例既可以使用簡單模式也可以使用數(shù)組模式。但是與之相反的是,面向?qū)ο蟮姆椒ㄖ挟攺暮唵文J角袚Q到數(shù)組模式時,你必須使用不同的類。Hobject的多態(tài)性:(part II)
Hobject可以用于所有圖形化對象。并且,圖像對象可以當做region使用作為參數(shù)。在這種情況下,圖像的domain,即像素“有效”的區(qū)域(即ROI)
自動提取。而面向?qū)ο蟮姆椒ǎ惚仨毷褂肎etDomain顯式地提取。Array(tuple) indices:(數(shù)組目錄)
面向?qū)ο蟮膱D形化數(shù)組以0開始,比如對于HTuple就是這樣。但是Hobject數(shù)組就是從1開始。
大多數(shù)時候,你將使用數(shù)組模式:只要你通過算子Connection將一個region分成連通的區(qū)域,你就將以HRegionArray結(jié)束。這樣,任何子序列的處理,比如形態(tài)學處理,像DilationCircle or 或者使用AreaCenter計算region的位置都將自動在數(shù)組的所有區(qū)域中呈現(xiàn),也就是數(shù)組模式。這樣,數(shù)組模式終究也是一個簡單的模式!