<h1 style="font-size: 32px; font-weight: bold; border-bottom: 2px solid rgb(204, 204, 204); padding: 0px 4px 0px 0px; text-align: left; margin: 0px 0px 10px;">把鼠标当画笔</h1><p style="white-space: normal;">本章节内容是博主网上收集的,主要内容包括OpenCv的一些基本绘图函数的操作。</p><p style="margin-top: 0px; margin-bottom: 10px; white-space: normal; padding: 0px; list-style: none; border: 0px; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); box-sizing: border-box;">当前系列所有demo下载地址:</p><p style="margin-top: 0px; margin-bottom: 10px; white-space: normal; padding: 0px; list-style: none; border: 0px; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); box-sizing: border-box;"><a href="https://github.com/GaoRenBao/OpenCv4-Demo" target="_blank" style="margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(0, 102, 0); transition-duration: 0.2s; transition-property: opacity; outline: none; opacity: 0.8;">https://github.com/GaoRenBao/OpenCv4-Demo</a></p><p style="margin-top: 0px; margin-bottom: 10px; text-wrap: wrap; padding: 0px; list-style: none; border: 0px; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; box-sizing: border-box; color: rgb(51, 51, 51);">不同编程语言对应的OpenCv版本以及<span style="">开发环境</span>信息如下:<span style="font-family: Calibri; font-size: 14px;"> </span></p><table border="1" style="text-wrap: wrap; border-right: none; border-bottom: none; border-image: initial; border-left: 1px solid rgb(102, 102, 102); border-top: 1px solid rgb(102, 102, 102);"><tbody><tr class="firstRow"><td width="81" valign="top" style="border-color: windowtext rgb(102, 102, 102) rgb(102, 102, 102) windowtext; border-bottom-width: 1px; border-bottom-style: solid; border-right-width: 1px; border-right-style: solid; padding: 5px;"><p style="text-align: center;"><strong><span style="font-family: 宋体; font-size: 14px;">语言</span></strong></p></td><td width="223" valign="top" style="border-color: windowtext rgb(102, 102, 102) rgb(102, 102, 102) windowtext; border-bottom-width: 1px; border-bottom-style: solid; border-right-width: 1px; border-right-style: solid; padding: 5px;"><p style="text-align: center;"><strong><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">OpenCv</span>版本</span></strong></p></td><td width="242" valign="top" style="border-color: windowtext rgb(102, 102, 102) rgb(102, 102, 102) windowtext; border-bottom-width: 1px; border-bottom-style: solid; border-right-width: 1px; border-right-style: solid; padding: 5px;"><p style="text-align: center;"><strong><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">IDE</span></span></strong></p></td></tr><tr><td width="81" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">C#</span></span></p></td><td width="223" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: Calibri; letter-spacing: 0px;">OpenCvSharp4.4.8.0.20230708</span></p></td><td width="242" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">Visual Studio 2022</span></span></p></td></tr><tr><td width="81" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">C++</span></span></p></td><td width="223" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; letter-spacing: 0px;"><span style="font-family: Calibri;">O</span></span><span style="font-family: Calibri; letter-spacing: 0px;">pen</span><span style="font-family: 宋体; letter-spacing: 0px;"><span style="font-family: Calibri;">C</span></span><span style="font-family: Calibri; letter-spacing: 0px;">v-4.5.5-vc14_vc15</span></p></td><td width="242" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">Visual Studio 2022</span></span></p></td></tr><tr><td width="81" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">Python</span></span></p></td><td width="223" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">OpenCv-Python (4.6.0.66)</span></span></p></td><td width="242" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">PyCharm Community Edition 2022.1.3</span></span></p></td></tr></tbody></table><p><span style="text-wrap: wrap;"></span></p><p style="margin-top: 0px; margin-bottom: 10px; white-space: normal; box-sizing: border-box; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); "><a target="_blank" href="https://pan.baidu.com/s/1T9xl4KOBvU1g7AyDfPWlpw" style="box-sizing: border-box; color: rgb(0, 102, 0); transition-duration: 0.2s; transition-property: opacity; background-color: transparent; outline: none;"></a></p><p style="white-space: normal;"><br/></p><p style="white-space: normal;">当前章节主要是演示opencv的回调函数的使用方法。以下提供了几个简单的使用demo。</p><p>本章节一共三个demo:</p><p>demo1:通过按键‘m’切换绘制圆和矩形</p><p><img src="/upload/image/6380705718415762634442851.gif" title="1.gif" alt="1.gif"/></p><p><br/></p><p>demo2:通过双击绘制圆</p><p><img src="/upload/image/6380705706403016495700706.gif" title="1.gif" alt="1.gif"/></p><p><br/></p><p>demo3:通过鼠标的左键和右键输出坐标</p><p><img src="/upload/image/6380705755675161711191640.gif" title="1 (1).gif" alt="1 (1).gif"/></p><p style="white-space: normal;"><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><br/></strong></p><p style="white-space: normal;"><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><span style="font-size: 16px; font-style: italic; font-weight: bold; color: rgb(51, 153, 204); line-height: 18px;">C#版本运行代码如下:</span></strong></p><p>演示demo1:</p><p> 通过按键‘m’切换绘制圆和矩形,运行效果,可参考python版本。</p><pre class="brush:c#;toolbar:false">using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
public static Mat img = new Mat();
// 当鼠标按下时变为 True
public static bool drawing = false;
// 矩形和圆形模式切换
public static bool mode = false;
// 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
public static int ix = -1, iy = -1;
public static void onMouse(MouseEventTypes @event, int x, int y, MouseEventFlags flags, IntPtr userData)
{
// 当按下左键是返回起始位置坐标
if (@event == MouseEventTypes.LButtonDown)
{
drawing = true;
ix = x;
iy = y;
}
// 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
if (@event == MouseEventTypes.MouseMove)
{
if(drawing)
{
if(mode)
{
Cv2.Rectangle(img, new Point(ix, iy), new Point(x, y), new Scalar(0, 255, 0), -1);
}
else
{
// 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
Cv2.Circle(img, new Point(x, y), 3, new Scalar(0, 0, 255), -1);
//下面注释掉的代码是起始点为圆心,起点到终点为半径的
//int r = (int)(Math.Sqrt((x - ix) * (x - ix) + (y - iy) * (y - iy)));
//Cv2.Circle(img, new Point(x, y), r, new Scalar(0, 0, 255), -1);
}
}
}
// 当鼠标松开停止绘画。
if (@event == MouseEventTypes.LButtonUp)
{
drawing = false;
//if (mode)
//{
// Cv2.Rectangle(img, new Point(ix, iy), new Point(x, y), new Scalar(0, 255, 0), -1);
//}
//else
//{
// Cv2.Circle(img, new Point(x, y), 5, new Scalar(0, 0, 255), -1);
//}
}
}
public static void Main(string[] args)
{
img = new Mat(new Size(512, 512), MatType.CV_8UC3);
mode = false;
Cv2.NamedWindow("image");
Cv2.SetMouseCallback("image", new MouseCallback(onMouse));
while(true)
{
Cv2.ImShow("image", img);
if (Cv2.WaitKey(1) == 'm')
{
mode = !mode;
}
}
}
}
}</pre><p>演示demo2:</p><p> 通过双击绘制圆,运行效果,可参考python版本。</p><pre class="brush:c#;toolbar:false">using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
public static Mat img = new Mat();
// 只用做一件事:在双击过的地方绘制一个圆圈。
public static void onMouse(MouseEventTypes @event, int x, int y, MouseEventFlags flags, IntPtr userData)
{
if (@event == MouseEventTypes.LButtonDoubleClick)
{
Cv2.Circle(img, new Point(x, y), 100, new Scalar(255, 0, 0), -1);
}
}
public static void Main(string[] args)
{
img = new Mat(new Size(512, 512), MatType.CV_8UC3);
Cv2.NamedWindow("image");
Cv2.SetMouseCallback("image", new MouseCallback(onMouse));
while(true)
{
Cv2.ImShow("image", img);
Cv2.WaitKey(1);
}
}
}
}</pre><p>演示demo3:</p><p> 通过鼠标的左键和右键输出坐标,运行效果,可参考python版本。</p><pre class="brush:c#;toolbar:false">using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
public static Mat img = new Mat();
// 鼠标左右键回调函数
public static void onMouse(MouseEventTypes @event, int x, int y, MouseEventFlags flags, IntPtr userData)
{
if (@event == MouseEventTypes.LButtonDown)
{
Console.WriteLine($"{x},{y}");
}
if (@event == MouseEventTypes.RButtonDown)
{
Vec3b vec = img.Get<Vec3b>(y, x);
byte blue = vec.Item0;
byte green = vec.Item1;
byte red = vec.Item2;
Console.WriteLine($"{red},{green},{blue}");
string strRGB = $"{red},{green},{blue}";
var font = HersheyFonts.HersheySimplex;
Cv2.PutText(img, strRGB, new Point(x, y), font, 1, new Scalar(255, 255, 255), 2);
Cv2.ImShow("original", img);
}
}
public static void Main(string[] args)
{
img = Cv2.ImRead("messi5.jpg");
Cv2.ImShow("original", img);
Cv2.NamedWindow("original");
Cv2.SetMouseCallback("original", new MouseCallback(onMouse));
Cv2.WaitKey(0);
Console.Read();
}
}
}</pre><p><br/></p><p><strong style="white-space: normal; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"><span style="font-size: 16px; font-style: italic; font-weight: bold; color: rgb(51, 153, 204); line-height: 18px;">C++<strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;">版本运行代码如下:</strong></span><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"></strong></strong></strong></p><pre class="brush:cpp;toolbar:false">#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#define DEMOID 0
#if DEMOID == 0
// 当鼠标按下时变为 True
bool drawing = false;
// 矩形和圆形模式切换
bool mode = false;
// 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
int ix = -1, iy = -1;
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*)param;
switch (event)
{
// 当按下左键是返回起始位置坐标
case EVENT_LBUTTONDOWN:
{
drawing = true;
ix = x;
iy = y;
}
break;
// 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
case EVENT_MOUSEMOVE:
{
if (drawing)
{
if (mode)
{
rectangle(image, Point(ix, iy), Point(x, y), Scalar(0, 255, 0), -1);
}
else
{
// 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
circle(image, Point(x, y), 3, Scalar(0, 0, 255), -1);
//下面注释掉的代码是起始点为圆心,起点到终点为半径的
//int r = (int)(sqrt((x - ix) * (x - ix) + (y - iy) * (y - iy)));
//circle(image, Point(x, y), r, Scalar(0, 0, 255), -1);
}
}
}
break;
// 当鼠标松开停止绘画。
case EVENT_LBUTTONUP:
{
drawing = false;
/*if (mode)
{
rectangle(image, Point(ix, iy), Point(x, y), Scalar(0, 255, 0), -1);
}
else
{
circle(image, Point(x, y), 5, Scalar(0, 0, 255), -1);
}*/
}
break;
}
}
int main()
{
Mat img = Mat(512, 512, CV_8UC3);
img = Scalar::all(0);
mode = false;
namedWindow("image");
setMouseCallback("image", on_MouseHandle, (void*)&img);
while (true)
{
imshow("image", img);
if (waitKey(1) == 'm')
{
mode = !mode;
}
}
}
#endif
#if DEMOID == 1
// 只用做一件事:在双击过的地方绘制一个圆圈。
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*)param;
if (event == EVENT_LBUTTONDBLCLK)
{
circle(image, Point(x, y), 100, Scalar(0, 0, 255), -1);
}
}
void main()
{
Mat img = Mat(512, 512, CV_8UC3);
img = Scalar::all(0);
namedWindow("image");
setMouseCallback("image", on_MouseHandle, (void*)&img);
while (true)
{
imshow("image", img);
waitKey(1);
}
}
#endif
#if DEMOID == 2
// 当鼠标按下时变为 True
bool drawing = false;
// 矩形和圆形模式切换
bool mode = false;
// 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
int ix = -1, iy = -1;
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*)param;
if (event == EVENT_LBUTTONDOWN)
{
cout << to_string(x) << "," << to_string(y) << endl;
}
if (event == EVENT_RBUTTONDOWN)
{
Vec3b vec = image.at<Vec3b>(y, x);
uchar blue = vec[0];
uchar green = vec[1];
uchar red = vec[2];
string strRGB = to_string(red) + "," + to_string(green) + "," + to_string(blue);
cout << strRGB << endl;
putText(image, strRGB, Point(x, y), FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 255, 255), 2, LINE_AA);
imshow("original", image);
}
}
void main()
{
Mat img = imread("../images/messi5.jpg");
imshow("original", img);
namedWindow("original");
setMouseCallback("original", on_MouseHandle, (void*)&img);
waitKey(0);
}
#endif</pre><p><br/></p><p><strong style="white-space: normal; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"><span style="font-size: 16px; font-style: italic; font-weight: bold; color: rgb(51, 153, 204); line-height: 18px;">Python<strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;">版本运行代码如下:</strong></span><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"></strong></strong></strong></p><p style="white-space: normal;">demo1演示代码如下:</p><pre class="brush:python;toolbar:false"># -*- coding: utf-8 -*-
import cv2
import numpy as np
# 当鼠标按下时变为 True
drawing = False
# 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
ix, iy = -1, -1
# 创建回调函数 #回调函数包含两部分 一部分画矩形 一部分画圆圈
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode
# 当按下左键是返回起始位置坐标
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
# 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
if drawing is True:
if mode is True:
cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
# 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
# 下面注释掉的代码是起始点为圆心,起点到终点为半径的
# r = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))
# cv2.circle(img, (x, y), r, (0, 0, 255), -1)
elif event == cv2.EVENT_LBUTTONUP: # 当鼠标松开停止绘画。
drawing = False
# if mode == True:
# cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
# else:
# cv2.circle(img, (x, y), 5, (0, 0, 255), -1)
#
img = np.zeros((512, 512, 3), np.uint8)
mode = False
cv2.namedWindow('image', 0)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
k = cv2.waitKey(1) # & 0xFF
if k == ord('m'):
mode = not mode
elif k == ord("q"):
break</pre><p><br/></p><p><span style="text-wrap: wrap;">demo2演示代码如下:</span></p><pre class="brush:python;toolbar:false"># -*- coding: utf-8 -*-
import cv2
import numpy as np
# mouse callback function
def draw_circle(event, x, y, flags, param): # 只用做一件事:在双击过的地方绘 制一个圆圈。
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.circle(img, (x, y), 100, (255, 0, 0), -1)
# 创建图像与窗口并将窗口与回调函数绑定
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
# if cv2.waitKey(20) & 0xFF == 27:
# break
key = cv2.waitKey(1)
if key == ord("q"):
break
cv2.destroyAllWindows()</pre><p><br/></p><p><span style="text-wrap: wrap;">demo3演示代码如下:</span></p><pre class="brush:python;toolbar:false">import cv2
def click_event(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
print(x, y)
if event == cv2.EVENT_RBUTTONDOWN:
red = img[y, x, 2]
blue = img[y, x, 0]
green = img[y, x, 1]
print(red, green, blue)
strRGB = str(red) + "," + str(green) + "," + str(blue)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, strRGB, (x, y), font, 1, (255, 255, 255), 2)
cv2.imshow('original', img)
img = cv2.imread('../images/messi5.jpg')
cv2.imshow('original', img)
cv2.setMouseCallback("original", click_event)
cv2.waitKey(0)
cv2.imshow('putText.jpg', img)
cv2.destroyAllWindows()</pre><p><br/></p>
把鼠标当画笔 本章节内容是博主网上收集的,主要内容包括OpenCv的一些基本绘图函数的操作。
当前系列所有demo下载地址:
https://github.com/GaoRenBao/OpenCv4-Demo
不同编程语言对应的OpenCv版本以及开发环境 信息如下:
语言
OpenCv 版本
IDE
C#
OpenCvSharp4.4.8.0.20230708
Visual Studio 2022
C++
O pen C v-4.5.5-vc14_vc15
Visual Studio 2022
Python
OpenCv-Python (4.6.0.66)
PyCharm Community Edition 2022.1.3
当前章节主要是演示opencv的回调函数的使用方法。以下提供了几个简单的使用demo。
本章节一共三个demo:
demo1:通过按键‘m’切换绘制圆和矩形
demo2:通过双击绘制圆
demo3:通过鼠标的左键和右键输出坐标
C#版本运行代码如下:
演示demo1:
通过按键‘m’切换绘制圆和矩形,运行效果,可参考python版本。
using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
public static Mat img = new Mat();
// 当鼠标按下时变为 True
public static bool drawing = false;
// 矩形和圆形模式切换
public static bool mode = false;
// 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
public static int ix = -1, iy = -1;
public static void onMouse(MouseEventTypes @event, int x, int y, MouseEventFlags flags, IntPtr userData)
{
// 当按下左键是返回起始位置坐标
if (@event == MouseEventTypes.LButtonDown)
{
drawing = true;
ix = x;
iy = y;
}
// 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
if (@event == MouseEventTypes.MouseMove)
{
if(drawing)
{
if(mode)
{
Cv2.Rectangle(img, new Point(ix, iy), new Point(x, y), new Scalar(0, 255, 0), -1);
}
else
{
// 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
Cv2.Circle(img, new Point(x, y), 3, new Scalar(0, 0, 255), -1);
//下面注释掉的代码是起始点为圆心,起点到终点为半径的
//int r = (int)(Math.Sqrt((x - ix) * (x - ix) + (y - iy) * (y - iy)));
//Cv2.Circle(img, new Point(x, y), r, new Scalar(0, 0, 255), -1);
}
}
}
// 当鼠标松开停止绘画。
if (@event == MouseEventTypes.LButtonUp)
{
drawing = false;
//if (mode)
//{
// Cv2.Rectangle(img, new Point(ix, iy), new Point(x, y), new Scalar(0, 255, 0), -1);
//}
//else
//{
// Cv2.Circle(img, new Point(x, y), 5, new Scalar(0, 0, 255), -1);
//}
}
}
public static void Main(string[] args)
{
img = new Mat(new Size(512, 512), MatType.CV_8UC3);
mode = false;
Cv2.NamedWindow("image");
Cv2.SetMouseCallback("image", new MouseCallback(onMouse));
while(true)
{
Cv2.ImShow("image", img);
if (Cv2.WaitKey(1) == 'm')
{
mode = !mode;
}
}
}
}
} 演示demo2:
通过双击绘制圆,运行效果,可参考python版本。
using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
public static Mat img = new Mat();
// 只用做一件事:在双击过的地方绘制一个圆圈。
public static void onMouse(MouseEventTypes @event, int x, int y, MouseEventFlags flags, IntPtr userData)
{
if (@event == MouseEventTypes.LButtonDoubleClick)
{
Cv2.Circle(img, new Point(x, y), 100, new Scalar(255, 0, 0), -1);
}
}
public static void Main(string[] args)
{
img = new Mat(new Size(512, 512), MatType.CV_8UC3);
Cv2.NamedWindow("image");
Cv2.SetMouseCallback("image", new MouseCallback(onMouse));
while(true)
{
Cv2.ImShow("image", img);
Cv2.WaitKey(1);
}
}
}
} 演示demo3:
通过鼠标的左键和右键输出坐标,运行效果,可参考python版本。
using OpenCvSharp;
using System;
namespace ConsoleApp
{
internal class Program
{
public static Mat img = new Mat();
// 鼠标左右键回调函数
public static void onMouse(MouseEventTypes @event, int x, int y, MouseEventFlags flags, IntPtr userData)
{
if (@event == MouseEventTypes.LButtonDown)
{
Console.WriteLine($"{x},{y}");
}
if (@event == MouseEventTypes.RButtonDown)
{
Vec3b vec = img.Get<Vec3b>(y, x);
byte blue = vec.Item0;
byte green = vec.Item1;
byte red = vec.Item2;
Console.WriteLine($"{red},{green},{blue}");
string strRGB = $"{red},{green},{blue}";
var font = HersheyFonts.HersheySimplex;
Cv2.PutText(img, strRGB, new Point(x, y), font, 1, new Scalar(255, 255, 255), 2);
Cv2.ImShow("original", img);
}
}
public static void Main(string[] args)
{
img = Cv2.ImRead("messi5.jpg");
Cv2.ImShow("original", img);
Cv2.NamedWindow("original");
Cv2.SetMouseCallback("original", new MouseCallback(onMouse));
Cv2.WaitKey(0);
Console.Read();
}
}
}
C++版本运行代码如下:
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
#define DEMOID 0
#if DEMOID == 0
// 当鼠标按下时变为 True
bool drawing = false;
// 矩形和圆形模式切换
bool mode = false;
// 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
int ix = -1, iy = -1;
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*)param;
switch (event)
{
// 当按下左键是返回起始位置坐标
case EVENT_LBUTTONDOWN:
{
drawing = true;
ix = x;
iy = y;
}
break;
// 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
case EVENT_MOUSEMOVE:
{
if (drawing)
{
if (mode)
{
rectangle(image, Point(ix, iy), Point(x, y), Scalar(0, 255, 0), -1);
}
else
{
// 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
circle(image, Point(x, y), 3, Scalar(0, 0, 255), -1);
//下面注释掉的代码是起始点为圆心,起点到终点为半径的
//int r = (int)(sqrt((x - ix) * (x - ix) + (y - iy) * (y - iy)));
//circle(image, Point(x, y), r, Scalar(0, 0, 255), -1);
}
}
}
break;
// 当鼠标松开停止绘画。
case EVENT_LBUTTONUP:
{
drawing = false;
/*if (mode)
{
rectangle(image, Point(ix, iy), Point(x, y), Scalar(0, 255, 0), -1);
}
else
{
circle(image, Point(x, y), 5, Scalar(0, 0, 255), -1);
}*/
}
break;
}
}
int main()
{
Mat img = Mat(512, 512, CV_8UC3);
img = Scalar::all(0);
mode = false;
namedWindow("image");
setMouseCallback("image", on_MouseHandle, (void*)&img);
while (true)
{
imshow("image", img);
if (waitKey(1) == 'm')
{
mode = !mode;
}
}
}
#endif
#if DEMOID == 1
// 只用做一件事:在双击过的地方绘制一个圆圈。
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*)param;
if (event == EVENT_LBUTTONDBLCLK)
{
circle(image, Point(x, y), 100, Scalar(0, 0, 255), -1);
}
}
void main()
{
Mat img = Mat(512, 512, CV_8UC3);
img = Scalar::all(0);
namedWindow("image");
setMouseCallback("image", on_MouseHandle, (void*)&img);
while (true)
{
imshow("image", img);
waitKey(1);
}
}
#endif
#if DEMOID == 2
// 当鼠标按下时变为 True
bool drawing = false;
// 矩形和圆形模式切换
bool mode = false;
// 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
int ix = -1, iy = -1;
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*)param;
if (event == EVENT_LBUTTONDOWN)
{
cout << to_string(x) << "," << to_string(y) << endl;
}
if (event == EVENT_RBUTTONDOWN)
{
Vec3b vec = image.at<Vec3b>(y, x);
uchar blue = vec[0];
uchar green = vec[1];
uchar red = vec[2];
string strRGB = to_string(red) + "," + to_string(green) + "," + to_string(blue);
cout << strRGB << endl;
putText(image, strRGB, Point(x, y), FONT_HERSHEY_SIMPLEX, 1, Scalar(255, 255, 255), 2, LINE_AA);
imshow("original", image);
}
}
void main()
{
Mat img = imread("../images/messi5.jpg");
imshow("original", img);
namedWindow("original");
setMouseCallback("original", on_MouseHandle, (void*)&img);
waitKey(0);
}
#endif
Python版本运行代码如下:
demo1演示代码如下:
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# 当鼠标按下时变为 True
drawing = False
# 如果 mode 为 true 绘制矩形。按下'm' 变成绘制曲线。 mode=True
ix, iy = -1, -1
# 创建回调函数 #回调函数包含两部分 一部分画矩形 一部分画圆圈
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode
# 当按下左键是返回起始位置坐标
if event == cv2.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
# 当鼠标左键按下并移动是绘制图形。event 可以查看移动,flag 查看是否按下
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
if drawing is True:
if mode is True:
cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
# 绘制圆圈,小圆点连在一起就成了线,3 代表了笔画的粗细
cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
# 下面注释掉的代码是起始点为圆心,起点到终点为半径的
# r = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))
# cv2.circle(img, (x, y), r, (0, 0, 255), -1)
elif event == cv2.EVENT_LBUTTONUP: # 当鼠标松开停止绘画。
drawing = False
# if mode == True:
# cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
# else:
# cv2.circle(img, (x, y), 5, (0, 0, 255), -1)
#
img = np.zeros((512, 512, 3), np.uint8)
mode = False
cv2.namedWindow('image', 0)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
k = cv2.waitKey(1) # & 0xFF
if k == ord('m'):
mode = not mode
elif k == ord("q"):
break
demo2演示代码如下:
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# mouse callback function
def draw_circle(event, x, y, flags, param): # 只用做一件事:在双击过的地方绘 制一个圆圈。
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.circle(img, (x, y), 100, (255, 0, 0), -1)
# 创建图像与窗口并将窗口与回调函数绑定
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.setMouseCallback('image', draw_circle)
while True:
cv2.imshow('image', img)
# if cv2.waitKey(20) & 0xFF == 27:
# break
key = cv2.waitKey(1)
if key == ord("q"):
break
cv2.destroyAllWindows()
demo3演示代码如下:
import cv2
def click_event(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
print(x, y)
if event == cv2.EVENT_RBUTTONDOWN:
red = img[y, x, 2]
blue = img[y, x, 0]
green = img[y, x, 1]
print(red, green, blue)
strRGB = str(red) + "," + str(green) + "," + str(blue)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, strRGB, (x, y), font, 1, (255, 255, 255), 2)
cv2.imshow('original', img)
img = cv2.imread('../images/messi5.jpg')
cv2.imshow('original', img)
cv2.setMouseCallback("original", click_event)
cv2.waitKey(0)
cv2.imshow('putText.jpg', img)
cv2.destroyAllWindows()