Halcon学习笔记-Day6:工业视觉高级技术应用与实战项目

第六十六节:Halcon深度学习环境配置与GPU加速

深度学习开发环境搭建

Halcon深度学习按照不同应用范围分为三个方向[1]:

  • 目标检测:用于定位项目,得到物料的位置坐标和角度
  • 分类:用于缺陷检测,可得到物料是好是坏
  • 语义分割:用于缺陷检测,可得到缺陷区域
环境配置步骤
  1. 安装显卡驱动

确保安装支持CUDA的NVIDIA显卡驱动,这是GPU加速的基础[1]。

  1. 安装CUDA并行通用架构

    • 验证CUDA环境
      system('nvidia-smi')
  2. 安装深度学习的Halcon环境

配置深度学习专用的Halcon运行时环境,支持GPU计算加速[1]。

  1. 安装打标签软件

使用专门的深度学习数据标注工具,为训练样本生成准确的标签[1]。


第六十七节:目标检测深度学习实现流程

数据集准备与标注

打标签过程:

  1. 新建项目 - 创建目标检测项目
  2. 框选目标 - 为每张图像打标签,尽量使矩形框相切框住物料
  3. 重叠处理 - 对于重叠的物体,需要按照物体本身的大小框住重叠区域
  4. 导出数据 - 打完标签后,导出数据为数据集[11]

深度学习网络创建

复制代码
* 读入数据集
read_dict('dataset.hdict', [], DLDataset)

* 创建数据字典
create_dict(Dict)
set_dict_tuple(Dict, 'image_width', 416)
set_dict_tuple(Dict, 'image_height', 416)
set_dict_tuple(Dict, 'batch_size', 8)

* 创建神经网络模型
create_dl_model_detection('yolo_v3', 3, Dict, DLModelHandle)

模型训练与优化

复制代码
* 设置模型参数
set_dl_model_param(DLModelHandle, 'batch_size', 8)
set_dl_model_param(DLModelHandle, 'learning_rate', 0.001)
set_dl_model_param(DLModelHandle, 'min_confidence', 0.5)

* 训练模型
create_dl_train_param(DLModelHandle, 100, [], [], TrainParam)
train_dl_model(DLModelHandle, TrainParam, 0, [])

第六十八节:语义分割深度学习实现

语义分割数据准备

打标签工具使用:

  • 准备classes.txt文件,表示各个类别的名称,一个类别一行
  • 准备打标签的图需放入image文件夹内,文件夹名称必须为image
  • 使用专门打标签软件进行像素级标注[7]

标注操作步骤:

  1. 按字母a表示添加一个标签
  2. 按字母n开始画区域,用鼠标在图像上圈区域
  3. 右键确认,并按数字键选择圈住的区域的类型
  4. 按字母c,按下数字选择区域所对应的正确的类型,按回车
  5. 按字母d,保存该张图
  6. 按向右箭头,接着下一张图标注[7]

语义分割模型训练

复制代码
* 语义分割模型创建
create_dl_model_segmentation('unet', 2, Dict, DLSegModelHandle)

* 数据集预处理
preprocess_dl_dataset(DLDataset, 'preprocessed/', [], PreprocessParam)

* 模型训练
train_dl_model(DLSegModelHandle, TrainParam, 0, [])

第六十九节:字符识别与OCR技术

OCR分类器训练流程

创建MLP神经网络
复制代码
* 创建分类器
create_ocr_class_mlp(80, 60, 'softmax', 'normalization', 10, [], [], OCRHandle)

* 训练样本准备
write_ocr_trainf(CharRegions, CharImage, Characters, 'train.trf')

* 追加训练样本
append_ocr_trainf(CharRegions, CharImage, Characters, 'train.trf')

* 训练模型
trainf_ocr_class_mlp(OCRHandle, 'train.trf', 100, 0.001, 0.001, Error, ErrorLog)

字符预处理技术

图像增强与分割
复制代码
* 拉开灰度对比度
emphasize(Image, ImageEnhanced, 10, 10, 1.0)

* 字符分割
char_threshold(ImageEnhanced, Regions, 20, 95)

* 字符区域优化
opening_rectangle1(Regions, RegionsOpened, 1, 1)
connection(RegionsOpened, ConnectedRegions)
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 50, 10000)
OCR文本模型识别
复制代码
* 创建文本模型
create_text_model_reader('auto', [], TextModel)

* 设置文本模型参数
set_text_model_param(TextModel, 'min_font_height', 20)
set_text_model_param(TextModel, 'max_font_height', 80)

* 文本查找
find_text(Image, TextModel, TextResult)

第七十节:工业相机标定技术

单目相机标定流程

标定板描述文件生成
复制代码
* 生成圆形标定板描述文件
gen_caltab(7, 7, 0.0125, 0.3, 'caltab.ps', 'caltab.descr')
标定助手应用

标定步骤:

  1. 采集标定板图像 - 采集10-15张标定板图像,尽量覆盖整个视野[36]

  2. 设置标定参数 - 包括焦距、畸变系数、像元尺寸等[36]

  3. 执行标定 - 使用TSAI两步标定法计算内外参[36]

  4. 评估标定精度 - 计算反向投影均方误差(RMSE)[36]

    • 创建标定模型
      create_calib_data('calibration_object', 1, 1, CalibDataID)

    • 设置初始内参
      set_calib_data_cam_param(CalibDataID, 0, 'area_scan_polynomial',
      [0.008, 0, 5.12e-6, 5.12e-6, 1280, 960, 2560, 1920])

    • 设置标定板描述文件
      set_calib_data_calib_object(CalibDataID, 0, 'caltab.descr')

    • 采集并标定
      for Index := 1 to 12 by 1
      read_image(Image, 'calib_' + Index$'02d')
      find_calib_object(Image, CalibDataID, 0, 0, Index, [])
      get_calib_data_observ_points(CalibDataID, 0, 0, Index, Row, Col, Pose)
      endfor

    calibrate_cameras(CalibDataID, Errors)


第七十一节:手眼标定技术

眼在手上手眼标定

标定原理与实现

基本原理:确定机械手坐标系(Base、Tool)和摄像机坐标系之间的矩阵转换关系[16]。

复制代码
* 读取保存的标定数据
read_pose('eye_hand_poses.dat', EyeInHandPoses)
read_image(Image, 'calib_image_1')

* 创建标定模型
create_calib_data('hand_eye_moving_cam', 1, 1, CalibDataID)

* 设置标定参数
set_calib_data_cam_param(CalibDataID, 0, 'area_scan_polynomial', CameraParams)
set_calib_data_calib_object(CalibDataID, 0, 'caltab.descr')

* 添加标定观察
for Index := 1 to 15 by 1
    read_image(Image, 'handeye_' + Index$'02d')
    find_calib_object(Image, CalibDataID, 0, 0, Index, [])
    get_calib_data_observ_points(CalibDataID, 0, 0, Index, Row, Col, Pose)
    set_calib_data(CalibDataID, 'hand_eye', 'tool_in_base_pose', Index, EyeInHandPoses[Index-1])
endfor

* 执行手眼标定
calibrate_hand_eye(CalibDataID, Errors)

旋转中心标定

三点拟合圆方法[23]:

  1. 在相机视野内移动标志点三次,机器人U轴旋转

  2. 求出标志点的像素坐标,转换为世界坐标

  3. 根据三个点确定圆的圆心坐标

  4. 计算tool0和tool1之间的偏差

    • 三点拟合圆求旋转中心
      fit_circle_contour_xld(Contour, 'algebraic', -1, 0, 0, 3, 2, CenterRow, CenterCol, Radius, StartPhi, EndPhi, PointOrder)

    • 计算偏差
      ToolOffsetX := Row1 - CenterRow
      ToolOffsetY := Col1 - CenterCol


第七十二节:多相机系统标定与坐标统一

双目标定实现

标定流程
复制代码
* 创建双目标定模型
create_calib_data('calibration_object', 2, 1, CalibDataID)

* 设置两个相机的初始内参
set_calib_data_cam_param(CalibDataID, 0, 'area_scan_polynomial', CamParam1)
set_calib_data_cam_param(CalibDataID, 1, 'area_scan_polynomial', CamParam2)

* 采集标定板图像(两个相机同时采集)
for Index := 1 to 12 by 1
    read_image(ImageLeft, 'left_' + Index$'02d')
    read_image(ImageRight, 'right_' + Index$'02d')
  
    find_calib_object(ImageLeft, CalibDataID, 0, 0, Index, [])
    find_calib_object(ImageRight, CalibDataID, 1, 0, Index, [])
endfor

* 执行双目标定
calibrate_cameras(CalibDataID, Errors)

* 获取相机间相对位姿
get_calib_data(CalibDataID, 'camera', 1, 'extrinsic_poses', Cam1ToCam2Pose)
坐标系统一方法

方法一:借助第三方坐标系

通过机器人base坐标系,将两个相机的像素点通过九点标定映射到base坐标系下[13]。

方法二:利用蜂窝标定板

使用蜂窝标定板进行多相机标定,不需要全部拍全,但至少找到一个finder,6张标定图即可[30]。

复制代码
* 创建蜂窝标定板
create_caltab(10, 10, 0.008, 0.3, [50, 50, 100, 100, 150, 150, 200, 200, 250, 250, 50, 150, 250, 350, 450], 
              'positive', 'hexagonal_caltab.ps', 'hexagonal_caltab.descr')

第七十三节:运动控制系统集成

运动板卡控制

雷赛DMC2410板卡应用

硬件组成:驱动器、模组、开关电源、电磁阀、真空发生器、空气压缩机、吸嘴、雷赛板卡、编码器、限位开关(9个)[24]

复制代码
* 运动控制算子示例
* 连续JOG运动
set_axis_status(0, 1)  * 开启第一轴
start_jog(0, 1, 1000)  * 开始JOG运动

* 点位运动
set_target_position(0, X, Y)
start_point_move(0, 1)

* 回零运动
home_move(0, 1)

机器人TCP通讯

爱普森机器人程序控制
复制代码
* TCP通讯设置
opennet('192.168.0.100', 2000)  * 连接到机器人IP地址

* 发送运动命令
send_command('MoveJ XY(' + X$'.2f' + ',' + Y$'.2f' + ',' + Z$'.2f' + ',U0)')

* 吸气控制
send_command('On 8')   * 开启吸气
send_command('Off 8')  * 关闭吸气

第七十四节:串口通信协议实现

Modbus RTU协议

协议格式

Modbus RTU帧格式[25]:

  1. 第一个字节:从站地址码

  2. 第二个字节:功能码

  3. 数据区:寄存器地址和数据

  4. 校验位:CRC校验或求和校验

    • 创建Modbus请求
      function create_modbus_request(device_addr, function_code, reg_addr, reg_count)
      request = [device_addr, function_code, reg_addr_hi, reg_addr_lo, reg_count_hi, reg_count_lo]

      • 计算CRC校验
        crc = calculate_crc16(request)
        request = [request, crc_low, crc_high]

      return request
      endfunction

    • 发送Modbus请求
      send_serial_data(request, 8)

C#串口通信实现

复制代码
public class SerialPortManager
{
    private SerialPort serialPort;
  
    public void InitializeSerialPort(string portName, int baudRate)
    {
        serialPort = new SerialPort();
        serialPort.PortName = portName;
        serialPort.BaudRate = baudRate;
        serialPort.DataBits = 8;
        serialPort.Parity = Parity.None;
        serialPort.StopBits = StopBits.One;
    }
  
    // 十六进制发送
    public void SendHexData(string hexString)
    {
        byte[] data = new byte[hexString.Length / 2];
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
        }
        serialPort.Write(data, 0, data.Length);
    }
  
    // 字符串发送
    public void SendStringData(string data)
    {
        byte[] byteData = Encoding.Default.GetBytes(data);
        serialPort.Write(byteData, 0, byteData.Length);
    }
}

第七十五节:网络通信协议实现

TCP/UDP通信

TCP服务器端实现
复制代码
public class TcpServerManager
{
    private TcpListener tcpListener;
    private NetworkStream networkStream;
  
    public async Task StartServerAsync(int port)
    {
        tcpListener = new TcpListener(IPAddress.Any, port);
        tcpListener.Start();
    
        while (true)
        {
            TcpClient client = await tcpListener.AcceptTcpClientAsync();
            await HandleClientAsync(client);
        }
    }
  
    private async Task HandleClientAsync(TcpClient client)
    {
        networkStream = client.GetStream();
        byte[] buffer = new byte[1024];
    
        int bytesRead = await networkStream.ReadAsync(buffer, 0, buffer.Length);
        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
    
        // 处理接收到的数据
        ProcessMessage(message);
    
        // 发送响应
        string response = "Message received: " + message;
        byte[] responseData = Encoding.UTF8.GetBytes(response);
        await networkStream.WriteAsync(responseData, 0, responseData.Length);
    }
}
UDP通信实现
复制代码
public class UdpCommunicationManager
{
    private UdpClient udpClient;
  
    public void InitializeUdpClient(int localPort)
    {
        udpClient = new UdpClient(localPort);
    }
  
    public async Task SendUdpMessage(string message, string remoteHost, int remotePort)
    {
        byte[] data = Encoding.UTF8.GetBytes(message);
        await udpClient.SendAsync(data, data.Length, remoteHost, remotePort);
    }
  
    public async Task<string> ReceiveUdpMessage()
    {
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        byte[] data = await udpClient.Receive(ref remoteEP);
        return Encoding.UTF8.GetString(data);
    }
}

第七十六节:光源选型与光学系统设计

光源分类与应用

各类光源特点

环形光源[28]:

  • 使用率最高,光线方向性较强
  • 低角度环形光源一般打凹凸缺陷、划痕等
  • 高角度范围大,各方向都有打光

同轴光源:

  • 适合打金属等反光物料、凹凸物料
  • 会降低亮度,打光面积较小

背光源:

  • 适合透明物料、或测量项目
  • 一般用短波长,衍射弱,蓝光

打光原则与技巧

反射定律应用[28]
复制代码
* 光源选择判断逻辑
if (MaterialType == 'metal' and SurfaceType == 'mirror')
    * 使用偏振片+同轴光源
    LightSource = 'coaxial'
    Polarizer = true
elseif (DefectType == 'scratch')
    * 使用低角度环形光
    LightSource = 'low_angle_ring'
    Angle = 30  * 30度低角度
elseif (MaterialType == 'transparent')
    * 使用背光源
    LightSource = 'backlight'
    Wavelength = 'blue'  * 蓝光
endif
光源大小计算[28]
复制代码
* 计算光源大小
* 光源大小最小为视野大小的两倍
LightSize = 2 * FOV
LightSize = max(LightSize, MinLightSize)  * 确保不小于最小尺寸

第七十七节:镜头选型与焦距计算

镜头焦距计算公式

基本焦距公式[40]
复制代码
* 根据工作距离和视野计算焦距
* 公式1: f = (WD * CCD_Size) / FOV
* 公式2: f = (Magnification * WD) / (Magnification + 1)

calculate_lens_parameters(WorkDistance, FOV, CCDWidth, CCDHeight, Magnification, FocalLength, FNumber)

* 其中:
* WorkDistance: 工作距离(mm)
* FOV: 视野范围(mm)
* CCDWidth/Height: CCD靶面尺寸(mm)
* Magnification: 放大倍率
* FocalLength: 计算出的焦距(mm)
远心镜头选型[40]

远心镜头优势:

  • 可矫正畸变,精度要求高时使用

  • 当客户精度要求非常高、视野比较小、物料比较小时使用

    • 远心镜头参数选择
      if (AccuracyRequirement >= 0.01) * 精度要求1丝以上
      LensType = 'telecentric'
      Magnification = RequiredFOV / CCDSize
      WorkingDistance = 65 * 标准远心镜头工作距离
      endif

景深计算与应用[40]

复制代码
* 景深计算
* DOF = (2 * CircleOfConfusion * FNumber * (Magnification + 1)) / (Magnification^2)
calculate_depth_of_field(Magnification, FNumber, COC, DepthOfField)

* 景深影响因素
* 焦距越小,景深越大
* 光圈越小,景深越大  
* 工作距离越大,景深越大

第七十八节:频域图像处理技术

频域滤波器设计

高斯滤波器应用
复制代码
* 创建高斯滤波器
gen_gauss_filter(GaussFilter, 512, 512, 1.0, 1.0, 0, 'none', 0, 0, 512, 512)

* 频域滤波
convol_fft(Image, GaussFilter, ImageFiltered)
带通滤波器
复制代码
* 正弦带通滤波器 - 适用于微小划痕
gen_sin_bandpass(SinBandpass, 512, 512, 'none', 0, 0, 512, 512)

* 差分滤波器
gen_gauss_filter(Gauss1, 512, 512, 0.5, 1.5, 0, 'none', 0, 0, 512, 512)
gen_gauss_filter(Gauss2, 512, 512, 1.0, 1.0, 0, 'none', 0, 0, 512, 512)
sub_image(Gauss1, Gauss2, DiffFilter, 1, 0)

频域缺陷增强

复制代码
* 利用频域得到背景图,空间域差分增强缺陷
power_real(FFTImage, PowerSpectrum)
convert_image_type(PowerSpectrum, PowerSpectrum, 'byte')
threshold(PowerSpectrum, BackgroundRegion, 128, 255)
gen_image_proto(PowerSpectrum, BackgroundImage, 255)

* 空间域差分
sub_image(Image, BackgroundImage, DefectImage, 1, 128)
emphasize(DefectImage, DefectEnhanced, 3, 3, 1.5)

第七十九节:二维码识别技术

二维码码制选择与参数设置

常用码制特点[29]
  • QR码:最常见的码,有三个方框和一个小方框

  • Data Matrix ECC 200:无任何标记的二维码

  • Aztec Code:中间有个框

  • Micro_QR Code:左下角有个方框

    • 创建二维码模型
      create_data_code_2d_model('Data Matrix ECC 200', 'default_parameters', [], QRCodeModel)

    • 设置识别参数
      set_data_code_2d_param(QRCodeModel, 'symbol_size_min', 10)
      set_data_code_2d_param(QRCodeModel, 'symbol_size_max', 100)
      set_data_code_2d_param(QRCodeModel, 'contrast_min', 30)
      set_data_code_2d_param(QRCodeModel, 'module_gap_min', 'no')

难识别二维码处理

透视变换矫正
复制代码
* 二维码透视变换
* 找到二维码四个角点
points_foerstner_sub_pix(Image, 1, 200, 3, 'gauss', 1, 0, 'true', Row, Col, JI, COV, PSI)

* 计算透视变换矩阵
hom_vector_to_proj_hom_mat2d(Row, Col, [1,1,1,1], RowTrans, ColTrans, [1,1,1,1], 'normalized', HomMat2D)

* 应用透视变换
projective_trans_image(Image, ImageCorrected, HomMat2D, 'bilinear', 'false', 'false', 0.5)

* 在矫正后图像中识别二维码
find_data_code_2d(ImageCorrected, SymbolXLDs, QRCodeModel, 30, 35, ResultHandles, DecodedDataStrings)

第八十节:一维码识别技术

条码码制与参数设置

常用码制特点[42]
  • Code 128:通用性最强,支持所有ASCII字符

  • Code 39:支持数字和大写字母

  • EAN-13:商品条码,13位数字

  • ITF:交叉25码,只支持数字

    • 创建一维码模型
      create_bar_code_model('auto', 'default_parameters', BarCodeModel)

    • 设置码制类型
      set_bar_code_param(BarCodeModel, 'code_type', 'Code 128')

    • 设置识别参数
      set_bar_code_param(BarCodeModel, 'element_size_min', 2)
      set_bar_code_param(BarCodeModel, 'element_size_max', 8)
      set_bar_code_param(BarCodeModel, 'contrast_min', 20)
      set_bar_code_param(BarCodeModel, 'check_char', 'absent')

特殊条码处理

凹凸状一维码处理[49]
复制代码
* 环形一维码处理
* 先进行极坐标转换拉直
image_to_polar_coords(Image, PolarImage, 512, 512, 256, 256, 100, 200, 0, 6.28318, 'interpolation')

* 然后在拉直图像中识别条码
find_bar_code(PolarImage, SymbolRegions, BarCodeModel, 'auto', 'interpolated', DecodedDataStrings)
参数调优
复制代码
* 针对小条码优化
set_bar_code_param(BarCodeModel, 'symbol_size_min', 5)
set_bar_code_param(BarCodeModel, 'symbol_size_max', 15)
set_bar_code_param(BarCodeModel, 'element_size_variable', 'true')

* 启用投票机制
set_bar_code_param(BarCodeModel, 'majority_voting', 'true')

第八十一节:工业测量技术

二维测量实现

测量助手应用[38]

测量流程:

  1. 定位 → 确定测量基准

  2. 分割 → 提取边缘特征

  3. 拟合 → 使用最小二乘法

  4. 标定 → 转换为实际尺寸

  5. 测量 → 计算几何参数

    • 创建测量矩形
      gen_measure_rectangle2(100, 200, 0, 50, 20, 640, 480, 'bilinear', MeasureHandle)

    • 边缘对测量
      measure_pairs(Image, MeasureHandle, 1.0, 20, 'positive', 'all',
      RowEdge, ColEdge, Amplitude, Distance, IntraDistance, InterDistance)

一维测量技术

亚像素边缘提取[41]
复制代码
* Canny边缘检测
edges_sub_pix(Image, Edges, 'canny', 1, 20, 40)

* 直线拟合
fit_line_contour_xld(Edges, 'regression', 0, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
测量结果分析
复制代码
* 计算测量值
* 两点间距离
distance_pp(RowBegin, ColBegin, RowEnd, ColEnd, Distance)

* 直线与直线夹角
angle_ll(RowBegin, ColBegin, RowEnd, ColEnd, Row2Begin, Col2Begin, Row2End, Col2End, Angle)

第八十二节:3D视觉技术应用

双目立体视觉

双目标定与重建[32]
复制代码
* 双目标定
calibrate_stereo_cameras(Caltab, CalibParam1, CalibParam2, NFinalPose1, NFinalPose2, c1Pc2, Errors)

* 图像矫正
rectify_stereo_image(Image1Rect, Image2Rect, CalibParam1, CalibParam2, c1Pc2)

* 视差图计算
stereo_match(Image1Rect, Image2Rect, Disparity, Score, 'ncc', 15, 5, 5, 1, 0, 'none', 'false')

* 3D坐标重建
disparity_image_to_xyz(Disparity, CalibParam1, Row, Col, Z, X, Y)

激光三角测量

光平面标定与点云重建[21]
复制代码
* 光平面标定
calibrate_sheet_of_light(LowPose, HighPose, LightPlanePose, [])
fit_3d_plane_xyz(X, Y, Z, PlaneParams)

* 点云重建
reconstruct_sheet_of_light_profile(Image, SheetOfLightModel, X, Y, Z, Intensity)

第八十三节:模板匹配进阶技术

多尺度模板匹配

等比缩放匹配[4]
复制代码
* 创建等比缩放模板
create_scaled_shape_model(Template, 5, 0.8, 1.2, 0.01, 0.5, 0.8, 'auto', 'use_polarity')

* 查找缩放匹配
find_scaled_shape_model(Image, ScaleModelID, 0.8, 1.2, 0.5, 600, 1, 0.5, 'least_squares', 0, 0.8, 
                       Row, Column, Angle, Scale, Score)
不等比缩放匹配
复制代码
* 创建各向异性缩放模板
create_aniso_shape_model(Template, 5, 0.8, 1.2, 0, 0.8, 1.2, 0, 'auto', 'use_polarity')

* 查找各向异性缩放匹配
find_aniso_shape_model(Image, AnisoModelID, 0.8, 1.2, 0, 0.8, 1.2, 0, 0.5, 600, 1, 0.5, 
                      'least_squares', 0, 0.8, Row, Column, Angle, ScaleR, ScaleC, Score)

多模板匹配

复制代码
* 创建多个模板
create_shape_model(Template1, 4, 0, 0.785, 'auto', 'use_polarity', 'auto', 1, ModelID1)
create_shape_model(Template2, 4, 0, 0.785, 'auto', 'use_polarity', 'auto', 1, ModelID2)

* 模板句柄数组
ModelHandles := [ModelID1, ModelID2]

* 多模板查找
find_shape_models(Image, ModelHandles, 0, 0.785, 0.5, 8, 1, 0.5, 'least_squares', 0, 0.8, 
                 ModelIDs, Row, Column, Angle, Score)

第八十四节:字符识别高级技术

OCR文本模型应用

自动文本分割[35]
复制代码
* 创建文本模型
create_text_model_reader('auto', [], TextModel)

* 查找文本
find_text(Image, TextModel, TextResult)

* 获取文本结果
get_text_result(TextResult, 'class', TextClasses)
get_text_result(TextResult, 'confidence', TextConfidences)
手动模式OCR
复制代码
* 设置文本模型为手动模式
set_text_model_param(TextModel, 'manual_text_lines', 'true')

* 查找文本(手动模式返回区域)
find_text(Image, TextModel, TextResult)

* 获取分割的字符区域
get_text_object(TextLines, TextResult, 'lines')
get_text_object(CharRegions, TextResult, 'words')

* 识别字符
do_ocr_multi_class_mlp(CharRegions, Image, OCRHandle, RecChar, Confidence)

复杂背景OCR处理

预处理技术
复制代码
* 差分高斯增强
diff_of_gauss(Image, ImageEnhanced, 1.0, 2.0)

* 字符分割
partition_dynamic(CharRegions, PartitionedRegions, 20, 0.2)

* 区域优化
opening_rectangle1(CharRegions, CharRegionsOpened, 2, 2)
fill_up(CharRegionsOpened, CharRegionsFilled)

第八十五节:工业项目实战案例

自动贴合系统

系统架构

硬件组成:

  • 爱普森六轴机器人
  • 上相机(物料定位)
  • 下相机(放置检测)
  • 真空吸盘
  • 控制系统[39]
贴合算法流程
复制代码
* 上相机物料定位
read_image(ImageTop, 'top_image')
find_shape_model(ImageTop, TopModelID, 0, 3.14159, 0.7, 1, 0.5, 'least_squares', 0, 0.8,
                TopRow, TopCol, TopAngle, TopScore)

* 计算物料姿态
affine_trans_point_2d(TopRow, TopCol, HomMat2D, WorldRow, WorldCol)

* 机器人抓取
MoveJ(L PickPose)
On 8  ' 开启吸气
WaitTime(0.5)
Off 8

* 下相机位置检测
read_image(ImageBottom, 'bottom_image')
find_shape_model(ImageBottom, BottomModelID, 0, 3.14159, 0.8, 1, 0.5, 'least_squares', 0, 0.8,
                BottomRow, BottomCol, BottomAngle, BottomScore)

* 位置纠偏
* 计算位置偏差
DeltaX := BottomCol - TargetCol
DeltaY := BottomRow - TargetRow
DeltaAngle := BottomAngle - TargetAngle

* 应用纠偏
CorrectedX := PickX + DeltaX
CorrectedY := PickY + DeltaY  
CorrectedU := PickU + DeltaAngle

* 放置物料
MoveL(XY(CorrectedX, CorrectedY, PlaceZ, CorrectedU))
On 9  ' 关闭吸气

分选机系统

深度学习分类集成
复制代码
* 读取深度学习模型
read_dl_model('classification_model.hdl', DLModelHandle)

* 图像预处理
preprocess_dl_samples(Image, ImagePreprocessed, PreprocessParam)

* 分类推理
apply_dl_model(DLModelHandle, ImagePreprocessed, [], [], DLResult)

* 获取分类结果
get_dict_tuple(DLResult, 'classification', ClassificationResult)

* 根据分类结果控制分选
if (ClassificationResult[0] == 'good')
    * 发送到合格品通道
    send_command('MoveTo GoodChannel')
elseif (ClassificationResult[0] == 'defect')
    * 发送到不良品通道  
    send_command('MoveTo DefectChannel')
endif

总结

通过Day6的学习,我们深入掌握了Halcon的高级视觉技术:

  1. 深度学习应用 - 目标检测、语义分割、分类的实现流程
  2. OCR识别技术 - 从基础字符识别到复杂文本处理
  3. 工业标定技术 - 相机标定、手眼标定、多相机系统
  4. 运动控制集成 - 机器人控制、通信协议实现
  5. 光学系统设计 - 光源选型、镜头配置
  6. 图像处理算法 - 频域处理、模板匹配进阶
  7. 条码识别技术 - 一维码、二维码的完整解决方案
  8. 工业实战 - 贴合系统、分选机等实际项目应用

这些技术构成了现代工业视觉系统的核心知识体系,为实际工程应用提供了强有力的技术支撑。

下节预告:Day7将深入学习Halcon的高级算法优化、3D视觉应用以及完整的工业项目解决方案设计。

相关推荐
GHL28427109021 小时前
调用通义千问(qwen-plus)模型demo-学习
学习·ai·ai编程
Chris_121921 小时前
Halcon学习笔记-Day6进阶:工业级视觉系统核心技术详解
人工智能·python·深度学习·halcon
AI视觉网奇1 天前
audio2face mh_arkit_mapping_pose_A2F 不兼容
笔记·ue5
wdfk_prog1 天前
[Linux]学习笔记系列 -- [fs]super
linux·笔记·学习
GHL2842710901 天前
Temperature、Top P 学习
学习·ai
Yyuanyuxin1 天前
保姆级学习开发安卓手机软件(三)--安装模拟机并开始简单的进入开发
android·学习
不爱编程爱睡觉1 天前
代码随想录学习——项目学习——HTTP服务框架——环境配置问题
学习
日更嵌入式的打工仔1 天前
单片机基础知识:内狗外狗/软狗硬狗
笔记·单片机
KhalilRuan1 天前
数据结构与算法-笔记
笔记