完整解决方案:Halcon+VisualStudio2015使用线程实现大恒水星相机实时图像采

优采云 发布时间: 2022-10-24 07:51

  完整解决方案:Halcon+VisualStudio2015使用线程实现大恒水星相机实时图像采

  实时采集图像,您可以将采集图像保存到本地文件夹

  具体的C#代码如下:

  使用系统;

  使用系统.集合.通用;

  使用系统组件模型;

  使用系统数据;

  使用系统绘图;

  使用系统;

  使用系统文本;

  使用系统线程;

  使用系统.Windows.Forms;

  使用光标网;

  使用 System.IO;

  命名空间演示

  {

  公共分部类图像采集:形式

  {

  私有线程线程对象;线程

  私有布尔线程停止 = 假; // 确定线程是否已关闭

  私有 HTuple 窗口 ID;

  公众形象采集().

  {

  初始化组件();

  线程对象实例化

  线程对象 = 新线程(新线程启动(线程函数));

  创建哈尔康窗口();// 创建哈尔康显示窗口

  }

  公共空白创建哈尔康窗口()

  

  {

  HTUPLE父亲窗口 = 这个。DisplayVideo_pictureBox.手柄;

  设置窗口的背景色

  HOperatorSet.SetWindowAttr(“background_color”,“黑色”);

  HOperatorSet.OpenWindow(0, 0, this.DisplayVideo_pictureBox.宽度,这个。DisplayVideo_pictureBox.身高,父亲窗口,“可见”,“”,窗外ID);

  }

  线程回调函数

  公共空隙线程函数()

  {

  对象 ho_Image = 空;

  hv_AcqHandle = 空;

  HOperatorSet.GenEmptyObj(out ho_Image);

  HOperatorSet.OpenFramegrabber(“GenICamTL”, 0, 0, 0, 0, 0, 0, “默认”, -1, “默认”, -1, “false” , “default” “MER-131-210U3M(KG0170060082)”, 0, -1, 出hv_AcqHandle);

  300万像素:1280*1024

  整数图像宽度 = 1280;

  整型图像高度 = 1024;//

  线程停止 = 假;

  而 (!线程停止)

  {

  //ho_Image.dispose();

  //HOperatorSet.GrabImage(出ho_Image,hv_AcqHandle);

  HOperatorSet.GrabImageStart(hv_AcqHandle, -1);

  ho_Image.处置();

  HOperatorSet.GrabImageAsync(出ho_Image, hv_AcqHandle, -1);

  调整图像

  通过更改图像的比例来正常显示窗口

  HOperatorSet.SetPart(WindowID, 0, 0, ImageHeight, ImageWidth);

  在窗口中显示图像

  HOperatorSet.dispObj(ho_Image, WindowID);

  

  如果(这个。SaveImage_checkBox.已选中)

  {

  字符串文件名 = DateTime.Now.ToString(“yyyyy-year mm 月 dd 日 HH 小时 mm分钟秒 fff 毫秒”);

  HOperatorSet.WriteImage(ho_Image, “bmp”, 0, Directory.GetCurrentDirectory() + “/image/” + 文件名 + “.bmp”);

  }

  }

  HOperatorSet.CloseFramegrabber(hv_AcqHandle);

  ho_Image.处置();

  }

  私有 void DisplayImage_button_Click(对象发送方,事件Args e)

  {

  if (线程对象.线程状态 == 系统.线程连接.线程状态.未启动)

  {

  线程对象启动();

  }

  如果 ((线程对象.线程状态 == 系统.线程.线程状态.已停止) ||(线程对象.线程状态 == 系统.线程连接.线程状态.中止))

  {

  线程对象 = 新线程(新线程启动(线程函数));

  线程对象启动();

  }

  }

  私有 void StopPlay_button_Click(对象发送方,事件Args e)

  {

  线程停止 = 真;

  }

  }

  }

  控制用户界面界面:

  直观:并发队列:ArrayBlockingQueue实际运用场景和原理

  阵列块队列实际应用场景

  之前,我在一家公司做过一个情感识别系统,通过调用*敏*感*词*接口采集人脸信息,对采集人脸信息进行人脸识别和情感分析,最后通过一定的算法将个人情感数据转换为特定的行为指标值。图片采集部分使用并发队列数组阻止队列。

  如上图所示:有n台摄像机,单线程采集的效率会比较慢,所以在采集摄像机的过程中是多线程的,图片采集需要存储在图片服务器中,对图片服务器写入的要求也很高,图片服务器是集群化的,还需要多线程化。图片存储完毕后,图片数据需要发送到人脸分析服务器进行处理,这涉及到分布式消息,因此黑点部分使用kafka传递消息。多线程图片的红色虚线部分采集信息传递到 ArrayBlockingQueue 中使用的多线程图片存储,该存储是并发安全队列。

  数组阻塞队列简化了类图结构

  从类图中可以看出,Queue 接口提供了用于添加、提供到队列中以及提供用于轮询队列的方法的方法!

  阻塞队列接口添加了一个放入队列的方法,并提供了一种取出队列的方法!

  附加说明:UML 类图结构:

  并发队列阻塞和非阻塞概念

  从上面的类图名称中,可以看出 Queue 提供的方法不是阻塞的!把,拿的方法,封锁队列提供的办法是封锁!让我们遵循旧的想法,让我们用代码来解释阻塞和非阻塞!

  非阻塞

  import java.util.concurrent.ArrayBlockingQueue;

/**

 * @author :jiaolian

 * @date :Created in 2021-02-02 20:16

 * @description:ArrayBlockingQueue阻塞非阻塞测试

 * @modified By:

 * 公众号:叫练

 */

public class ArrayBlockingQueueTest {

<p>

    public static void main(String[] args) {

        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(1);

        arrayBlockingQueue.offer("叫练");

        arrayBlockingQueue.offer("叫练");

        //输出arrayBlockingQueue的长度

        System.out.println(arrayBlockingQueue.size());

    }

}</p>

  如上面的代码所示:将数组块队列的长度设置为1,通过提供方法向队列中添加2个元素,最后打印数组块队列的长度?答案是1,它不会阻塞,因为offer方法丢弃了第二个元素“喊叫”,我们说允许队列继续执行并加入我们调用的队列非阻塞。如果切换到 add 方法,该怎么办?将报告错误队列溢出,如下图所示!但它还没有阻止。我们来看看有哪些堵塞!

  阻塞

  import java.util.concurrent.ArrayBlockingQueue;

/**

 * @author :jiaolian

 * @date :Created in 2021-02-02 20:16

 * @description:ArrayBlockingQueue阻塞非阻塞测试

 * @modified By:

 * 公众号:叫练

 */

public class ArrayBlockingQueueTest {

    public static void main(String[] args) throws InterruptedException {

        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(1);

<p>

        arrayBlockingQueue.put("叫练");

        arrayBlockingQueue.put("叫练");

        //输出arrayBlockingQueue的长度

        System.out.println(arrayBlockingQueue.size());

    }

}</p>

  如上面的代码所示:数组块队列长度为1,通过 put 方法向队列中添加 2 个元素,最后输出数组阻止队列长度是多少?答案是控制台继续运行,因为程序在添加第二个“调用”时会阻塞。我们说,不能允许的队列继续执行,当我们离开队列并加入队列时,我们调用阻塞,添加方法,轮询方法,采取方法 我们不会一一给出例子,你可以编写代码来做最简单的测试!

  好吧,让我们总结一下几种方法!

  优惠:队列已满且已丢弃。

  add:队列已满,但有错误。

  放置:块。

  轮询 :如果队列为空,则返回 null。

  采取:阻止。

  分析数组块队列的实现原理

  如上所示,数组阻止队列是用数组实现的,重入锁独占锁控制数组的进入和退出。让我们来看看采取,放置方法流,其他方法也是如此。

  完全无阻塞队列并发链接队列

  ConcurrentLinkedQueue还实现了队列接口,提供提供,添加,轮询方法都是非阻塞的,并且从名称中可以看出,底层是链表结构,cas是旋转用于队列内外的。

  列出多线程安全方案:链接阻止队列

  链接阻止队列和数组阻止队列是相似的,链接阻止队列是

  有界,长度为整数.MAX_VALUE,实现时,链接块队列是一个链接列表,并且是一个双锁,如上图所示,采取Lock独占锁控制队列头,putLock控制队列的末尾,不相互影响,目的是增加链接块队列的并发性。

  总结

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线