【开源】基于 C# 和 Halcon 机器视觉开发的车牌识别工具(附带源码)

文章目录


项目介绍

halcon_chepai一款基于C#编程语言与Halcon机器视觉库的车牌识别系统。该系统利用Halcon强大的图像处理能力,结合C#的灵活性与易用性,实现了高效、准确的车牌识别功能。识别成功率高达90%。

注意:项目中只引用了HalconDotNet.dll,还需安装halcon环境,或将halcon的安装路径文件放到本项目debug里才能正常运行。

应用场景

  • 智能交通系统:在交通监控、违章抓拍等场景中,自动识别车牌号码,辅助交通管理。
  • 停车场管理:自动识别进出车辆的车牌,实现自动化停车计费与管理。
  • 物流追踪:在物流园区或货运站,通过车牌识别追踪货物运输车辆。
  • 安防监控:在重要区域或场所的出入口,通过车牌识别加强安全监控。

功能特点

  • 高精度识别:利用Halcon先进的图像处理算法,实现高精度的车牌识别。
  • 实时性强:优化算法与处理流程,确保系统实时响应,满足实时监控需求。
  • 适应性强:能够适应不同光照条件、车牌类型与倾斜角度的车牌识别。
  • 易用性高:提供友好的用户界面与简单的操作方式,降低使用门槛。

Halcon关键代码

css 复制代码
dev_close_window()

dev_clear_window()
read_image(image,'C:/Users/Administrator/Desktop/halcon/chepai4.jpg')
get_image_size(image, Width, Height)
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle)
dev_display(image)
* 将图片转化为rgb三通道
decompose3(image, r, g, b)
* 转为hsv 色调 饱和度 明度值
trans_from_rgb(r, g, b, h, s, v, 'hsv')
* 提升图片对比度
emphasize(s, ImageEmphasize, Width, Height, 1)

threshold(ImageEmphasize, Region, 255, 255)

connection(Region, ConnectedRegions)

closing_rectangle1(ConnectedRegions, RegionClosing, 50, 50)

* 按照最大面积选
select_shape_std(RegionClosing, SelectedRegions, 'max_area', 70)
* 填充选出区域的孔洞
fill_up(SelectedRegions, RegionFillUp)
* 抠图
reduce_domain(ImageEmphasize, RegionFillUp, ImageReduced)
* 抠出原图
reduce_domain(image, RegionFillUp, ImageReduced1)
* 识别
threshold(ImageReduced, Region1, 0, 100)
* 打断连接区域
connection(Region1, ConnectedRegions1)
* 筛选显示区域
select_shape (ConnectedRegions1, SelectedRegions1, 'area', 'and', 4014, 19840.76)
* 排序区域
sort_region(SelectedRegions1, SortedRegions, 'character', 'true', 'row')
* 反转图片
invert_image(ImageReduced1, ImageInvert)
* 开始识别
read_ocr_class_mlp('Industrial_0-9A-Z_NoRej.omc', OCRHandle)
do_ocr_multi_class_mlp(SortedRegions, ImageInvert, OCRHandle, Class, Confidence)

功能截图

源码地址

https://gitee.com/ss123true/halcon_chepai

C#调用项目代码

界面

HalconDev类

css 复制代码
using HalconDotNet;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

public partial class HalconDev
{
    private HTuple windowHandle;
    public List<string[]> action(int threhold_down, int threhold_up, int area_down,int area_up,PictureBox pcb,string path)
    {

        List<string[]> dic = new List<string[]>();
        // Local iconic variables 
        HObject ho_image, ho_r, ho_g, ho_b, ho_h, ho_s;
        HObject ho_v, ho_ImageEmphasize, ho_Region, ho_ConnectedRegions;
        HObject ho_RegionClosing, ho_SelectedRegions, ho_RegionFillUp;
        HObject ho_ImageReduced, ho_ImageReduced1, ho_Region1, ho_ConnectedRegions1;
        HObject ho_SelectedRegions1, ho_SortedRegions, ho_ImageInvert;

        // Local control variables 

        HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
        HTuple hv_WindowHandle = new HTuple(), hv_OCRHandle = new HTuple();
        HTuple hv_Class = new HTuple(), hv_Confidence = new HTuple();
        // Initialize local and output iconic variables 
        HOperatorSet.GenEmptyObj(out ho_image);
        HOperatorSet.GenEmptyObj(out ho_r);
        HOperatorSet.GenEmptyObj(out ho_g);
        HOperatorSet.GenEmptyObj(out ho_b);
        HOperatorSet.GenEmptyObj(out ho_h);
        HOperatorSet.GenEmptyObj(out ho_s);
        HOperatorSet.GenEmptyObj(out ho_v);
        HOperatorSet.GenEmptyObj(out ho_ImageEmphasize);
        HOperatorSet.GenEmptyObj(out ho_Region);
        HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
        HOperatorSet.GenEmptyObj(out ho_RegionClosing);
        HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
        HOperatorSet.GenEmptyObj(out ho_RegionFillUp);
        HOperatorSet.GenEmptyObj(out ho_ImageReduced);
        HOperatorSet.GenEmptyObj(out ho_ImageReduced1);
        HOperatorSet.GenEmptyObj(out ho_Region1);
        HOperatorSet.GenEmptyObj(out ho_ConnectedRegions1);
        HOperatorSet.GenEmptyObj(out ho_SelectedRegions1);
        HOperatorSet.GenEmptyObj(out ho_SortedRegions);
        HOperatorSet.GenEmptyObj(out ho_ImageInvert);
        if (HDevWindowStack.IsOpen())
        {
            HOperatorSet.CloseWindow(HDevWindowStack.Pop());
        }

        if (HDevWindowStack.IsOpen())
        {
            HOperatorSet.ClearWindow(HDevWindowStack.GetActive());
        }
        ho_image.Dispose();
        HOperatorSet.ReadImage(out ho_image, path);
        hv_Width.Dispose(); hv_Height.Dispose();
        HOperatorSet.GetImageSize(ho_image, out hv_Width, out hv_Height);
        hv_WindowHandle.Dispose();
        HOperatorSet.OpenWindow(0, 0, pcb.Width, pcb.Height, pcb.Handle, "visible", "", out windowHandle);
        HDevWindowStack.Push(windowHandle);
        
        //将图片转化为rgb三通道
        ho_r.Dispose(); ho_g.Dispose(); ho_b.Dispose();
        HOperatorSet.Decompose3(ho_image, out ho_r, out ho_g, out ho_b);
        //转为hsv 色调 饱和度 明度值
        ho_h.Dispose(); ho_s.Dispose(); ho_v.Dispose();
        HOperatorSet.TransFromRgb(ho_r, ho_g, ho_b, out ho_h, out ho_s, out ho_v, "hsv");
        //提升图片对比度
        ho_ImageEmphasize.Dispose();
        HOperatorSet.Emphasize(ho_s, out ho_ImageEmphasize, hv_Width, hv_Height, 1);

        ho_Region.Dispose();
        HOperatorSet.Threshold(ho_ImageEmphasize, out ho_Region, 255,255);

        ho_ConnectedRegions.Dispose();
        HOperatorSet.Connection(ho_Region, out ho_ConnectedRegions);

        ho_RegionClosing.Dispose();
        HOperatorSet.ClosingRectangle1(ho_ConnectedRegions, out ho_RegionClosing, 50, 50);

        //按照最大面积选
        ho_SelectedRegions.Dispose();
        HOperatorSet.SelectShapeStd(ho_RegionClosing, out ho_SelectedRegions, "max_area", 70);
        //填充选出区域的孔洞
        ho_RegionFillUp.Dispose();
        HOperatorSet.FillUp(ho_SelectedRegions, out ho_RegionFillUp);
        //抠图
        ho_ImageReduced.Dispose();
        HOperatorSet.ReduceDomain(ho_ImageEmphasize, ho_RegionFillUp, out ho_ImageReduced
            );
        //抠出原图
        ho_ImageReduced1.Dispose();
        HOperatorSet.ReduceDomain(ho_image, ho_RegionFillUp, out ho_ImageReduced1);
        //识别
        ho_Region1.Dispose();
        HOperatorSet.Threshold(ho_ImageReduced, out ho_Region1, threhold_down, threhold_up); // 0 100
        //打断连接区域
        ho_ConnectedRegions1.Dispose();
        HOperatorSet.Connection(ho_Region1, out ho_ConnectedRegions1);
        //筛选显示区域
        ho_SelectedRegions1.Dispose();
        HOperatorSet.SelectShape(ho_ConnectedRegions1, out ho_SelectedRegions1, "area",
            "and", area_down, area_up); //4014, 19840.76
        //排序区域
        ho_SortedRegions.Dispose();
        HOperatorSet.SortRegion(ho_SelectedRegions1, out ho_SortedRegions, "character",
            "true", "row");
        //反转图片
        ho_ImageInvert.Dispose();
        HOperatorSet.InvertImage(ho_ImageReduced1, out ho_ImageInvert);
        
            //开始识别
        hv_OCRHandle.Dispose();
        HOperatorSet.ReadOcrClassMlp("Industrial_0-9A-Z_NoRej.omc", out hv_OCRHandle);
        hv_Class.Dispose(); hv_Confidence.Dispose();
        HOperatorSet.DoOcrMultiClassMlp(ho_SortedRegions, ho_ImageInvert, hv_OCRHandle,
            out hv_Class, out hv_Confidence);
        if (HDevWindowStack.IsOpen())
        {
            dic.Clear();
            HOperatorSet.DispObj(ho_ImageReduced1, windowHandle);
            HOperatorSet.DispObj(ho_image, windowHandle);
            HOperatorSet.DispObj(ho_Region1, windowHandle);
            HOperatorSet.WriteString(windowHandle,hv_Class);
            string[] cls = hv_Class.ToSArr();
            string[] confidence = hv_Confidence.ToSArr();
            for (int i = 0;i< cls.Length;i++)
            {
                dic.Add(new string[] { cls[i], confidence[i] }); 
            }
        }
        ho_image.Dispose();
        ho_r.Dispose();
        ho_g.Dispose();
        ho_b.Dispose();
        ho_h.Dispose();
        ho_s.Dispose();
        ho_v.Dispose();
        ho_ImageEmphasize.Dispose();
        ho_Region.Dispose();
        ho_ConnectedRegions.Dispose();
        ho_RegionClosing.Dispose();
        ho_SelectedRegions.Dispose();
        ho_RegionFillUp.Dispose();
        ho_ImageReduced.Dispose();
        ho_ImageReduced1.Dispose();
        ho_Region1.Dispose();
        ho_ConnectedRegions1.Dispose();
        ho_SelectedRegions1.Dispose();
        ho_SortedRegions.Dispose();
        ho_ImageInvert.Dispose();

        hv_Width.Dispose();
        hv_Height.Dispose();
        hv_WindowHandle.Dispose();
        hv_OCRHandle.Dispose();
        hv_Class.Dispose();
        hv_Confidence.Dispose();
        return dic;

    }



}

Form1.cs

css 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace halcon_chepai
{
    public partial class Form1 : Form
    {
        private HalconDev halconDev;
        private int threhold_up_value = 100;
        private int threhold_down_value = 0;
        private int area_down_value = 4014;
        private int area_up_value = 19840;
        public Form1()
        {
            halconDev = new HalconDev();
            InitializeComponent();
            threshold_down.Value = threhold_down_value;
            threshold_up.Value = threhold_up_value;
            area_up.Value = area_up_value;
            area_down.Value = area_down_value;
            threhold_up_label.Text = threhold_up_label.Text + " : " + threhold_up_value;
            threhold_down_label.Text = threhold_down_label.Text + " : " +threhold_down_value;
            area_down_label.Text = area_down_label.Text + " : " + area_down_value;
            area_up_label.Text = area_up_label.Text + " : " + area_up_value;
        }


        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                var dic = halconDev.action(threhold_down_value, threhold_up_value, area_down_value, area_up_value, pictureBox1, textBox1.Text);
                listView1.Items.Clear();
                foreach(var i in dic)
                {
                    ListViewItem item = new ListViewItem();
                    item.SubItems.Add(i[1]);
                    item.Text = i[0];
                    listView1.Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                label1.Text = ex.Message;
            }
        }

  

        private void threshold_down_Scroll(object sender, EventArgs e)
        {
            try
            {
                threhold_down_value = threshold_down.Value;
                threhold_down_label.Text = threhold_down_label.Text.Split(':')[0].Replace(" ", "") + " : " + threhold_down_value;
                var dic = halconDev.action(threhold_down_value, threhold_up_value, area_down_value, area_up_value, pictureBox1, textBox1.Text);
                listView1.Items.Clear();
                foreach (var i in dic)
                {
                    ListViewItem item = new ListViewItem();
                    item.SubItems.Add(i[1]);
                    item.Text = i[0];
                    listView1.Items.Add(item);
                }
            }
            catch(Exception ex)
            {
                label1.Text = ex.Message;
            }
           
        }

        private void threshold_up_Scroll(object sender, EventArgs e)
        {
            try
            {
                threhold_up_value = threshold_up.Value;
                threhold_up_label.Text = threhold_up_label.Text.Split(':')[0].Replace(" ", "") + " : " + threhold_up_value;
                var dic = halconDev.action(threhold_down_value, threhold_up_value, area_down_value, area_up_value, pictureBox1, textBox1.Text);
                listView1.Items.Clear();
                foreach (var i in dic)
                {
                    ListViewItem item = new ListViewItem();
                    item.SubItems.Add(i[1]);
                    item.Text = i[0];
                    listView1.Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                label1.Text = ex.Message;
            }
        }

        private void area_down_Scroll(object sender, EventArgs e)
        {
            try
            {
                area_down_value = area_down.Value;
                area_down_label.Text = area_down_label.Text.Split(':')[0].Replace(" ", "") + " : " + area_down_value;
                var dic = halconDev.action(threhold_down_value, threhold_up_value, area_down_value, area_up_value, pictureBox1, textBox1.Text);
                listView1.Items.Clear();
                foreach (var i in dic)
                {
                    ListViewItem item = new ListViewItem();
                    item.SubItems.Add(i[1]);
                    item.Text = i[0];
                    listView1.Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                label1.Text = ex.Message;
            }
        }

        private void area_up_Scroll(object sender, EventArgs e)
        {
            try
            {
                area_up_value = area_up.Value;
                area_up_label.Text = area_up_label.Text.Split(':')[0].Replace(" ", "") + " : " + area_up_value;
                var dic = halconDev.action(threhold_down_value, threhold_up_value, area_down_value, area_up_value, pictureBox1, textBox1.Text);
                listView1.Items.Clear();
                foreach (var i in dic)
                {
                    ListViewItem item = new ListViewItem();
                    item.SubItems.Add(i[1]);
                    item.Text = i[0];
                    listView1.Items.Add(item);
                }
            } 
            catch(Exception ex)
            {
                label1.Text = ex.Message;
            }
}
    }
}
相关推荐
龙潜月七9 小时前
做一个背单词的脚本
数据库·windows·c#·aigc·程序那些事
逑之9 小时前
C语言笔记14:结构体、联合体、枚举
c语言·开发语言·笔记
崇山峻岭之间9 小时前
Matlab学习记录30
开发语言·学习·matlab
stillaliveQEJ9 小时前
【JavaEE】Spring IoC(二)
java·开发语言·spring
民乐团扒谱机9 小时前
【微实验】MATLAB 仿真实战:多普勒效应 —— 洒水车音乐的音调变化仿真
开发语言·matlab·多普勒效应·多普勒频移
寻星探路9 小时前
【Python 全栈测开之路】Python 基础语法精讲(一):常量、变量与运算符
java·开发语言·c++·python·http·ai·c#
朔北之忘 Clancy9 小时前
2020 年 6 月青少年软编等考 C 语言一级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解
csbysj20209 小时前
组合实体模式
开发语言
万物皆字节9 小时前
Spring Cloud Gateway 启动流程源码分析
java·开发语言·spring boot