OpenCV2:幼儿园篇 第七章 界面事件
一.简介
OpenCV中提供了程序界面中的鼠标和键盘事件
二.鼠标事件
// 设置鼠标回调函数
void setMouseCallback
(
const string& winname,
MouseCallback onMouse,
void* userdata = 0
)
// 被调用的函数指针
void Fun
(
int event,
int x,
int y,
int flags,
void* param)
- event
#define CV_EVENT_MOUSEMOVE 0--滑动
#define CV_EVENT_LBUTTONDOWN 1--左键点击
#define CV_EVENT_RBUTTONDOWN 2--右键点击
#define CV_EVENT_MBUTTONDOWN 3--中键点击
#define CV_EVENT_LBUTTONUP 4--左键放开
#define CV_EVENT_RBUTTONUP 5--右键放开
#define CV_EVENT_MBUTTONUP 6--中键放开
#define CV_EVENT_LBUTTONDBLCLK 7--左键双击
#define CV_EVENT_RBUTTONDBLCLK 8--右键双击
#define CV_EVENT_MBUTTONDBLCLK 9--中键双击
- flags
#define CV_EVENT_FLAG_LBUTTON 1--左键拖曳
#define CV_EVENT_FLAG_RBUTTON 2--右键拖曳
#define CV_EVENT_FLAG_MBUTTON 4-中键拖曳
#define CV_EVENT_FLAG_CTRLKEY 8~15--按Ctrl键不放事件
#define CV_EVENT_FLAG_SHIFTKEY 16~31--按Shift键不放事件
#define CV_EVENT_FLAG_ALTKEY 32~39--按Alt键不放事件
(1)图片信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | //鼠标点击事件 #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <stdio.h> //全局变量 cv::Mat srcImage; void MouseEvent( int event, int x, int y, int flags, void * data) { char charText[30]; cv::Mat tempImage, hsvImage; tempImage = srcImage.clone(); // // 左键按下移动显示RGB信息 // if (event == CV_EVENT_LBUTTONDOWN) { cv::Vec3b p = tempImage.at<cv::Vec3b>(y,x); sprintf (charText, "R = %d, G = %d, B = %d" , p[2], p[1], p[0]); // 写RGB信息文本到图像 cv::putText(tempImage, charText, cv::Point(8,20), cv::FONT_HERSHEY_COMPLEX, 2, CV_RGB(0,0,255)); imwrite( "c.jpg" ,tempImage); } // // 右键按下移动显示HSV信息 // else if (event == CV_EVENT_RBUTTONDOWN) { // 转换成HSV图像 cv::cvtColor(tempImage, hsvImage, CV_BGR2HSV); cv::Vec3b p = hsvImage.at<cv::Vec3b>(y,x); // 获取相应的通道值 sprintf (charText, "H = %d, S = %d, V = %d" , p[0], p[1], p[2]); // 写HSV文本信息到图像 cv::putText(tempImage, charText, cv::Point(8,20), cv::FONT_HERSHEY_PLAIN, 2, CV_RGB(0,255,0)); imwrite( "d.jpg" ,tempImage); } // // 没有按下键显示对应坐标 // else { // 移动鼠标显示坐标 sprintf (charText, "x = %d, y = %d" , x, y); // 写X Y坐标文本信息到图像 cv::putText(tempImage, charText, cv::Point(8,20), cv::FONT_HERSHEY_PLAIN, 2, CV_RGB(255,0,0)); imwrite( "e.jpg" ,tempImage); } } int main( int argc, char ** argv) { // 读取图像及判断是否正确读入 srcImage = cv::imread( "a.jpg" ); if (srcImage.empty()) return -1; // 回调事件响应 cv::namedWindow( "srcImage" ); cv::setMouseCallback( "srcImage" , MouseEvent, 0); cv::imshow( "srcImage" , srcImage); cv::waitKey(0); return 0; } |
- (2)滑动条
OpenCV提供滑动条函数createTrackbar(),当拖动滑块移动鼠标时触发滑动事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | // 滑动条二值化 #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> //createTrackbar的回调响应函数 void onChangeTrackBar( int pos, void * data) { // 强制类型转换 cv::Mat srcImage = *(cv::Mat*)(data); cv::Mat dstImage; // 根据滑动条的值进行二值化 cv::threshold(srcImage, dstImage, pos, 255, 0); cv::imshow( "dyn_threshold" , dstImage); } int main() { // 源图像载入及判断 cv::Mat srcImage = cv::imread( "a.jpg" ); if (!srcImage.data) return -1; //转换为灰度图像 cv::Mat srcGray; cv::cvtColor(srcImage, srcGray, CV_RGB2GRAY); cv::namedWindow( "dyn_threshold" ); cv::imshow( "dyn_threshold" , srcGray); //创建滑动条createTrackbar,调用回调函数 createTrackbar( "pos" , "dyn_threshold" , 0, 255, onChangeTrackBar, &srcGray); cv::waitKey(0); return 0; } |
- (3)固定区域提取
从整个图像中提取出兴趣区域ROI,通过Rect设置相应的感兴趣矩形区域,再用copyTo进行图像赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> // 全局变量源图像 cv::Mat srcImage; // 方法1:利用Rect选择区域(100, 180, 150, 50) void regionExtraction( int xRoi, int yRoi, int widthRoi, int heightRoi) { // 提取指定坐标区域 cv::Mat roiImage(srcImage.rows, srcImage.cols, CV_8UC3); std::cout << srcImage.rows << " " << srcImage.cols << std::endl; // 将兴趣区域复制到目标图像 srcImage(cv::Rect(xRoi, yRoi, widthRoi, heightRoi)).copyTo(roiImage); cv::imshow( "roiImage" , roiImage); cv::waitKey(0); } int main() { // 源图像载入及判断 srcImage = cv::imread( "a.jpg" ); if (!srcImage.data) return -1; cv::imshow( "ROIing" , srcImage); // 方法1:利用Rect选择区域(100,180,150,50) int xRoi = 100; int yRoi = 180; int widthRoi = 150; int heightRoi = 50; regionExtraction(xRoi, yRoi, widthRoi, heightRoi); cv::waitKey(0); return 0; } |
(4)鼠标提取区域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <stdio.h> using namespace cv; using namespace std; //全局变量 cv::Mat srcImage; //所选矩形区域 cv::Rect roiRect; //起始点 cv::Point startPoint; //终止点 cv::Point endPoint; //完成所选区域标志位 bool downFlag = false ; bool upFlag = false ; void MouseEvent( int event, int x, int y, int flags, void * data) { // 鼠标左键按下 获取起始点 if (event == EVENT_LBUTTONDOWN) { downFlag = true ; startPoint.x = x; startPoint.y = y; } // 鼠标拖到松开 获取终止点 if (event == EVENT_LBUTTONUP) { upFlag = true ; endPoint.x = x; endPoint.y = y; } // 显示拖到图像区域 if (downFlag == true && upFlag == false ) { Point tempPoint; tempPoint.x = x; tempPoint.y = y; // 用于显示图像生成 cv::Mat tempImage = srcImage.clone(); cv::rectangle(tempImage, startPoint, tempPoint, Scalar(255,0,0), 2, 3, 0); cv::imshow( "ROIing" , tempImage); } // 选择区域生成 if (downFlag == true && upFlag == true ) { // 获取选择区域的ROI roiRect.width = abs (startPoint.x - endPoint.x); roiRect.height = abs (startPoint.y - endPoint.y); roiRect.x = min(startPoint.x, endPoint.x); roiRect.y = min(startPoint.y, endPoint.y); cv::Mat roiMat(srcImage, roiRect); imshow( "ROI" , roiMat); downFlag = false ; upFlag = false ; } cv::waitKey(0); } int main( int argc, char ** argv) { // 读取图像及判断是否正确读入 srcImage = cv::imread( "a.jpg" ); if (srcImage.empty()) return -1; // 回调事件响应 cv::namedWindow( "ROIing" ); cv::imshow( "ROIing" , srcImage); cv::setMouseCallback( "ROIing" , MouseEvent, 0); cv::waitKey(0); return 0; } |
三.键盘事件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)