在 SerialDevice 插件中添加相机增益和光照自动控制功能

以下为实现方式

首先定义串口设备抽象类,为该类设置基本属性和构造函数

csharp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class SerialDevice
{
//串口设备
public SerialPort serialPort;
public ModbusSerialMaster master;

//串口参数
public string portname;
public int baunrate;
public int databits = 8;
public Parity parity = Parity.None;
public StopBits stopbits = StopBits.One;

//设备参数
public string DeviceName;
public SerialDevice()
{
serialPort = new SerialPort();
serialPort.DataBits = databits;
serialPort.Parity = parity;
serialPort.StopBits = stopbits;

}

public void close()
{
serialPort.Close();
}

public void open()
{
if (!serialPort.IsOpen)
{
serialPort.Open();
}
}
}

然后继承这个设备抽象类,定义相机控制类灯光控制类

csharp
1
2
3
4
5
//相机控制
class CameraController : SerialDevice{...}

//灯光控制器
class LightController : SerialDevice{...}

灯光控制类中,加入灯光控制相关指令和操作

相机控制类中,加入相机控制相关串口指令

csharp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public LightController(string PortName, int Baunrate=38400) : base()
{
portname = PortName;
baunrate = Baunrate;

serialPort.PortName = portname;
serialPort.BaudRate = baunrate;
serialPort.Close();
}

//调节灯光亮度
public void Intensity(byte port,int intensity)
{
...;
}

void sendCmd(byte command, byte port, int value) //光源控制器命令发送
{
...;
}
void Check_Dell(ref byte[] buffer) //验证位处理函数
{
...;
}

在 Plugin.cs 中添加 AutoGain 类,并且继承 IPlugin 接口,提供相关接口实现,设置其为周期执行,并且执行周期为 5s,周期事件为根据当前图像平均灰度值调节灯光亮度和相机增益。其设置子对象 灯光控制器 light 和相机控制器 camera 并初始化。

csharp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class AutoGain :IPlugin
{
...;
public string Name
{
get
{
return "自动相机增益和灯光调整插件";
}
}
...;

public bool IsLoop { get { return true; } }
public int Interval { get { return 5; } }

LightController light;
CameraController camera;

//控制参数
public bool CameraAutoGain = true;
public bool LightAutoAdjust = true;

int Min_threshold_mean = 130;
int Max_threshold_mean = 170;
int Min_adjust_mean = 140;
int Max_adjust_mean = 160;
int Light_adjust_stride = 4;
double Camera_adjust_stride = 0.2;

double gain = 0.5;
int intensity = 125;

//接受参数

double mean = 0;

public EvtHanlder hanlder
{
get
{
EvtHanlder h = new EvtHanlder();
h.DefectFoundEvent += DefectFoundHandler;
return h;
}

}
}

在 Attributes 列表中添加相应的控制参数,供外部修改相关参数。

csharp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void Init(Control control = null)
{
...;
camera = new CameraController();
//临时设置串口号
light = new LightController("COM3");

Attributes = new Dictionary<string, object>();

//添加控制参数

Attributes.Add("Camera", camera);
Attributes.Add("Light", light);
Attributes.Add("Light.COM", light.serialPort.PortName);
Attributes.Add("Light.intensity", intensity);
Attributes.Add("Camera.gain", gain);


//开关
Attributes.Add("CameraAutoGain", CameraAutoGain);
Attributes.Add("LightAutoAdjust", LightAutoAdjust);

}

在 AutoGain 类中添加函数,根据当前暂存的平均灰度值调节灯光和相机增益。

csharp
1
2
3
4
5
public void AutoGainMain(double mean)
{
//算法细节略
...;
}

在全局事件定义中添加检测到瑕疵的事件,在主程序流程中添加相应事件触发器。

csharp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public delegate void DefectFoundHandler(object sender, CustomEventArgs Args);
public class EvtHanlder
{
//定义事件
...;
public event DefectFoundHandler DefectFoundEvent;
//事件触发
public void Trigger(object sender, CustomEventArgs Args)
{

...;
//分类事件处理
switch (e)
{
...;
case CustomEvent.DefectFoundEvent:
DefectFoundEvent(sender, Args);
break;
...;
}
}

public EvtHanlder()
{
...;
DefectFoundEvent += new DefectFoundHandler((object sender, CustomEventArgs Args) => { });
}
}

在插件 AutoGain 类中添加事件响应函数,绑定函数实现更新当前平均灰度值,供自动调节过程使用。

csharp
1
2
3
4
5
public void DefectFoundHandler(object sender, CustomEventArgs Args) 
{
mean = (double)PluginToolkits.GetValue(Args.msg, "Mean");

}

最后添加周期调用函数实现

csharp
1
2
3
4
5
6
7
8
9
10
11
public void RunLoop()
{
if (camera == null)
return;
if (light == null)
return;
if (mean != 0)
{
Task.Run(() => { AutoGainMain(mean); });
}
}

OK,这样就完成了整个功能插件的实现,编译并将插件放入 plugin 目录应该就能实现自动加载和执行了。

未解决的问题:判断对应设备的串口号并连接。

目前没有相应硬件设备,上机调试的问题后续更新。