opencv鼠标事件获取并在图片上手动画线

opencv鼠标事件获取 图像处理操作(手动画线)

基本思路:
(1)读入一张图片
(2)设置鼠标监听事件,鼠标左键按下并且光标移动触发画点操作
(3)判断鼠标监听到的点是否是第一个点,第一个点只画圆(半径为1),后续的点画直线
(4)判断两次触发画点操作间隔的时间,如果时间大于阈值,重新设置当前点为起点
(5)不断更新显示这张图片(opencv画圆画线直接对图进行操作,操作后需要实时更新显示效果)

代码:

//***************************************************************************
//***************************************************************************
//鼠标操作在一张图片上面画线
//***************************************************************************
//***************************************************************************

#include<iostream>
#include<time.h>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>//图像处理的库,circle()要用到
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

Mat img;
Point p1, p2;
int point_num = 0;
clock_t previous=clock(),current;
double duration;


//*********************************************
//响应函数,在点击的地方画圆
//传递过来的参数:鼠标事件,鼠标事件发生处的坐标,FLAG
//********************************************
static void draw_circle(int event, int x, int y, int flags, void *)
{
	if ((event == CV_EVENT_MOUSEMOVE)&&(flags&CV_EVENT_FLAG_LBUTTON))//鼠标左键按下并且光标移动
	{
		p2 = Point(x, y);
		current = clock();//clock返回ms, time则返回s
		duration = (double)(current - previous);//返回的是double类型的s
		cout << duration << endl;

		//如果停顿时间很长,则重新起点画线
		if (duration > 200)//经验阈值200
		{
			point_num = 0;
		}
		cout << "Mouse Event" << endl;

		//判断当前点是否是起点,起点只画圆,后续点画圆连线
		if (point_num != 0)
		{
			//circle(img, p2, 1, Scalar(0, 0, 255)); //描以后的点
			line(img, p1, p2, Scalar(0, 0, 255));//与前一点进行连线  参数:画图板背景、第一个点位置、第二个点位置、BGR颜色
		}
		else
		{
			circle(img, p2, 1, Scalar(0, 0, 255));//描第一个点 参数:画图板背景、原点的位置、半径、BGR颜色
		}
		p1 = p2;
		previous = current;
		point_num++;
		
	}
}


int main()
{
	img = imread("picture.png");
	namedWindow("image");
	setMouseCallback("image", draw_circle);//回调draw_circle(),获取鼠标信息
	while (1)
	{
		imshow("image", img);
		waitKey(30);
	}
}

Tips
(1)用两次画线的点触发之间的时间间隔,判断是否要连续画线
(2)鼠标事件同时获取单击和光标移动,要用event配合flags

if ((event == CV_EVENT_MOUSEMOVE)&&(flags&CV_EVENT_FLAG_LBUTTON))//鼠标左键按下并且光标移动

效果:
在这里插入图片描述

OpenCV是一个强大的计算机视觉库,但它本身并不直接提供鼠标事件处理功能以画正方形。如果你想在OpenCV窗口中通过鼠标交互绘制正方形,你需要编写一些额外的用户交互代码。下面是一个简单的步骤概述: 1. 首先,创建一个`cv::namedWindow()`,以便接收用户的输入。 2. 设置鼠标回调函数,比如`cv::setMouseCallback()`, 这个函数会在鼠标移动或点击时被调用。 3. 在回调函数中,记录鼠标的当前位置以及按下并开始拖动的点。 4. 当鼠标释放时,计算两个点之间的距离,并根据需要判断是否构成正方形边长。 5. 使用`cv::rectangle()`函数,传入起点和终点坐标,画出正方形。 以下是一个简化的伪代码示例: ```cpp #include <opencv2/opencv.hpp> cv::Point start; // 起始点 cv::Point end; // 结束点 void mouseCallback(int event, int x, int y, int flags, void* userdata) { if (event == cv::EVENT_LBUTTONDOWN) { // 左键按下 start = cv::Point(x, y); } else if (event == cv::EVENT_LBUTTONUP) { // 左键抬起 end = cv::Point(x, y); float sideLength = sqrt(pow(end.x - start.x, 2) + pow(end.y - start.y, 2)); if (fabs(start.x - end.x) == sideLength && fabs(start.y - end.y) == sideLength) { cv::rectangle(windowName, start, end, cv::Scalar(0, 255, 0), 2); // 绘制绿色正方形 } } } int main() { cv::namedWindow("Drawing Square", cv::WINDOW_NORMAL); cv::setMouseCallback("Drawing Square", mouseCallback, nullptr); while (true) { cv::imshow("Drawing Square", img); // 显示图像 if (cv::waitKey(1) >= 0) break; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值