1.意义
这段程序的意义在于实现了一个简单的图像处理程序,通过鼠标交互的方式在图像上绘制矩形框。它的主要作用是:
-
图像标注:通过鼠标点击在图像上绘制矩形框,可以用于标注图像中的感兴趣区域或目标位置。这在计算机视觉任务中非常常见,如目标检测、图像分割等。
-
用户交互:通过鼠标交互,用户可以根据需要自由选择绘制矩形框的位置和大小,提供了一种直观的方式与图像进行交互。
-
程序演示和测试:这段程序可以作为演示和测试使用,展示了如何使用 OpenCV 库进行图像处理和鼠标事件的处理。可以用于教学或学习目的,以及验证和调试其他图像处理算法。
2.效果图
总的来说,这段程序的意义在于提供了一个基于鼠标交互的图像处理功能,可以用于图像标注、用户交互和程序演示等场景。
3. c++ 代码
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
struct param {
bool drawing; // 是否正在绘制矩形框的标志
Rect box; // 矩形框的位置和大小
bool last_box = false; // 是否是最后一个绘制的矩形框的标志
};
void onMouse(int event, int x, int y, int flags, void* params) {
param* rect = reinterpret_cast<param*>(params);
if (event == EVENT_LBUTTONDOWN) { // 左键按下,开始绘制
rect->box = Rect(x, y, 0, 0);
rect->drawing = true;
rect->last_box = false;
}
else if (event == EVENT_LBUTTONUP) { // 左键释放,结束绘制
rect->drawing = false;
rect->last_box = true;
}
else if (event == EVENT_MOUSEMOVE) { // 鼠标移动,更新矩形框大小
if (rect->drawing) {
rect->box.width = x - rect->box.x;
rect->box.height = y - rect->box.y;
}
}
}
int main(int argc, char** argv) {
// 读取图像
cv::Mat image1 = cv::imread("../images/bus.jpg");
if (image1.empty()) {
std::cout << "Error reading image..." << std::endl;
return 0;
}
// 创建窗口并设置鼠标回调函数
cv::namedWindow("Image1", 0);
param params; // 存储绘制参数的结构体对象
cv::setMouseCallback("Image1", onMouse, ¶ms);
while (true) {
// 显示图像
imshow("Image1", image1);
if (params.drawing) { // 绘制矩形框
cv::Mat temp = image1.clone();
rectangle(temp, params.box, Scalar(0, 255, 0), 2);
imshow("Image1", temp);
}
else if (params.last_box) { // 最后一个绘制的矩形框
rectangle(image1, params.box, Scalar(0, 255, 0), 2);
imshow("Image1", image1);
}
int key = waitKey(1);
if (key == 'q' || key == 27) // 按下 'q' 键或者 Esc 键退出循环
break;
}
destroyWindow("Image1");
return 0;}
4. python代码
下面是将该程序转换为Python版本的代码:
import cv2
class Param:
def __init__(self):
self.drawing = False
self.box = None
self.last_box = False
def on_mouse(event, x, y, flags, param):
rect = param
if event == cv2.EVENT_LBUTTONDOWN: # 左键按下,开始绘制
rect.box = (x, y, 0, 0)
rect.drawing = True
rect.last_box = False
elif event == cv2.EVENT_LBUTTONUP: # 左键释放,结束绘制
rect.drawing = False
rect.last_box = True
elif event == cv2.EVENT_MOUSEMOVE: # 鼠标移动,更新矩形框大小
if rect.drawing:
rect.box = (rect.box[0], rect.box[1], x - rect.box[0], y - rect.box[1])
def main():
image = cv2.imread("../images/bus.jpg")
if image is None:
print("Error reading image...")
return
cv2.namedWindow("Image")
params = Param()
cv2.setMouseCallback("Image", on_mouse, params)
while True:
cv2.imshow("Image", image)
if params.drawing: # 绘制矩形框
temp = image.copy()
cv2.rectangle(temp, (params.box[0], params.box[1]), (params.box[0] + params.box[2], params.box[1] + params.box[3]), (0, 255, 0), 2)
cv2.imshow("Image", temp)
elif params.last_box: # 最后一个绘制的矩形框
cv2.rectangle(image, (params.box[0], params.box[1]), (params.box[0] + params.box[2], params.box[1] + params.box[3]), (0, 255, 0), 2)
cv2.imshow("Image", image)
key = cv2.waitKey(1)
if key == ord('q') or key == 27: # 按下 'q' 键或者 Esc 键退出循环
break
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
这段代码是将之前的C++程序转换为Python版本的代码。它实现了相同的功能,通过鼠标交互在图像上绘制矩形框。使用了cv2
模块来进行图像加载和显示,并调用相应的函数处理鼠标事件。
请注意,Python的语法和函数调用方式与C++略有不同。在Python版本中,我们使用cv2
模块代替了C++中的opencv2/opencv.hpp
头文件,并相应地调整了函数的命名和参数传递方式。