OpenCV | 项目 | 虚拟绘画

OpenCV | 项目 | 虚拟绘画

捕捉摄像头

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

cpp 复制代码
#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

cpp 复制代码
#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;
}

添加描绘轮廓

cpp 复制代码
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);
    }
}


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

添加边界框

cpp 复制代码
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);
        }
    }
}

绘制

cpp 复制代码
#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;
}

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

相关推荐
老云讲算力市场2 分钟前
智算中心加速迈向超节点时代,奇点算力布局高效算力服务
人工智能·科技
潍坊老登6 分钟前
甲方正在记着办理经营性ICP许可证,我三天二开了一个在线教育系统
人工智能
benben04414 分钟前
大模型之基于TRL的ORPO对齐训练实战篇
人工智能
中微极客31 分钟前
多智能体编排实战:CrewAI vs AutoGen(2026版)
大数据·网络·人工智能
葡萄城技术团队31 分钟前
活字格 AI Coding——重新定义大屏开发范式(三)
人工智能
QXWZ_IA36 分钟前
RTK外业成果怎么判断能不能用于正式成图?交付标准
人工智能·科技·智能硬件
骊城英雄44 分钟前
Rust从入门到精通-trait
人工智能·算法·rust
阿文和她的Key1 小时前
GPT-5.6 降价后, API 账单的三层漏斗该怎么拆
人工智能·gpt·ai·chatgpt
BEOL贝尔科技1 小时前
样本安全存储中还有哪些重要因素需要考虑?如何设置样本安全?
人工智能·安全·数据分析
thesky1234561 小时前
27届大模型岗面试准备(十四):多模态大模型 VLM——从视觉编码器到多模态推理的完整链路
人工智能·ai·大模型