opencv c++鼠标拖动任意画多个圆并同时显示多个圆
时间: 2023-09-10 14:04:54 浏览: 50
### 回答1:
你可以使用 OpenCV 的 `setMouseCallback` 函数来监听鼠标事件,然后在鼠标拖动时画圆并显示出来。以下是一个简单的示例代码:
```c++
#include <opencv2/opencv.hpp>
using namespace cv;
// 定义一个vector来存储所有画的圆
std::vector<Vec3f> circles;
// 鼠标事件回调函数
void onMouse(int event, int x, int y, int flags, void* userdata)
{
if (event == EVENT_LBUTTONDOWN) {
// 鼠标左键按下,记录当前位置
Vec3f circle(x, y, 10);
circles.push_back(circle);
}
else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)) {
// 鼠标左键拖动,更新圆的半径
Vec3f& circle = circles.back();
float dx = x - circle[0];
float dy = y - circle[1];
circle[2] = sqrt(dx*dx + dy*dy);
}
}
int main()
{
Mat image(500, 500, CV_8UC3, Scalar(255, 255, 255));
// 设置鼠标事件回调函数
namedWindow("image");
setMouseCallback("image", onMouse, 0);
while (true) {
// 清空画布
image.setTo(Scalar(255, 255, 255));
// 画出所有圆
for (const auto& circle : circles) {
circle(image, Point(circle[0], circle[1]), circle[2], Scalar(0, 0, 255), 2);
}
imshow("image", image);
char key = waitKey(10);
if (key == 27) break;
}
return 0;
}
```
在这个示例代码中,我们首先定义了一个 `std::vector<Vec3f>` 类型的变量 `circles` 来存储所有画的圆。在 `onMouse` 函数中,当鼠标左键按下时,我们记录当前位置,并创建一个新的圆并添加到 `circles` 中;当鼠标左键拖动时,我们更新当前圆的半径。在 `main` 函数中,我们在一个 `while` 循环中不断地更新画布并显示所有圆。你可以通过按下 ESC 键来退出程序。
### 回答2:
在使用OpenCV的C++编程中,我们可以通过捕获鼠标事件来实现鼠标拖动画多个圆的功能。下面是一个简单的实现过程:
1. 首先,我们需要创建一个用于显示结果的窗口和一个回调函数来处理鼠标事件:
```cpp
#include <opencv2/opencv.hpp>
using namespace cv;
void onMouse(int event, int x, int y, int flags, void* param);
Mat image;
int main() {
// 创建窗口
namedWindow("Draw Circles", WINDOW_AUTOSIZE);
image = Mat::zeros(500, 500, CV_8UC3);
// 设置鼠标事件的回调函数
setMouseCallback("Draw Circles", onMouse);
// 循环显示画布
while (true) {
imshow("Draw Circles", image);
// 等待按下ESC键退出程序
if (waitKey(20) == 27) {
break;
}
}
return 0;
}
void onMouse(int event, int x, int y, int flags, void* param) {
switch (event) {
case EVENT_LBUTTONDOWN: {
// 鼠标左键按下,记录当前位置
Point center(x, y);
// 生成一个随机颜色
Scalar color(rand() & 255, rand() & 255, rand() & 255);
// 画圆
circle(image, center, 50, color, 3);
break;
}
}
}
```
上述代码中,我们创建了一个名为"Draw Circles"的窗口,并在其中创建了一个底图`image`,用于显示圆。然后,我们设置了鼠标事件的回调函数`onMouse`来处理鼠标左键按下事件,每次按下鼠标左键时,都会在底图`image`上画一个圆。
2. 编译运行上述代码后,会弹出一个窗口,我们可以在窗口中拖动鼠标左键来画多个圆。
通过这种方式,我们可以拖动鼠标任意画多个圆,并在同一个窗口中显示这些圆。
### 回答3:
opencv是一个开源的计算机视觉库,可以在C语言中使用。它提供了许多图像处理和计算机视觉算法的函数和方法。
要实现鼠标拖动任意画多个圆并同时显示多个圆,可以按照以下步骤进行操作:
1. 导入opencv头文件,包括"opencv2/core.hpp"、"opencv2/imgproc.hpp"、"opencv2/highgui.hpp"等。
2. 创建一个空白的图像,用于显示圆。
```
cv::Mat image = cv::Mat::zeros(cv::Size(800, 600), CV_8UC3);
```
3. 定义一个回调函数,用于接收鼠标事件。在回调函数中,根据鼠标事件的类型进行处理:
- 当鼠标按下时,在图像上记录圆心的坐标。
- 当鼠标移动时,在图像上画出圆。
- 当鼠标释放时,将画好的圆显示出来,并在控制台打印出圆心坐标和半径长度。
```
void onMouse(int event, int x, int y, int flags, void* param) {
static cv::Point center;
static bool isMousePressed = false;
if (event == cv::EVENT_LBUTTONDOWN) {
isMousePressed = true;
center = cv::Point(x, y);
}
else if (event == cv::EVENT_MOUSEMOVE && isMousePressed) {
cv::circle(image, center, cv::norm(center - cv::Point(x, y)), cv::Scalar(255, 0, 0), 2);
}
else if (event == cv::EVENT_LBUTTONUP) {
isMousePressed = false;
cv::circle(image, center, cv::norm(center - cv::Point(x, y)), cv::Scalar(255, 0, 0), 2);
cv::imshow("Multiple Circles", image);
std::cout << "Center coordinates: (" << center.x << ", " << center.y << ")" << std::endl;
std::cout << "Radius: " << cv::norm(center - cv::Point(x, y)) << std::endl;
}
}
```
4. 创建一个窗口并在窗口上注册鼠标事件回调函数。
```
cv::namedWindow("Multiple Circles");
cv::setMouseCallback("Multiple Circles", onMouse);
```
5. 进入主循环,等待用户操作,直到按下退出键(通常是Esc键)。
```
while (true) {
cv::imshow("Multiple Circles", image);
if (cv::waitKey(30) == 27)
break;
}
```
通过以上步骤,就可以实现鼠标拖动任意画多个圆并同时显示多个圆的功能。