当前位置: 首页 > article >正文

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


http://www.kler.cn/a/312326.html

相关文章:

  • 阿里巴巴通义灵码推出Lingma SWE-GPT:开源模型的性能新标杆
  • 鸿蒙自定义UI组件导出使用
  • Matlab: 生成对抗网络,使用Datastore结构输入mat格式数据
  • 数据结构-集合
  • 知识库管理系统:企业数字化转型的加速器
  • Java 网络编程(一)—— UDP数据报套接字编程
  • constexpr与const的区别
  • 【正负交替的分数求和】
  • Linux环境基础开发工具---vim
  • 4×4矩阵键盘详解(STM32)
  • 什么是 WebApiEngine?
  • C#中单例模式CSingleton
  • 前端如何快速调试线上问题
  • react的组件的概念和使用
  • 家庭聚餐:用白酒传递亲情与温暖
  • 滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
  • 浅谈vue2.0与vue3.0的区别(整理十六点)
  • npm run build报Cannot find module错误的解决方法
  • 誉龙视音频 Third/TimeSyn 远程命令执行复现
  • weblogic CVE-2020-14882 靶场攻略
  • 【百日算法计划】:每日一题,见证成长(018)
  • pytorch使用技巧
  • Designify——AI优化图像设计,自动去背景、调整构图、添加视觉效果,创建高质量的设计图像
  • 2024 Oracle CloudWorld的信息量实在太大了
  • Pikachu靶场之XSS
  • Leetcode面试经典150题-97.交错字符串