一、Halcon
当谈及计算机视觉领域中强大的工具和框架时,Halcon
(由德国MVTec
公司开发)无疑是一个备受关注的系统。Halcon
被广泛用于工业视觉和机器视觉应用中,其强大的功能和灵活性使其成为许多开发人员和研究人员的首选选择。
Halcon
的独特之处在于其高度优化的图像处理算法和丰富的功能库。它提供了丰富的工具和函数,可以用于解决各种复杂的图像处理问题,包括形状识别、特征提取、匹配、测量和分类、以及深度学习等。其高性能的图像处理算法和优化的数据结构使得在处理大规模图像数据时能够快速而有效地进行分析和处理。
Halcon
还支持多种编程语言,包括C、C++、C#
和Python
等,这使得开发人员可以根据自己的偏好和需求选择合适的编程语言来进行应用开发。其丰富的文档和示例代码也为开发者提供了便利,加速了开发过程。
使用 Python
开发时,需要确保电脑上已经安装了 Halcon
环境,并在环境变量进行了如下配置:
HALCONROOT: Halcon 安装位置,默认情况下为:C:\Program Files\MVTec\HALCON-22.11-Steady
Path
中追加如下变量:
;%HALCONROOT%\bin\x64-win64
然后安装 Python
依赖:
pip install mvtec-halcon==22111.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
注意:版本号要和电脑安装的 Halcon 版本一致:
然后在 Python
中调用 Halcon
也是非常简单,算子和 Halcon
工具中高度保持一致,例如:
import halcon as ha
import os
def open_window(width, height, row=0, col=0):
if os.name == 'nt':
ha.set_system('use_window_thread', 'true')
window = ha.open_window(
row=row,
column=col,
width=width,
height=height,
father_window=0,
mode='visible',
machine=''
)
ha.set_draw(window, 'fill')
ha.set_line_width(window, 2)
ha.set_color(window, 'red')
return window
if __name__ == '__main__':
# 读取图像
image = ha.read_image("printer_chip/printer_chip_01")
# 阈值分割
region = ha.threshold(image, 128, 255)
# 开启一个窗口
window = open_window(500, 500)
# 展示图像
ha.disp_obj(image, window)
ha.disp_obj(region, window)
ha.wait_seconds(5)
下面以口罩图像中定位编号为例:
由于编号会有变化,可以以下面的 CE
为模版,然后每次通过模版定位编号的位置:
二、使用 Halcon 实现过程
首先使用 Halcon
实现过程,然后再转换到 Python
中。
创建模版:
dev_get_window (WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (2)
dev_set_color ('red')
read_image (Image, 'face_masks/face_mask_01')
* 模版区域
gen_rectangle2 (ROI, 616.5, 708.5, rad(-82.4054), 50, 35)
write_region (ROI, 'D:/halcon/test/ROI.hobj')
* 目标区域
gen_rectangle2 (ROI_0, 725.847, 792.482, rad(-83.3001), 236.754, 32.7044)
write_region (ROI_0, 'D:/halcon/test/ROI_0.hobj')
reduce_domain (Image, ROI, ImageReduced)
* 创建 ncc 模型
create_ncc_model (ImageReduced, 'auto', rad(0), rad(360), 'auto', 'use_polarity', ModelID)
write_ncc_model (ModelID,'D:/halcon/test/de.ncm')
下面使用上面创建的模版检测图像:
dev_get_window (WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (2)
* 读取ncc模版
read_ncc_model ('C:/Users/16058/Desktop/de.ncm', ModelID)
* 读取模版目标区域
read_region (ROI, 'D:/halcon/test/ROI.hobj')
* 读取目标区域
read_region (ROI_0, 'D:/halcon/test/ROI_0.hobj')
smallest_rectangle2 (ROI, Row1, Column1, Phi1, Length1, Length2)
smallest_rectangle2 (ROI_0, Row2, Column2, Phi2, Length11, Length21)
NumImages := 5
for Index := 1 to NumImages by 1
read_image (Image, 'face_masks/face_mask_' + Index$'02')
count_seconds (T0)
* 模版检测
find_ncc_model (Image, ModelID, rad(0), rad(360), 0.7, 1, 0.5, 'true', 0, Row, Column, Angle, Score)
count_seconds (T1)
Time := (T1 - T0)
dev_clear_window ()
dev_display (Image)
if (|Score| > 0)
* 刚性仿射变换
vector_angle_to_rigid (Row1, Column1, 0, Row, Column, Angle, HomMat2D)
* 转换得到目标区域
affine_trans_region (ROI, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
affine_trans_region (ROI_0, RegionAffineTrans1, HomMat2D, 'nearest_neighbor')
dev_set_color ('red')
dev_display (RegionAffineTrans)
dev_set_color ('green')
dev_display (RegionAffineTrans1)
endif
dev_disp_text ('耗时:'+Time, 'image', 50, 50, 'black', [], [])
stop ()
endfor
运行后可以得到如下结果:
绿色框为目标区域。
三、Python 实现上述检测过程
在 Python
中算子通过 halcon
库直接调用即可。
import halcon as ha
import os
def open_window(width, height, row=0, col=0):
if os.name == 'nt':
ha.set_system('use_window_thread', 'true')
window = ha.open_window(
row=row,
column=col,
width=width,
height=height,
father_window=0,
mode='visible',
machine=''
)
ha.set_draw(window, 'margin')
ha.set_line_width(window, 2)
ha.set_color(window, 'red')
return window
def detection():
# 读取ncc模版
model_id = ha.read_ncc_model('D:/halcon/test/de.ncm')
# 读取模版目标区域
roi = ha.read_object('D:/halcon/test/ROI.hobj')
# 读取目标区域
roi_0 = ha.read_object('D:/halcon/test/ROI_0.hobj')
row1, column1, phi1, length1, length2 = ha.smallest_rectangle2(roi)
for i in range(1, 6):
image = ha.read_image(f"face_masks/face_mask_0{i}.png")
# 模版检测
t0 = ha.count_seconds()
row, column, angle, score = ha.find_ncc_model(image, model_id, 0.0, 6.28319, 0.7, 1, 0.5, 'true', 0)
t1 = ha.count_seconds()
time = (t1 - t0)
print(f"耗时:{time}")
if (len(score) > 0):
# 刚性仿射变换
hom_mat_2d = ha.vector_angle_to_rigid(row1, column1, 0, row, column, angle)
# 转换得到目标区域
region_affine_trans = ha.affine_trans_region(roi, hom_mat_2d, 'nearest_neighbor')
region_affine_trans1 = ha.affine_trans_region(roi_0, hom_mat_2d, 'nearest_neighbor')
# 展示结果
window = open_window(500, 500)
ha.disp_obj(image, window)
ha.set_color(window, 'red')
ha.disp_obj(region_affine_trans, window)
ha.set_color(window, 'green')
ha.disp_obj(region_affine_trans1, window)
ha.wait_seconds(2)
if __name__ == '__main__':
detection()