Halcon例程分析20:Halcon多線程處理圖像

打開halcon,按下ctrl+e打開halcon自帶例程。應用範圍->二維碼識別->par_start.hdev

* This is a simple example program that demonstrates the
* Aoption to call  several HLtoCON operars or procedures in parallel.
* In general, owing to the overheadof thread creation,
* not in all cases a speedup can be expected,
* especially, if the used operators are already parallelized
* internally using the automatic operator parallelization.
* 
* Number of loops to get a more robust time measurement
Loops := 3
* 
* Initialize visualization
dev_update_off ()
dev_close_window ()
read_image (Image, 'barcode/mixed/barcodes_datacodes_mixed_01')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
disp_message (WindowHandle, 'Read codes sequentially and multithreaded (multiple times)', 'window', 12, 12, 'black', 'true')
* 
* Part A
* 
* Show thread creation overhead
* 
* Thread creation causes a significant overhead.
* Therefore, it is not advisable to create threads for fast tasks.
* 
count_seconds (T1)
*循環創建3個線程,線程中什麼事情都不做,這裏是爲了測試創建線程花費的時間,這裏是爲了告訴你不要頻繁的創建線程,那樣可能會花費更多的時間
for L := 1 to Loops * 10 by 1
    par_start<Thread1> : do_nothing ()
    par_start<Thread2> : do_nothing ()
    par_start<Thread3> : do_nothing ()
    * par_join basically takes as long as the slowest thread (plus overhead).
    * Use the profiler to check execution times.
    par_join ([Thread1,Thread2,Thread3])
endfor
count_seconds (T2)
* Time needed to create and join the three threads in milliseconds
TimeOverhead := 1000.0 * (T2 - T1) / (Loops * 10)
* 
* Part B
* 
* Show perfect parallelization
* 
* The best speedup can be achieved for long running tasks
* that are not parallelized internally.
* 
*測試一下3個處理時間都爲1s的程序在應用多線程處理後花費的總時間
count_seconds (T1)
for L := 1 to Loops by 1
    par_start<Thread1> : wait_seconds (1)
    par_start<Thread2> : wait_seconds (1)
    par_start<Thread3> : wait_seconds (1)
    * par_join basically takes as long as the slowest thread (plus overhead).
    * Use the profiler to check execution times.
    *等待三個線程全部執行完成
    par_join ([Thread1,Thread2,Thread3])
endfor
count_seconds (T2)
* This should be about 1000 milliseconds
TimeWaitSeconds := 1000.0 * (T2 - T1) / Loops
* 
* Part C
* 
* Read bar codes and data codes in parallel
* 
* 
* Create the bar code and data code models
*創建二維碼模板/這個例程中不只有二維碼,還有ECC,條形碼
create_data_code_2d_model ('QR Code', [], [], QrCodeModel)
create_data_code_2d_model ('Data Matrix ECC 200', 'default_parameters', 'maximum_recognition', Ecc200Model)
create_bar_code_model ([], [], BarCodeModel)
* 
* Training
*查找二維碼
find_data_code_2d (Image, QrCodeXldsSeq, QrCodeModel, ['stop_after_result_num','train'], [2,'all'], QrCodeHandlesSeq, QrCodeStringsSeq)
find_data_code_2d (Image, Ecc200XldsSeq, Ecc200Model, ['stop_after_result_num','train'], [2,'all'], Ecc200HandlesSeq, Ecc200StringsSeq)
find_bar_code (Image, BarCodeRegionsSeq, BarCodeModel, ['EAN-13','Code 128'], BarCodeStringsSeq)
* 
* Execute once to fill cache
find_qr_codes (Image, QrCodeXldsSeq, QrCodeModel, QrCodeHandlesSeq, QrCodeStringsSeq)
find_ecc200_codes (Image, Ecc200Xlds, Ecc200Model, Ecc200Handles, Ecc200Strings)
find_bar_codes (Image, BarCodeRegions, BarCodeModel, BarCodeStrings)
* 
* Read codes sequentially
*順序執行處理二維碼查找的問題,計算順序執行所需花費的時間
count_seconds (T1)
for L := 1 to Loops by 1
    find_qr_codes (Image, QrCodeXldsSeq, QrCodeModel, QrCodeHandlesSeq, QrCodeStringsSeq)
    find_ecc200_codes (Image, Ecc200Xlds, Ecc200Model, Ecc200Handles, Ecc200Strings)
    find_bar_codes (Image, BarCodeRegions, BarCodeModel, BarCodeStrings)
endfor
count_seconds (T2)
* 
TimeSeq := 1000.0 * (T2 - T1) / Loops
* 
* Read codes in parallel
*創建多線程來處理二維碼查找的問題,提升程序執行效率
count_seconds (T1)
for L := 1 to Loops by 1
    *選中函數,按alt+enter快速定位到本地函數中
    par_start<ThreadQRCode> : find_qr_codes (Image, QrCodeXlds, QrCodeModel, QrCodeHandlesSeq, QrCodeStringsSeq)
    par_start<ThreadECC200> : find_ecc200_codes (Image, Ecc200Xlds, Ecc200Model, Ecc200Handles, Ecc200Strings)
    par_start<ThreadBarcode> : find_bar_codes (Image, BarCodeRegions, BarCodeModel, BarCodeStrings)
    * par_join basically takes as long as the slowest thread (plus overhead).
    *等待三個線程全部執行完成
    par_join ([ThreadQRCode,ThreadECC200,ThreadBarcode])
endfor
count_seconds (T2)
TimePar := 1000.0 * (T2 - T1) / Loops
* 
* Calculate speedup
Speedup := 100 * ((TimeSeq / TimePar) - 1)
* 
* Display result
dev_set_draw ('margin')
dev_set_line_width (4)
dev_set_color ('yellow')
dev_display (QrCodeXlds)
dev_set_color ('green')
dev_display (Ecc200Xlds)
dev_set_color ('cyan')
dev_display (BarCodeRegions)
Color := ['forest green','red']
disp_message (WindowHandle, 'Multithreading speedup: ' + Speedup$'.2f' + '%', 'window', 42, 12, Color[Speedup < 1], 'true')
* 
clear_bar_code_model (BarCodeModel)
clear_data_code_2d_model (Ecc200Model)
clear_data_code_2d_model (QrCodeModel)

以上通過創建多線程處理圖像,通過創建線程調用本地函數來處理圖像,那麼本地函數怎麼創建呢?

1、在程序編輯器上單機右鍵

2、添加新函數,輸入新函數名稱

3、確定函數的輸入輸出參數,通過加號自由添加刪除

(1)輸入圖像參數

(2)輸出圖像參數

(3)輸入控制參數

(4)輸出參數

4、後續需要更改本地函數的輸入輸出參數時,點擊圓圈處按鈕

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章