文中内容大多来自大神浅墨_毛星云 所著【OpenCV3编程入门】,在此基础上加入了自己的理解和补充内容。
#include <opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "程序窗口"
//全局函数声明
void on_MouseHandle(int event, int x, int y, int flags, void *param);
void drawRectangle(Mat &img, Rect box);
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345);//随机数 参数为随机种子
int main(int argc, char **argv) {
//准备参数
g_rectangle = Rect(-1, -1, 0, 0);
Mat srcImage(600, 800,CV_8UC3);
Mat tempImage;
srcImage.copyTo(tempImage);
// g_rectangle = Rect(-1, -1, 0, 0);
srcImage = Scalar::all(0);
//设置鼠标回调函数
namedWindow(WINDOW_NAME);
//为指定的窗口设置鼠标回调函数
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void *) &srcImage);
//程序主循环 ,当进行绘制的标识符为true时,进行绘制
while (1) {
srcImage.copyTo(tempImage);
if (g_bDrawingBox) {
drawRectangle(tempImage, g_rectangle);
}
imshow(WINDOW_NAME, tempImage);
//esc退出 esc 的ASCII码为27
if (waitKey(10) == 27) {
break;
}
}
return 0;
}
/**
* 鼠标回调函数,根据不同的鼠标事件进行不同的操作
@param事件是cv :: MouseEventTypes常量之一。
@param x鼠标事件的x坐标。
@param y鼠标事件的y坐标。
@param标记cv :: MouseEventFlags常量之一。
@param userdata可选参数。
*/
void on_MouseHandle(int event, int x, int y, int flags, void *param) {
Mat &image = *(Mat *) param;
switch (event) {
case EVENT_MOUSEMOVE://鼠标移动
if (g_bDrawingBox) {
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
break;
case EVENT_LBUTTONDOWN: {//鼠标左键按下
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);//记录起始点
}
break;
case EVENT_LBUTTONUP: {//鼠标释放
g_bDrawingBox = false;
//对宽高小于0的处理
//起点往上往左画 分别对应着height<0 width<0
if (g_rectangle.width < 0) {
std::cout<<"width < 0"<<std::endl;
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
}
if (g_rectangle.height < 0) {
std::cout<<"height < 0"<<std::endl;
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
drawRectangle(image, g_rectangle);
}
break;
}
}
/**
* 绘制矩形
* @param img 图像
* @param box 矩形框 随机颜色
*/
void drawRectangle(Mat &img, Rect box) {
// img 图像. pt1 矩形的一个顶点。 pt2 矩形对角线上的另一个顶点 color 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。 thickness 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。 line_type 线条的类型。见cvLine的描述 shift 坐标点的小数点位数。
rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(
0, 255
),g_rng
.uniform(0,255),g_rng.uniform(0,255)),1,4,0);
}
运行后鼠标绘图截图:

补充:
Mat srcImage(600, 800,CV_8UC3); 中的CV_8UC3的含义:
这里的type可以是任何的预定义类型,预定义类型的结构如下所示:
CV_<bit_depth>(S|U|F)C<number_of_channels>
- bit_depth---比特数---代表8bite,16bites,32bites,64bites---举个例子吧--比如说,如
如果你现在创建了一个存储--灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张
灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位--所以它对
应的就是CV_8- S|U|F--S--代表---signed int---有符号整形
U--代表--unsigned int--无符号整形
F--代表--float---------单精度浮点型- C<number_of_channels>----代表---一张图片的通道数,比如:
灰度图片--grayImg---是--单通道图像
RGB彩色图像---------是--3通道图像
带Alph通道的RGB图像--是--4通道图像
所以这里的意思是创建一个高600,宽800的8位无符号3通道的RGB彩色图像容器
网友评论