本人为机器视觉入门小白,自己突发奇想,想将自己阶段性的学习总结一下,所以基于自己的条件(即家里没有工业相机、镜头和目标对象)做了一个硬币识别的小Demo。一共分为以下几个部分:
1.图片数据来源和分析
2.HALCON实现
3.C#搭建界面框架
4.C#中嵌入HALCON代码,即联合编程
5.导出.exe文件,运行以及Debug
目标是这样的,在图片中识别出每种类型的硬币数量,然后计算出总钱数。先上结果。C#界面和结果:
1.图片数据来源和分析
图片大小及格式均统一,拍摄的时候已经尽可能的去除了背景噪点,所以图像处理的要求并不很高(重点在于思路)。硬币区分原理本人代码采用直径范围来判断(也可以半径或区域面积,HALCON算子可选项很多)
2.HALCON实现
首先在HALCON自带的HDevelop软件里实现图像处理部分。HALCON代码如下。HD里面采用文件夹读图以方便测试,C#里会修改成选择文件夹图片
list_files ('F:/09 Halcon练习项目/硬币识别/硬币识别APP2/picture', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
* Image Acquisition 01: Do something
*计算图像尺寸,得到图像宽度和高度
get_image_size (Image, Width, Height)
*灰度化
rgb1_to_gray (Image, GrayImage1)
*平滑处理
median_image (GrayImage1, ImageMedian, 'square', 1, 'mirrored')
*二进制阈值分割图像
threshold (ImageMedian, Region, 120, 255)
*填充图像中各个区域的小孔
fill_up (Region, RegionFillUp)
*区域连通
connection (RegionFillUp, ConnectedRegions)
*面积筛选
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 13000, 36296)
*圆形度筛选
select_shape(SelectedRegions, SelectedRegions1, 'circularity', 'and', 0.75, 1)
*计算区域数量
count_obj (SelectedRegions1, Number)
*得到各个区域数据
gen_contour_region_xld (SelectedRegions1, Contours1, 'center')
fit_circle_contour_xld (Contours1, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
i:=0
dev_display (Image)
*设置显示颜色
dev_set_color ('red')
*设置显示线宽
dev_set_line_width (3)
*循环,分别将所有区域画出
for J:= 0 to Number by 1
if(J<Number)
gen_circle_contour_xld (Contours, Row[i], Column[i], Radius[i], 0, 6.28318, 'positive', 1)
i:=i+1
dev_display (Contours)
endif
endfor
stop()
endfor
3.C#搭建界面框架
图片显示窗口采用HALCON的HWindowControl。
4.C#中嵌入HALCON代码,即联合编程
第2步中的HALCON代码导出成C#代码,即.cs文件。然后将图像算法部分作为一个函数放置在C#代码中。
对于我这种入门菜鸟来说,这里有两点需要学习和练习。一个是窗口适应图片大小,二个是C#选择文件夹里的文件
(1)窗口适应图片,论坛里借鉴别的大神的代码,加载到HALCON显示图片的那行代码的前面。
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, hv_Height - 1, hv_Width - 1);
这里我的HWindowControl窗口长宽比和图片像素长宽比是一样的(数值可以不一样,比例要一样)这样图片不会因为适应窗口出现变形,只会同比例缩小放大。
(2)C#选择文件,即点击界面上的“加载图片”按钮,出现文件夹目录。同样借鉴的大神代码
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "PNG文件|*.png*|JPEG文件|*.jpg*|BMP文件|*.bmp*";
openFileDialog1.RestoreDirectory = true;
openFileDialog1.FilterIndex = 1;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
ImagePath = openFileDialog1.FileName;
HD.ReadPicture(hWindowControl1.HalconWindow, ImagePath);
}
}
button1_Click即是“打开图片”按钮。
关于Halcon算子部分的代码,我是单独建的一个函数,然后在Form1里面调用该函数,以实现图像处理和显示。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HalconDotNet;
public partial class HDevelopExport
{
public void InitHalcon()
{
// Default settings used in HDevelop
HOperatorSet.SetSystem(