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对图像处理有一定的影响,测试过程中还发现,不同算法,图像的复杂度等均有一定影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/796214.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Web开发 —— 放大镜效果(HTML、CSS、JavaScript)

目录 一、需求描述 二、实现效果 三、完整代码 四、实现过程 1、HTML 页面结构 2、CSS 元素样式 3、JavaScript动态控制 &#xff08;1&#xff09;获取元素 &#xff08;2&#xff09;控制大图和遮罩层的显隐性 &#xff08;3&#xff09;遮罩层跟随鼠标移动 &…

麦克风设计指南

前言&#xff1a; 本指南基于乐鑫的 ESP32-S3 系列语音开发板。 整机 mic 要求 麦克风电器性能推荐 麦克类型&#xff1a;全向型 MEMS 麦克风 SMD-4P,2.8x1.9mm MEMS 麦克风 顶视图 MEMS 麦克风 底视图 灵敏度 1 Pa 声压下模拟麦灵敏度不低于 -38 dBV&#xff0c;数字麦灵…

CSS技巧专栏:一日一例 5-纯CSS实现背景色从四周向中心填充的按钮特效

特此说明 本专题专注于讲解如何使用CSS制作按钮特效。前置的准备工作和按钮的基本样式,都在本专栏第一篇文章中又详细说明。自本专栏第四篇文章起,本专栏都将直接跳过前面的内容,不再重复复制,需要了解按钮基础样式的同学,请移步:《CSS技巧 - 一日一例 (1):会讨好的热…

全渠道AI智能商品管理软件平台 助力零售品牌占领技术高地

关于7thonline第七在线 1999年创立于纽约&#xff0c;7thonline第七在线全渠道AI智能商品管理平台&#xff0c;以先进的数学算法模型、人工智能和机器学习技术为核心驱动力&#xff0c;融合了众多零售商品管理的卓越实践经验&#xff0c;精心打造出一套深度适配零售业务场景的自…

微信小程序---npm 支持

一、构建 npm 目前小程序已经支持使用 npm 安装第三方包&#xff0c;但是这些 npm 包在小程序中不能够直接使用&#xff0c;必须得使用小程序开发者工具进行构建后才可以使用。 为什么得使用小程序开发者工具需要构建呢❓ 因为 node_modules 目录下的包&#xff0c;不会参与…

PG大会周五于杭州举办;Pika发布4.0;阿里云MySQL上线Zero-ETL集成能力

重要更新 1. PostgreSQL中国技术大会举行12日&#xff08;周五&#xff09;于杭州举办&#xff0c;是PostgreSQL社区年度的大会&#xff0c;举办地点&#xff1a;杭州君尚云郦酒店&#xff08;杭州市上城区临丁路1188号&#xff09;&#xff0c;感兴趣的可以考虑现场参加 ( [1]…

git常用命令及git分支

git常用命令及git分支 git常用命令设置用户签名初始化本地库查看本地库状态将文件添加到暂存区提交到本地库查看历史记录版本穿梭 git分支什么是分支分支的好处分支的操作查看分支创建分支切换分支删除分支合并分支合并冲突 git常用命令 设置用户签名 //设置用户签名 git con…

Ubuntu 修改~/.bashrc终端选择是否使用annconda环境

首先需要明白的是anaconda虽然自带了python&#xff0c;但安装anaconda后并不会覆盖掉你原来的python&#xff08;pip也是一样的&#xff09;&#xff0c;但安装anaconda后它会把自己的bin目录&#xff08;里面有python、pip、conda等命令&#xff09;加到PATH上&#xff0c;而…

Math/System/Runtime/Object

1、Math &#xff08;1&#xff09;常用方法 类型方法名说明public static intabs (int a)返回整数的绝对值public static doublepow (double a,double b)计算a的b次幂的值public static int max (int a,int b) 获取两个int值中的较大值public static intmin (int a,int…

vue学习day07-scoped样式冲突、data是一个函数、props详解、组件通信、非父子通信-event bus 事件总线

19、scoped样式冲突 &#xff08;1&#xff09;默认情况&#xff1a;写在组件中的样式会全局生效&#xff0c;因此会很容易造成多个组件之间的样式冲突问题。 1&#xff09;全局样式&#xff1a;默认组件中的样式会作用到全局 比如&#xff1a; 当只有box1设置边框时&#…

Unity如何查找两个transform最近的公共parent

查找两个子对象最近的父对象 一、问题背景二、解决方案思路核心算法代码 三、总结 一、问题背景 最近看到个关于Unity的问题&#xff1a;在Hierarchy面板中的游戏对象&#xff0c;给定两个子物体transform对象&#xff0c;如何查找这两个transform最近的公共父级parent。感觉挺…

应用帕累托原则学习新的编程语言

在本文中&#xff0c;我将讨论如何应用帕累托原则快速学习一门新的编程语言&#xff0c;并在加深对编程语言的理解的同时开始解决实际问题。 什么是帕累托原则&#xff1f; 帕累托原则&#xff0c;又称 80/20 法则&#xff0c;指出对于许多结果而言&#xff0c;大约 80% 的后…

【简历】某电子科技大学:前端实习简历指导,面试通过率低

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 这是一份一本某电子科技大学的同学简历&#xff0c;投递的职位就是我们前端&#xff0c;但是因为学校是一本&#xff0c;我们说主要主体在…

【Lora模型推荐】Stable Diffusion创作具有玉石翡翠质感的图标设计

站长素材AI教程是站长之家旗下AI绘图教程平台 海量AI免费教程&#xff0c;每日更新干货内容 想要深入学习更多AI绘图教程&#xff0c;请访问站长素材AI教程网&#xff1a; AI教程_深度学习入门指南 - 站长素材 (chinaz.com) logo版权归各公司所有&#xff01;本笔记仅供AIGC…

Cesium 点选3DTiles泛光特效

Cesium 点选3DTiles泛光特效 原理&#xff1a;和上一篇点选Entity相同 直接上效果&#xff1a;

StarRocks部署高可用 FE 集群

一、准备工作 1.1 部署规划 这里我打算部署存算一体模式&#xff0c;三节点。即三个FE节点&#xff0c;三个BE节点。假设三台IP分别为&#xff1a;10.10.10.50、10.10.10.51、10.10.10.52 我将采用三台centos7.9进行部署&#xff0c;单台配置为128C 256G 3T。 1.2 服务器检查…

GESP CCF C++ 二级认证真题 2024年6月

第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级&#xff0c;那他可以选择的认证语言有几种&#xff1f;&#xff08; &#xff09; A. 1 B. 2 C. 3 D. 4 第 2 题 下面流程图在yr输入2024时&#xff0c;可以判定yr代表闰年&#xff0c;并输出 2月…

【LeetCode】2187. 完成旅途的最少时间

1. 题意 2. 分析 二分法有一个关键特征&#xff1a;如果答案answer满足题意&#xff0c;那么对于任何整数i&#xff0c;如果有i>answer&#xff0c;那么i也会是一个存在的解&#xff0c;只不过不是最优解。 本题想要找出一个达到 totalTrips 趟需要的最少时间成本t&#x…

分布式系统中雪花ID的使用及前后台精度解决

本文介绍了雪花ID的应用场景&#xff0c;以及针对雪花id生成精度过大导致数据缺失的解决方案。 一、概念 雪花 ID是一种分布式 ID 生成策略&#xff0c;保证全局唯一&#xff0c;位数组成中含有时间戳&#xff0c;相比UUID,故也能保证自增。 二、应用场景 分库、分表、分片、…

Python 爬虫:使用打码平台来识别各种验证码:

本课程使用的是 超级鹰 打码平台&#xff0c; 没有账户的请自行注册&#xff01; 超级鹰验证码识别-专业的验证码云端识别服务,让验证码识别更快速、更准确、更强大 使用打码平台来攻破验证码难题&#xff0c; 是很简单容易的&#xff0c; 但是要钱&#xff01; 案例代码及测…