自学内容网 自学内容网

OpenCV绘制ROI区域(五)

鼠标绘制矩形

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _01_绘制矩形
{
    internal class Program
    {
        //宏  常量
        public static string WINDOW_NAME = "程序窗口";
        //Scalar.All(0)  矩阵  像素点 多个通道  Scalar.All(0)设置每个通道都为空
        public static Mat scrImage = new Mat(600, 800, MatType.CV_8UC3,Scalar.All(0));
        public static Rect g_rectange;//矩形类
        public static bool g_bDrawingBox=false;//是否开始绘制
        public static Random g_rng = new Random();//随机颜色
        
        static void Main(string[] args)
        {
            //1.准备参数
            g_rectange = new Rect(-1,-1,0,0);
            Mat tempImage = new Mat();
            //2.设置鼠标操作的事件
            Cv2.NamedWindow(WINDOW_NAME);
            //委托
            MouseCallback GetRBMouseCallback = new MouseCallback(on_MonuseHandle);

            //绑定事件
            Cv2.SetMouseCallback(WINDOW_NAME, GetRBMouseCallback);

            //3.监听    
            while (true)
            {
                scrImage.CopyTo(tempImage);// 拷贝原图到临时变量
                if (g_bDrawingBox)
                {
                    DrawRectangle(ref tempImage, g_rectange);
                }
                Cv2.ImShow(WINDOW_NAME, tempImage);
                if (Cv2.WaitKey(10)==27)//按下了ESC  程序推出
                {
                    break;
                }
            }
         
        }

        //委托类型的事件处理函数
        //参数1:事件对象  里面包含当前事件的一系列参数  如:鼠标按下的位置  移动的位置 事件的类型 .......


        // x ,y 鼠标的 坐标
        public static void on_MonuseHandle(MouseEventTypes @event,int x,int y,MouseEventFlags flages,IntPtr userdate)
        {

            //鼠标移动
            //MouseEventTypes  委托类型   
            //MouseEventTypes.MouseMove  移动
            //MouseEventTypes.LButtonDown 鼠标左键按下
            //MouseEventTypes.LButtonUp 鼠标左键抬起
            if (@event== MouseEventTypes.MouseMove)
            {

                if (g_bDrawingBox)//判断鼠标是否按下  鼠标按下才能开始绘制
                {
                    // 把鼠标的坐标记录到 Rect 变量中
                    g_rectange.Width= x - g_rectange.X;
                    g_rectange.Height = y - g_rectange.Y;
                }

            }


            //鼠标左键按下
            if (@event == MouseEventTypes.LButtonDown)
            {
                g_bDrawingBox=true;
                g_rectange=new Rect(x,y,0,0);//记录起始点
            }

            //鼠标左键抬起
            if (@event == MouseEventTypes.LButtonUp)
            {
                g_bDrawingBox=false;

                //对宽高小于0的处理

                if (g_rectange.Width<0)
                {
                    g_rectange.X += g_rectange.Width;
                    g_rectange.Width*=-1;
                      
                }

                if (g_rectange.Height < 0)
                {
                    g_rectange.Y += g_rectange.Height;
                    g_rectange.Height *= -1;
                }

                //绘制图形

                DrawRectangle(ref scrImage, g_rectange);

            }

        }

        public static void DrawRectangle(ref Mat img,Rect box)
        {
            if ((box.BottomRight.X > box.TopLeft.X) && (box.BottomRight.Y > box.TopLeft.Y))
            {
                Cv2.Rectangle(img, box.TopLeft, box.BottomRight, new Scalar(g_rng.Next(255), g_rng.Next(255), g_rng.Next(255)), 2);//随机颜色
            }
                
        }
    }
}

脚本绘制

using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _02_脚本绘制
{
    internal class Program
    {

        public static string WINDOW_NAME1 = "【绘制图1】";// 为窗口标题定义的宏 
        public static string WINDOW_NAME2 = "【绘制图2】";// 为窗口标题定义的宏 
        public static int WINDOW_WIDTH = 600;             // 定义窗口大小的宏

        static void Main(string[] args)
        {
            // 创建空白的Mat图像
            Mat atomImage = new Mat(WINDOW_WIDTH, WINDOW_WIDTH, MatType.CV_8UC3);
            Mat rookImage = new Mat(WINDOW_WIDTH, WINDOW_WIDTH, MatType.CV_8UC3);

            // --------------<1>绘制化学中的原子示例图--------------
            // 先绘制出椭圆
            DrawEllipse(atomImage, 90);
            DrawEllipse(atomImage, 0);
            DrawEllipse(atomImage, 45);
            DrawEllipse(atomImage, -45);

            // 再绘制圆心
            DrawFilledCircle(atomImage, new Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2));

            // --------------<2>绘制组合图--------------
            //先绘制出椭圆
            DrawPolygon(rookImage);

            // 绘制矩形
            Cv2.Rectangle(rookImage,
                new Point(0, 7 * WINDOW_WIDTH / 8),
                new Point(WINDOW_WIDTH, WINDOW_WIDTH),
                new Scalar(0, 255, 255), -1, LineTypes.Link8);

            // 绘制一些线段
            DrawLine(rookImage, new Point(0, 15 * WINDOW_WIDTH / 16), new Point(WINDOW_WIDTH, 15 * WINDOW_WIDTH / 16));
            DrawLine(rookImage, new Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8), new Point(WINDOW_WIDTH / 4, WINDOW_WIDTH));
            DrawLine(rookImage, new Point(WINDOW_WIDTH / 2, 7 * WINDOW_WIDTH / 8), new Point(WINDOW_WIDTH / 2, WINDOW_WIDTH));
            DrawLine(rookImage, new Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8), new Point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH));

            // 显示绘制出的图像
            Cv2.ImShow(WINDOW_NAME1, atomImage);
            Cv2.MoveWindow(WINDOW_NAME1, 0, 200);
            Cv2.ImShow(WINDOW_NAME2, rookImage);
            Cv2.MoveWindow(WINDOW_NAME2, WINDOW_WIDTH, 200);
            Cv2.WaitKey(0);
        }


        // 自定义的绘制函数,实现了绘制不同角度、相同尺寸的椭圆
        public static void DrawEllipse(Mat img, double angle)
        {
            Cv2.Ellipse(img,
                new Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2),
                new Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16),
                angle, 0, 360, new Scalar(255, 129, 0), 2, LineTypes.Link8);
        }

        // 自定义的绘制函数,实现了实心圆的绘制
        public static void DrawFilledCircle(Mat img, Point center)
        {
            Cv2.Circle(img, center.X, center.Y, WINDOW_WIDTH / 32, new Scalar(0, 0, 255), -1, LineTypes.Link8);
        }

        // 自定义的绘制函数,实现了凹多边形的绘制
        public static void DrawPolygon(Mat img)
        {
            //创建一些点
            List<List<Point>> pts = new List<List<Point>>()
            {
                new List<Point>
                {
                     new Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8),
                     new Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8),
                     new Point(3 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16),
                     new Point(11 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16),
                     new Point(19 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8),
                     new Point(3 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8),
                     new Point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8),
                     new Point(26 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8),
                     new Point(26 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4),
                     new Point(22 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4),
                     new Point(22 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8),
                     new Point(18 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8),
                     new Point(18 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4),
                     new Point(14 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4),
                     new Point(14 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8),
                     new Point(WINDOW_WIDTH / 4, WINDOW_WIDTH / 8),
                     new Point(WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8),
                     new Point(13 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8),
                     new Point(5 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16),
                     new Point(WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16)
                }
            };

            // 绘制多边形填充
            Cv2.FillPoly(img, pts, new Scalar(255, 255, 255), LineTypes.Link8);
        }

        // 自定义的绘制函数,实现了线的绘制
        public static void DrawLine(Mat img, Point start, Point end)
        {
            Cv2.Line(img, start.X, start.Y, end.X, end.Y, new Scalar(0, 0, 0), 2, LineTypes.Link8);
        }
    }
}


原文地址:https://blog.csdn.net/weixin_45788237/article/details/142381286

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!