zoukankan      html  css  js  c++  java
  • 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)图片信息

    //鼠标点击事件
     
    #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(),当拖动滑块移动鼠标时触发滑动事件

    // 滑动条二值化
     
    #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进行图像赋值

    #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)鼠标提取区域

    #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;
    }
    

    三.键盘事件

  • 相关阅读:
    队列的链式存储结构实现
    堆栈的链式存储实现
    使用C#改变windows系统本地时间
    oracle 多数值录入校验(分隔符“/”)
    oracle中in和exists的区别
    redis安装 windows版(图形化安装)
    Oracle 返回结果集
    饿了么4年 + 阿里2年:研发路上的一些总结与思考
    Oracle 获取各类时间
    Oracle表中已有数据,修改字段长度
  • 原文地址:https://www.cnblogs.com/k5bg/p/11083333.html
Copyright © 2011-2022 走看看