队列在一个halcon项目中的使用

公司用halcon机器视觉技术在外地有一个项目,就是找到集装箱地板上的钉子的坐标,然后在这个坐标上用油封住这个钉子。
一,这个项目的框架早就搭建好了,框架采用了生产者 / 消费者模式。
在原来的代码Test()函数中,

// 测试
private void Test(HImage image)
{
	_halcon.Find_Nail(image, 0, 0, 1800, 1800, 180, 5000, 15000, 7.5, out HTuple width, out HTuple height);
	_formMain.DisplayImageMessage(string.Format("w:{0},H:{1}", width, height));
			
}

halcon找到了了钉子,并且显示它的坐标。
为了能在用户通过上位机给我们这里传递指令后,我们必须发送还给他们钉子的坐标,我声明了一个全局变量队列 q

public Queue q;

并且修改了TestI()函数

// 测试1 (实际使用)
private Queue Test1(HImage image)
{
	_halcon.Find_Nail(image, UpLeftX, UpLeftY, DownRightX, DownRightY, Grayscale, Area1, Area2, Crevice, out HTuple width, out HTuple height);
			
	Queue tempq = new Queue();
	for (int i = 0; i < width.Length; i++)
	{
		strtemp = Math.Round((double)width[i]) + " " + Math.Round((double)height[i]);
				tempq.Enqueue(strtemp);
	}
    	return tempq;
}

让它返回一个队列tempq,因为队列是先进先出的,所以只要有外来的指令传过来,总可以把先采集到的坐标发送出去。

public void ReceiveImage(HImage image)
{
	_formMain.DisplayImage(image);
    q = Test1(image);
	_formMain.DisplayImageMessage();
	image.Dispose();
}
while (q.Count > 0)
{				
		message = (string)q.Dequeue();
		SplitCoord(message, out int[] x, out int[] y);
		var senddata = FormatHelper.FormatSend(x, y);
		foreach (var item in senddata)
		{
			tmp.Append(item.ToString("X2") + " ");
		}
			_serial.SendData(senddata);
		//记录到log中
		SaveFile("找到坐标点(" + i +"): " + message);
		i++;
}

二,要在屏幕上显示来一条指令,发送还此时的钉子坐标,原来的显示函数是这么写的:

        // 显示Log
		public void DisplayImageMessage(string message)
		{
			var len = _screenMessage.Count;
			if (len >= Screen_Message_Row)
			{
				_screenMessage.RemoveAt(0);
			}
			_screenMessage.Add(message);

			var top = 0;
			foreach (var m in _screenMessage)
			{
				hSmartWindowControlMain.HalconWindow.DispText(m,
				"window", top, "left", "green", "box", 0);
				top += 20;
			}
		}

但是这样会使屏幕上出现每行都有字的现象,干扰视觉。
我想不如这个函数每次把屏幕清空,然后把整个屏幕(一共十行显示)按照接受到的字符全部显示;而接受到的屏幕字符也采用一个队列,考虑到队列还是先进先出,所以后面的字符会在底下显示,同时把最上面的字清掉。那么接受的字符本身就是就考虑字符超过十行后,会把上面的行清除掉。

        //实际使用
		public void DisplayImageMessage()
		{ 
			string[] tempStr = new string[10] { "", "", "", "", "", "", "", "", "", ""} ;
			_screenMessage.Clear();
			if (_mainController.mQ.Count > 0)
			{
				_mainController.mQ.CopyTo(tempStr,0);
				for (int i = 0; i < tempStr.Length; i++)
				{
					_screenMessage.Add((string)tempStr[i]);
				}
				var top = 0;
				foreach (var m in _screenMessage)
				{
					hSmartWindowControlMain.HalconWindow.DispText(m,
					"window", top, "left", "green", "box", 0);
					top += 20;
				}

			}
		}
        // 连接设备
		public void ConnectDevice()
		{
			var message = "";
			try
			{
				_imageGrabber.OpenGrabber(_programParam.VisionInterfaceName,
					_programParam.VisionCameraType, _programParam.VisionDeviceName);
				
			}
			catch (Exception e)
			{
				 message = string.Format("连接相机失败:{0}。", e.Message);
				if (mQ.Count >= 10)
				{
					mQ.Dequeue();
					mQ.Enqueue(message);
				}
				else
				{ 
				   mQ.Enqueue(message);
				}
				LogHelper.WriteLog(message);
				_formMain.DisplayImageMessage();
			}
			//后台打开串口
			var s = _serial.Connect(out string error);
			if (s)
			{			
				message = string.Format("打开串口成功: {0}", _param.SerialName);
				if (mQ.Count >= 10)
				{
					mQ.Dequeue();
					mQ.Enqueue(message);
				}
				else
				{
					mQ.Enqueue(message);
				}
				LogHelper.WriteLog(message);
				_formMain.DisplayImageMessage();
			}
			else
			{
				message = string.Format("打开串口失败:{0}" , error);
				if (mQ.Count >= 10)
				{
					mQ.Dequeue();
					mQ.Enqueue(message);
				}
				else
				{
					mQ.Enqueue(message);
				}
				LogHelper.WriteLog(message);
				_formMain.DisplayImageMessage();
			}

		    LogHelper.WriteLog(message);
		}

这样,在这个项目中,我使用了2次队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值