当前位置: 首页 > news >正文

Kithara与OpenCV (二)

Kithara使用OpenCV + QT 进行特征检测


目录

    • Kithara使用OpenCV + QT 进行特征检测
      • OpenCV 特征检测简介
      • Qt应用框架简介
      • 项目说明
      • 关键代码
      • 抖动测试
          • 测试平台:
          • 测试结果:
          • 结论


OpenCV 特征检测简介

OpenCV是一个开源的计算机视觉库,提供了各种图像处理和计算机视觉算法的实现。特征检测是其中重要的功能之一。

特征检测是一种在图像中寻找关键点或感兴趣区域的技术。这些关键点通常具有以下特征:边缘、角点、斑点等。特征检测算法可以帮助我们定位和识别图像中的物体以及进行图像配准、目标跟踪等应用。

OpenCV提供了多种特征检测算法的实现,包括SIFT、SURF、ORB等。其中,SIFT(尺度不变特征变换)和SURF(速度ed特征变换)是两种常用的基于局部特征的算法,它们具有尺度不变性和旋转不变性,适用于广泛的图像变换和缩放操作。ORB(Oriented FAST and Rotated BRIEF)是一种结合了FAST关键点检测器和BRIEF描述符的快速算法,适用于实时应用。

特征检测的步骤通常包括关键点检测、关键点描述和匹配。关键点检测是在图像中找到具有显著性质的点,如边缘、角点等。关键点描述是为每个关键点生成一个描述符,用于表示其局部特征。匹配是将两个图像中的关键点进行配对,找到相对应的点对。

特征检测在计算机视觉领域有广泛的应用,如图像配准、目标识别、物体检测、增强现实等。通过使用OpenCV提供的特征检测算法,可以方便地实现这些应用。

关于Kithara如何调用OpenCV,以及如何编译适用于Kithara的OpenCV开发库可以查看 Kithara与OpenCV (一)

Qt应用框架简介

Qt是一个跨平台的C++应用程序开发框架。它提供了一套丰富的库和工具,用于开发图形用户界面(GUI)应用程序、网络应用程序和嵌入式应用程序,由于本章文章重点并不是Qt,所以就不展开说明,如果对Qt感兴趣,可以去Qt官网或者其他博客。

项目说明

使用Kithara Windows实时套件和OpenCV的组合,可以进行圆形检测,并结合Qt图形化应用框架实时显示检测图像,可以选择不同网口的摄像头和调节检测圆的参数,并测试处理抖动。

编写流程:

  1. 导入Kithara Windows实时套件和OpenCV库。
  2. 使用Qt图形化应用框架创建一个界面,包括一个图像显示区域和参数调节区域。
  3. 初始化Kithara并打开摄像头,开始实时获取图像。
  4. 在任务处理中,将实时获取的图像传递给OpenCV进行圆形检测。
  5. 根据检测结果,在图像上绘制圆形,并通过共享内存j将数据回传到应用层将图像实时显示在界面的图像显示区域中。
  6. 在参数调节区域中,添加可调节的参数,如圆形半径、最小阈值等,通过滑动条或输入框来修改参数。
  7. 当参数发生变化时,重新进行圆形检测,并在图像上实时显示检测结果。
  8. 可以添加其他功能,进行扩展。
  9. 结束时,释放资源和关闭摄像头。

在这里插入图片描述

关键代码

// 这是实时任务将运行的函数,并对接收到的图像执行 OpenCV 操作。只有实时任务才应调用 OpenCV 函数。
KSError __stdcall OpenCVcallback(void * /*pArgs*/, void * /*pContext*/)
{// 在内核层模式下自动并行化 OpenCV 可能会与您的实时应用程序冲突。 建议关闭自动并行化,除非真的需要// 禁用并行化cv::setNumThreads(0);// 表示已准备好处理图像。krenel_data_ptr_->ready = 1;// 图形抖动性测试int64 last_diff_time {0};int is_valid_time = 0;  // 时间是否有效 0 无效 1 时间有效 2 时间差有效int count = 0;  // 计数器int64 jitter_time_sum {0};  // 抖动总时间// 处理循环,此循环仅在发出中止信号时停止。for (;;){// 等待图像接收或停止的通知。KSError error = KS_waitForEvent(krenel_data_ptr_->image_received_event_handle, KSF_NO_FLAGS, 0);if (error != KS_OK) { KS_printK("KS_waitForEvent failed! \n"); }if (krenel_data_ptr_->abort != 0) { break; }// 计数器count++;// 获取当前时间,用于计算图像处理的抖动时间int64 last_time {0};error = KS_getClock(&last_time, KS_CLOCK_MEASURE_HIGHEST);if (error != KS_OK) { return error; }// 获取接收到的图像数据的缓冲区KSCameraBlock *camera_block;void *image_data;error = KS_recvCameraImage(krenel_data_ptr_->stream_handle, &image_data, &camera_block,KSF_NO_FLAGS);if (error != KS_OK){krenel_data_ptr_->ready = 1;continue;}//如果接收到的块类型不是图像,我们跳过。在任何情况下,如果 KS_recvCameraImage() 成功接收到的缓冲区必须使用 KS_releaseCameraImage() 释放。if (camera_block->blockType != KS_CAMERA_BLOCKTYPE_IMAGE){KS_releaseCameraImage(krenel_data_ptr_->stream_handle, image_data, KSF_NO_FLAGS);break;}// 在构建 OpenCV cv::Mat 之前,请检查接收到的图像是否具有正确的像素格式。const auto *image_block = reinterpret_cast<KSCameraImage *>(camera_block);// 图像转换cv::Mat image = CreateMat(image_block->height, image_block->width, image_block->pixelFormat, image_data, image_block->linePadding);// 圆形检测image = CircleDetect(krenel_data_ptr_->check_circle_param, image);error = KS_releaseCameraImage(krenel_data_ptr_->stream_handle, image_data, KSF_NO_FLAGS);if (error != KS_OK) { KS_printK("KS_releaseCameraImage failed! \n"); }// 填充图像信息到共享内存中krenel_data_ptr_->image_info.image_height = image.rows;krenel_data_ptr_->image_info.image_width = image.cols;krenel_data_ptr_->image_info.pixel_format = image_block->pixelFormat;if (image_block->pixelFormat == KS_CAMERA_PIXEL_MONO_8){KS_memCpy(pixel_buffer_, image.data, (int) image.cols * image.rows, KSF_NO_FLAGS);}else if (image_block->pixelFormat == KS_CAMERA_PIXEL_BGR_8){KS_memCpy(pixel_buffer_, image.data, (int) image.cols * image.rows * 3, KSF_NO_FLAGS);}//  图形处理完成后,减去上次处理完成的时间int64 time {0};error = KS_getClock(&time, KS_CLOCK_MEASURE_HIGHEST);if (error != KS_OK) { return error; }// 检测圆处理时间const int64 diff_time = time - last_time;int64 time_cyc = diff_time;KS_convertClock(&time_cyc, KS_CLOCK_MEASURE_HIGHEST, KS_CLOCK_MACHINE_TIME, KSF_NO_FLAGS);krenel_data_ptr_->jitter_value.time_cyc = time_cyc;if (is_valid_time == 0){last_diff_time = diff_time;is_valid_time = 1;}else{// 处理时间的抖动const int64 jitter_time = diff_time - last_diff_time;int64 single_time = jitter_time;KS_convertClock(&single_time, KS_CLOCK_MEASURE_HIGHEST, KS_CLOCK_MACHINE_TIME, KSF_NO_FLAGS); // 100 ns 为单位last_diff_time = diff_time;jitter_time_sum += single_time;if (krenel_data_ptr_->jitter_value.lat_min > single_time){krenel_data_ptr_->jitter_value.lat_min = single_time;}if (krenel_data_ptr_->jitter_value.lat_max < single_time){krenel_data_ptr_->jitter_value.lat_max = single_time;}krenel_data_ptr_->jitter_value.lat_avg = jitter_time_sum / count;krenel_data_ptr_->jitter_value.cur_val = single_time;}krenel_data_ptr_->ready = 1;}return KS_OK;
}

抖动测试

测试平台:

在这里插入图片描述

测试结果:

在这里插入图片描述

结论

Kithara Windows实时套件得益于独占CPU处理OpenCV对图像中圆的检测,无论Windows负载如何,检测任务任能稳定处理。
我也同时测试了不同平台对检测任务的影响,如图:
在这里插入图片描述
可以同样的检测任务,抖动出现较大差异,说明性能检测的CPU对图像处理有一定的影响,测试过程中还发现,不同算法,图像的复杂度等均有一定影响。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 观察者模式的实现
  • 海外短剧开源系统UNIAPP源码(支持多语言/海外支付/快捷登录)
  • 【Docker 系列】学习路线
  • Xcode多任务处理指南:释放iOS应用的并发潜能
  • 快速上手文心一言:让创作更轻松
  • TensorFlow系列:第五讲:移动端部署模型
  • 探索Java网络编程精髓:UDP与TCP的实战魔法!
  • 2024年高职云计算实验室建设及云计算实训平台整体解决方案
  • 三级_网络技术_13_局域网技术基础及应用
  • android 居中对齐
  • kafka部署以及常用命令详细总结
  • 【Docker系列】Docker 的基本概念和优势,以及在应用程序开发中的实际应用
  • 期货量化交易客户端开源教学第一节——交易服务器的安装
  • 【GameFramework扩展应用】6-3、GameFramework框架增加日志保存功能
  • 如何压缩pdf文件大小,怎么压缩pdf文件大小
  • [PHP内核探索]PHP中的哈希表
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • 07.Android之多媒体问题
  • HTML中设置input等文本框为不可操作
  • HTTP请求重发
  • Javascripit类型转换比较那点事儿,双等号(==)
  • JavaScript 奇技淫巧
  • javascript面向对象之创建对象
  • Java到底能干嘛?
  • maya建模与骨骼动画快速实现人工鱼
  • PermissionScope Swift4 兼容问题
  • SegmentFault 2015 Top Rank
  • Spring Cloud中负载均衡器概览
  • Vue小说阅读器(仿追书神器)
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 基于 Babel 的 npm 包最小化设置
  • 配置 PM2 实现代码自动发布
  • 前端性能优化——回流与重绘
  • 微信开放平台全网发布【失败】的几点排查方法
  • 写给高年级小学生看的《Bash 指南》
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • # Java NIO(一)FileChannel
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #### go map 底层结构 ####
  • #VERDI# 关于如何查看FSM状态机的方法
  • $.ajax()方法详解
  • (24)(24.1) FPV和仿真的机载OSD(三)
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (C++20) consteval立即函数
  • (pycharm)安装python库函数Matplotlib步骤
  • (vue)el-cascader级联选择器按勾选的顺序传值,摆脱层级约束
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (第二周)效能测试
  • (区间dp) (经典例题) 石子合并
  • (十七)Flink 容错机制
  • (算法)求1到1亿间的质数或素数
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决