栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

利用OPENCV实现在视频上绘图

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

利用OPENCV实现在视频上绘图

由于视频是一帧帧刷新的,常见的绘图方法只适用于不变的Mat上,而视频播放下一帧之后上一帧所绘制的图像则随着上一帧被刷掉了,而MFC则是创建一块DC,在DC内画所以原理不同。为了实现在视频和摄像头画面中进行绘图,则需要将绘图点保存在容器中,并在每帧播放的时候都要进行绘图,才能实现连贯的绘图。而OPENCV利用Circle进行画曲线画出来的线是离散的很容易断,与MFC效果又差太远,故想出了利用Polylines和Circle同时绘画,重合出一条连贯的实线,但因此这种方法性能很差,不知有没有其他实现曲线的办法,如果有可以评论区教教我嘻嘻

#include
#include
#include 
#include 
using namespace std;
using namespace cv;

bool g_bDrawing = false;
Point g_nCurrPoint;
Point g_nEndPoint;
vector> vecDrawPoint;
pair tempPoint;
vector vecCircle;
vector vecpoly;
vector> vecCirLine;

void onMouse(int event, int x, int y, int flag, void* param)
{
	Mat& img = *(cv::Mat*)param;

	switch (event)
	{
		//移动鼠标的时候
	case CV_EVENT_MOUSEMOVE:
	{
		if (g_bDrawing == true)
		{
			g_nEndPoint = Point(x, y);
			tempPoint.first = g_nCurrPoint;
			tempPoint.second = g_nEndPoint;
			vecCircle.push_back(g_nEndPoint);
			vecpoly.push_back(g_nEndPoint);
		}
	}
	break;
	//点击鼠标左键时
	case CV_EVENT_LBUTTONDOWN:
	{
		g_bDrawing = true;
		g_nCurrPoint = Point(x, y);
	}
	break;
	//松开鼠标左键时
	case CV_EVENT_LBUTTONUP:
	{
		g_bDrawing = false;
		g_nEndPoint = Point(x, y);
		if (g_nEndPoint != g_nCurrPoint)
		{
			pair linePoint(g_nCurrPoint, g_nEndPoint);
			vecDrawPoint.push_back(linePoint);
		}
		vecpoly.clear();
	}
	break;
	}
}

void DrawRectangle(Mat matFrame)
{
	rectangle(matFrame, tempPoint.first, tempPoint.second, Scalar(255, 255, 0), 2);
	if (!vecDrawPoint.empty())
	{
		for (int i = 0; i < vecDrawPoint.size(); i++)
		{
			rectangle(matFrame, vecDrawPoint[i].first, vecDrawPoint[i].second, Scalar(255, 255, 0), 2);
		}
	}
}

void DrawLine(Mat matFrame)
{
	line(matFrame, tempPoint.first, tempPoint.second, Scalar(255, 255, 0), 1, CV_AA);
	if (!vecDrawPoint.empty())
	{
		for (int i = 0; i < vecDrawPoint.size(); i++)
		{
			line(matFrame, vecDrawPoint[i].first, vecDrawPoint[i].second, Scalar(255, 255, 0), 1, CV_AA);
		}
	}
}

void DrawCir(Mat matFrame)
{
	for (int i = 0; i < vecCircle.size(); i++)
	{
		circle(matFrame, vecCircle[i], 0, Scalar(255, 255, 0), 2, CV_AA);
	}
	if (!vecCircle.empty())
	{
		vecCirLine.push_back(vecpoly);
		for (int i = 0; i < vecCirLine.size(); i++)
		{
			polylines(matFrame, vecCirLine[i], false, Scalar(255, 255, 0), 2);
		}
	}
}

int main()
{
	int nDrawType = 2;//设置绘图类型  1:直线  2:矩形  3:曲线
	string strPath= "E:/test.avi";
	VideoCapture Vcap;
	VideoWriter writer(strPath, 1, Vcap.get(CAP_PROP_FPS), cv::Size(Vcap.get(CAP_PROP_FRAME_WIDTH),
		Vcap.get(CAP_PROP_FRAME_HEIGHT)),true);
	Vcap.open(0);//为0时获取第一个摄像头设备画面,为路径时则打开路径指向的视频文件
	if (!Vcap.isOpened())
	{
		return 0;
	}

	Mat matFrame;

	namedWindow("video", 0);
	setMouseCallback("video", onMouse, (void*)&matFrame);
	while (1)
	{
		Vcap >> matFrame;
		//Canny(matFrame, matCFrame, 20, 100,3);//边缘检测
		if (matFrame.empty())
		{
			break;
		}
		switch (nDrawType)
		{
			case 1:
				DrawLine(matFrame);//画直线
				break;
			case 2:
				DrawRectangle(matFrame);//画矩形
				break;
			case 3:
				DrawCir(matFrame);//画曲线
				break;
		default:
			break;
		}
		
		writer.write(matFrame);

		imshow("video", matFrame);
		if (waitKey(60) > 0)
		{
			break;
		}
	}
	Vcap.release();
	destroyAllWindows();

	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/925587.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号