OpenCV | 项目 | 虚拟绘画

OpenCV | 项目 | 虚拟绘画

捕捉摄像头

如果在虚拟机中运行,请确保虚拟机摄像头打开。

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
    VideoCapture cap(0);

    Mat img;
    
    while(1) {
        cap.read(img);
        imshow("Image", img);
        waitKey(1);
    }

    return 0;
}

捕捉对应单一颜色

myColors 的颜色值对应 hmin smin vmin hmax smax vmax

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

vector<vector<int>> myColors {{109,125,66,179,209,215}, // red
                              {35, 81, 131, 52, 255, 214}}; // Green

vector<Scalar> myColorValues{   {0, 0, 255}, // red
                                {0, 255, 0}}; // Green

Mat img;

void findColor(Mat img)
{
    Mat imgHSV;
    cvtColor(img, imgHSV, COLOR_BGR2HSV);
    
    for(int i = 0; i < myColors.size(); i ++)
    {
        Scalar lower(myColors[i][0], myColors[i][1], myColors[i][2]);
        Scalar upper(myColors[i][3], myColors[i][4], myColors[i][5]);

        Mat mask;
        inRange(imgHSV, lower, upper, mask);

        imshow(to_string(i), mask);
    }
}

int main()
{
    VideoCapture cap(0);
    
    while(1) {
        cap.read(img);

        findColor(img);

        imshow("Image", img);
        waitKey(1);
    }

    return 0;
}

添加描绘轮廓

void getContours(Mat imgDil)
{
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;

    findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

	vector<vector<Point>> conPoly(contours.size());
	vector<Rect> boundRect(contours.size());
    for(int i = 0; i < contours.size(); i ++)
    {
        int area = contourArea(contours[i]);
        cout << area << endl;

        string objectType;

        if(area > 1000) 
        {
            float peri = arcLength(contours[i], true);

            approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);

            drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);

            cout << conPoly[i].size() << endl;

            boundRect[i] = boundingRect(conPoly[i]);
        }
    }
}

void findColor(Mat img)
{
    Mat imgHSV;
    cvtColor(img, imgHSV, COLOR_BGR2HSV);
    
    for(int i = 0; i < myColors.size(); i ++)
    {
        Scalar lower(myColors[i][0], myColors[i][1], myColors[i][2]);
        Scalar upper(myColors[i][3], myColors[i][4], myColors[i][5]);

        Mat mask;
        inRange(imgHSV, lower, upper, mask);

        imshow(to_string(i), mask);
        getContours(mask);
    }
}


883b27456b42a44fe730c8484118ee4.png
(不过识别的还是有点抽象的, (逃~))

添加边界框

void getContours(Mat imgDil)
{
    ...

    for(int i = 0; i < contours.size(); i ++)
    {
        ...
        
        if(area > 1000) 
        {
            ...
            drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
            rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 5);
        }
    }
}

绘制

#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

Mat srcimg;
Mat img;

vector<vector<int>> newPoints;

vector<vector<int>> myColors {{118, 0, 171, 130, 255, 232}, // White
                              {35, 81, 131, 52, 255, 214}}; // Green

vector<Scalar> myColorValues{   {255, 0, 255}, // Purple
                                {0, 255, 0}}; // Green

Point getContours(Mat imgDil)
{
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;

    findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    vector<vector<Point>> conPoly(contours.size());
    vector<Rect> boundRect(contours.size());

    Point myPoint(0, 0);

    for(int i = 0; i < contours.size(); i ++)
    {
        int area = contourArea(contours[i]);
        cout << area << endl;
        
        string objectType;

        if(area > 1000) 
        {
            float peri = arcLength(contours[i], true);

            approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);

            cout << conPoly[i].size() << endl;

            boundRect[i] = boundingRect(conPoly[i]);
            myPoint.x = boundRect[i].x + boundRect[i].width / 2;
            myPoint.y = boundRect[i].y;

            drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);
            rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 5);
        }
    }

    return myPoint;
}

vector<vector<int>> findColor(Mat img)
{
    Mat imgHSV;
    cvtColor(img, imgHSV, COLOR_BGR2HSV);
    
    for(int i = 0; i < myColors.size(); i ++)
    {
        Scalar lower(myColors[i][0], myColors[i][1], myColors[i][2]);
        Scalar upper(myColors[i][3], myColors[i][4], myColors[i][5]);

        Mat mask;
        inRange(imgHSV, lower, upper, mask);

        imshow(to_string(i), mask);
        Point myPoint = getContours(mask);

        if(myPoint.x != 0 && myPoint.y != 0)
            newPoints.push_back({myPoint.x, myPoint.y, i});
    }
    return newPoints;
}

void drawOnCanvas(vector<vector<int>> newPoints, vector<Scalar> myColorValues)
{
    for(int i = 0; i < newPoints.size(); i ++)
    {
        circle(img, Point(newPoints[i][0], newPoints[i][1]), 10, myColorValues[newPoints[i][2]], FILLED);
    }
}


int main()
{
    VideoCapture cap(0);
    
    while(1) {
        cap.read(srcimg);
        Mat resultImage2;
	    flip(srcimg, img, 1);

        newPoints = findColor(img);
        drawOnCanvas(newPoints, myColorValues);

        imshow("Image", img);
        waitKey(1);
    }

    return 0;
}

可以根据捕获到的物体来进行绘制(我这里代码采用了白色物体,取值不是很准确,所以会有断断续续的点。)

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

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

相关文章

应用案例 | 商业电气承包商借助Softing NetXpert XG2节省网络验证时间

一家提供全方位服务的电气承包商通过使用Softing NetXpert XG2顺利完成了此次工作任务——简化了故障排查的同时&#xff0c;还在很大程度上减少了不必要的售后回访。 对已经安装好的光纤或铜缆以太网网络进行认证测试可能会面临不同的挑战&#xff0c;这具体取决于网络的规模、…

【八】centos7.6安装chrome和chromedriver并启动selenium

学习来源&#xff1a; 安装chrome和chrome driver -----https://blog.csdn.net/zdlcome/article/details/133813441 安装Python11 -----https://blog.csdn.net/weixin_43741408/article/details/130251102 chromedriver下载地址 -----https://googlechromelabs.github.io/chrom…

ICode国际青少年编程竞赛- Python-4级训练场-嵌套for循环入门

ICode国际青少年编程竞赛- Python-4级训练场-嵌套for循环入门 1、 for i in range(3):Dev.step(3)for j in range(3):Dev.turnLeft()Dev.step(-2)Dev.turnLeft()2、 for i in range(3):Dev.turnLeft()Dev.step(4)Dev.turnRight()Dev.step(2)for i in range(4):Dev.step(2)D…

flstudio21中文版2024最新下载安装图文使用教程

FL Studio 21.2.3.4004中文版 中文别名水果编曲软件&#xff0c;是一款全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室&#xff0c;它为您提供了一个集成的开发环境&#xff0c;使用起来非常简单有效&#xf…

AI赋能未来教育:中国教学科研新蓝图

设“人啊 前言 回顾过去&#xff0c;传统的教育模式以知识灌输和应试为主&#xff0c;虽培养出大量人才&#xff0c;但也存在着学生创新能力不足、实践经验缺乏等问题。随着时代的进步和科技的发展&#xff0c;传统教育模式已难以满足当今社会对人才的需求。然而&#xff0c;当…

基于双经度模型的鱼眼图像畸变校正

文章目录 1. 简介2. 基本原理基本思路从目标图到半球面模型的投影从半球面模型到鱼眼图像的投影正交投影等距投影 3.实际效果示例论文中的原图去畸变 4. 有意思的玩法5. 对生成的鱼眼图去畸变 1. 简介 算法来自论文《基于双经度模型的鱼眼图像畸变矫正方法》 2. 基本原理 基本…

Java实现的网上书店系统(附带完整源码)

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者 实现技术:JSP技术;javaBean;servlet;MySql数据库。 系统功能结构图 该系统为MVC结构,它的运行环境分客户端、应用服务器端和数据库服务器端三部分 书店系统需求分析: 通过…

charts3D地球--添加航线

要在地球视角下画出海运路线图 方案 添加 globl 地球创建geo地理坐标系创建canvas对象用于承载地图世界地图this.worldChart //初始化canvas节点let cav document.createElement("canvas");this.$echarts.registerMap("world", geoJson);this.worldCha…

【Linux】环境变量是什么?如何配置?详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

相同的树——java

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true示例 2&…

C#高级编程笔记-泛型

本章的主要内容如下&#xff1a; ● 泛型概述 ● 创建泛型类 ● 泛型类的特性 ● 泛型接口 ● 泛型结构 ● 泛型方法 目录 1.1 泛型概述 1.1.1 性能 1.1.2 类型安全 1.1.3 二进制代码的重用 1.1.4 代码的扩展 1.1.5 命名…

SpringBootWeb 篇-深入了解请求响应(服务端接收不同类型的请求参数的方式)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 请求响应概述 1.1 简单参数 1.2 实体参数 2.3 数组集合参数 2.4 日期参数 2.5 json 参数 2.6 路径参数 3.0 完整代码 1.0 请求响应概述 当客户端发送不同的请求参…

【驱动】SPI

1、简介 SPI(Serial Peripheral interface)串行外设接口。 特点: 高速:最大几十M,比如,AD9361的SPI总线速度可以达到40MHz以上全双工:主机在MOSI线上发送一位数据,从机读取它,而从机在MISO线上发送一位数据,主机读取它一主多从:主机产生时钟信号,通过片选引脚选择…

微火全域外卖城市合伙人究竟是什么?详细介绍

随着外卖市场的蓬勃发展&#xff0c;微火全域外卖团购业务正逐渐崭露头角&#xff0c;成为商家与消费者之间的新桥梁。这种业务模式&#xff0c;也被称为全域合伙人&#xff0c;其魅力在于其独特的多平台销售策略和简便的管理系统。那么&#xff0c;这种全域外卖城市合伙人&…

N1077B keysight 是德 光/电时钟恢复设备,参数

Keysight N1077B是一款光/电时钟恢复设备&#xff0c;支持115 MBd至24 GBd的数据速率范围&#xff0c;适用于多模和单模光信号以及电信号。该设备能够处理PAM4和NRZ两种类型的数据信号&#xff0c;并提供符合标准的时钟恢复功能。 型 号&#xff1a;N1077B/A 名 称&#xff1a…

【教程向】从零开始创建浏览器插件(四)探索Chrome扩展的更多常用API

探索Chrome扩展的更多常用API 在Chrome扩展开发中&#xff0c;除了最基础的API外&#xff0c;Chrome还提供了一系列强大的API&#xff0c;允许开发者与浏览器的各种功能进行交互。本文将介绍其中几个常用的API&#xff0c;并提供详细的示例代码帮助您开始利用这些API。 书签…

【Spring】初识 Spring AOP(面向切面编程)

目录 1、介绍AOP 1.1、AOP的定义 1.2、AOP的作用 1.3、AOP的核心概念及术语 2、AOP实现示例 3、EnableAspectJAutoProxy注解 1、介绍AOP 1.1、AOP的定义 AOP&#xff08;Aspect Orient Programming&#xff09;&#xff0c;直译过来就是面向切面编程&#xff0c;AOP 是一…

大型模型技术构建本地知识库

使用大型模型技术构建本地知识库是一个复杂的过程&#xff0c;涉及到数据科学、机器学习和软件工程等多个领域的知识。以下是构建本地知识库的一般步骤。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.需求分析&#xff1a; 确定知…

软件工程经济学--期末复习资料

软件工程经济学--期末复习资料 前言第一章 绪论第二章 软件工程经济学基础第三章 软件的成本管理与定价分析第四章 软件工程项目评价方法与经济效果评价第五章 软件生产函数、效益分析及不确定性分析第六章 软件工程项目进度计划的制定结尾总结 前言 软件工程经济学&#xff0…

书生作业:XTuner

作业链接&#xff1a; https://github.com/InternLM/Tutorial/blob/camp2/xtuner/homework.md xtuner: https://github.com/InternLM/xtuner 环境配置 首先&#xff0c;按照xtuner的指令依次完成conda环境安装&#xff0c;以及xtuner库的安装。 然后&#xff0c;我们开始尝试…