19.java openCV4.x 入门-Imgproc之图形绘制

2024-04-16 08:36

本文主要是介绍19.java openCV4.x 入门-Imgproc之图形绘制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

专栏简介

💒个人主页
📖心灵鸡汤📖

我们唯一拥有的就是今天,唯一能把握的也是今天


建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫
📰专栏目录

Imgproc之图像绘制

  • 一、直线绘制
    • 字段
    • 1.带箭直线绘制
    • 2.普通直线绘制
      • 1.line
      • 2.polylines
  • 二、矩形绘制
  • 三、圆绘制
  • 四、椭圆(椭圆弧)绘制
  • 五、多边形填充
    • 1.单个填充
    • 2.多个填充
  • 六、标记绘制
    • 1.字段
    • 2.方法介绍
  • 七、文本绘制
    • 1.字段
    • 2.方法介绍
  • 八、相关扩展方法
    • 1.线段裁定
    • 2.椭圆弧转换为多段线
    • 3.计算字体尺寸比例

本节内容比较简单,但是很重要

一、直线绘制

  线段被图像边界裁剪。对于非抗锯齿的整数坐标线,使用8-连接或4-连接的Bresenham算法。粗线以圆角结束绘制。抗锯齿线使用高斯滤波器绘制。

字段

LINE_4 使用4点线段。这通常用于表示直线,使用起点和终点坐标
LINE_8使用8点线段。这提供了更多的控制点,可以用于更精确地表示曲线或直线
LINE_AA使用抗锯齿线段。抗锯齿技术用于平滑线条的边缘,使其看起来更平滑和自然

1.带箭直线绘制

1.在给定的图像上,从第一个点到第二个点绘制一个箭头线段

arrowedLine(Mat img, Point pt1, Point pt2, Scalar color, int thickness, int line_type, int shift, double tipLength)
参数:
img 要绘制线段的图像
pt1线段的起始点坐标
pt2 线段的终点坐标
color 线段的颜色
thickness 线段的粗细
line_type线段的类型。 参见 #LINE_*
shift坐标点的小数位数
tipLength箭头尖端的长度与箭头长度之间的关系
        //创建一个图像Mat mat = new Mat(400,400, CvType.CV_8UC3);//设置颜色mat.setTo(new Scalar(0,0,0));// 定义线段的起始点和终点坐标Point pt1 = new Point(50, 50);Point pt2 = new Point(350, 350);// 定义线段的颜色Scalar color = new Scalar(0, 0, 255);int lineType=Imgproc.LINE_AA;Imgproc.arrowedLine(mat,pt1,pt2,color,10, lineType, 0, 0.1);HighGui.imshow("mat",mat);HighGui.waitKey();

结果:
请添加图片描述

2.普通直线绘制

1.line

1.图像上绘制直线(线段被图像边界裁剪)

line(Mat img, Point pt1, Point pt2, Scalar color, int thickness, int lineType, int shift)
参数:
img 要绘制线段的图像
pt1线段的起始点坐标
pt2 线段的终点坐标
color 线段的颜色
thickness 线段的粗细
line_type线段的类型。 参见 #LINE_*
shift坐标点的小数位数
        //创建矩阵Mat img = new Mat(200,300, CvType.CV_8UC3,new Scalar(0,0,0) );//定义线段开始结束坐标pt1Point pt1 = new Point(20,20);Point pt2 = new Point(100,100);Point pt3 = new Point(150,100);//定义绘制的颜色Scalar scalar= new Scalar(0,255,0);//定义线条粗细int thickness = 2;//定义线条类型int lineType=Imgproc.LINE_AA;//定义点坐标小数位数int shift=0;Imgproc.line(img,pt1,pt2,scalar,thickness,lineType,shift);Imgproc.line(img,pt2,pt3,scalar,thickness,lineType,shift);//显示HighGui.imshow("img",img);HighGui.waitKey();

结果:

在这里插入图片描述

2.polylines

1.绘制多段线

polylines(Mat img, java.util.List pts, boolean isClosed, Scalar color, int thickness, int lineType, int shift)
参数:
img 要绘制线段的图像
pts包含多段线顶点的 java.util.List 对象。每个 MatOfPoint 对象表示多段线的一个单独部分
isClosed一个布尔值,指示多段线是否闭合。如果为 true,则多段线闭合;如果为 false,则不闭合
color 线段的颜色
thickness 线段的粗细
line_type线段的类型。 参见 #LINE_*
shift坐标点的小数位数
 		Mat mat = new Mat(500,500, CvType.CV_8UC3);mat.setTo(new Scalar(255,255,255));List<MatOfPoint> pts = new ArrayList<>();MatOfPoint point = new MatOfPoint();point.fromArray(new Point(50,50),new Point(150,90),new Point(80,180),new Point(250,250));pts.add(point);Imgproc.polylines(mat,pts,false,new Scalar(0,255,0),2,Imgproc.LINE_AA,0);HighGui.imshow("mat",mat);HighGui.waitKey();

在这里插入图片描述

二、矩形绘制

1.矩形绘制(填充)

rectangle(Mat img, Point pt1, Point pt2, Scalar color, int thickness, int lineType, int shift)
参数:
img 要绘制线段的图像
pt1 矩形的一个角的坐标
pt2与 pt1 相对的矩形角的坐标
color 矩形的颜色
thickness 构成矩形的线条的厚度,-1则表示填充矩形
line_type线段的类型。 参见 #LINE_*
shift坐标点的小数位数
Mat mat = new Mat(300,300, CvType.CV_8UC3);
mat.setTo(new Scalar(255,255,255));Imgproc.rectangle(mat,new Point(50,50),new Point(250,250),new Scalar(0,250,0),4,Imgproc.LINE_AA,0);HighGui.imshow("mat",mat);
HighGui.waitKey();

结果:
在这里插入图片描述

2.矩形绘制(填充)

rectangle(Mat img, Rect rec, Scalar color, int thickness, int lineType, int shift)
参数:
img 要绘制线段的图像
recRect对象,表示矩形的位置和大小
color 矩形的颜色
thickness 构成矩形的线条的厚度,-1则表示填充矩形
line_type线段的类型。 参见 #LINE_*
shift坐标点的小数位数

三、圆绘制

1.绘制一个圆

circle(Mat img, Point center, int radius, Scalar color, int thickness, int lineType, int shift)
参数:
img 要绘制圆的图像
center 圆心的坐标(x, y)
radius 圆的半径
color 圆的颜色
thickness圆的线条厚度。如果为正数,表示绘制圆的外轮廓;如果为负数,表示绘制填充圆
line_type圆的边界类型。 参见 #LINE_*
shift圆心和半径值的坐标的小数位数
   //创建矩阵Mat img = new Mat(300,420, CvType.CV_8UC3,new Scalar(255,255,255));//定义坐标Point point = new Point(100,100);//定义半径int radius=50;//定义颜色Scalar scalar = new Scalar(255, 0, 0);//绘制圆Imgproc.circle(img,point,radius,scalar,4,Imgproc.LINE_AA,0);//蓝色圆//====在上方的基础上绘制一个五环===//定义坐标Point point1 = new Point(210,100);Point point2 = new Point(320,100);Point point3 = new Point(150,160);Point point4 = new Point(260,160);//定义颜色Scalar scalar1 = new Scalar(0, 0, 0);Scalar scalar2 = new Scalar(0,0,255);Scalar scalar3 = new Scalar(0,215,255);Scalar scalar4 = new Scalar(0,215,0);//绘制圆Imgproc.circle(img,point1,radius,scalar1,4,Imgproc.LINE_AA,0);//黑色圆Imgproc.circle(img,point2,radius,scalar2,4,Imgproc.LINE_AA,0);//红色圆Imgproc.circle(img,point3,radius,scalar3,4,Imgproc.LINE_AA,0);//黄色圆Imgproc.circle(img,point4,radius,scalar4,4,Imgproc.LINE_AA,0);//绿色圆//显示HighGui.imshow("img",img);HighGui.waitKey();

结果:
在这里插入图片描述

四、椭圆(椭圆弧)绘制

  使用分段线性曲线近似椭圆弧边界。如果您需要更多控制椭圆渲染,您可以使用 #ellipse2Poly 获取曲线,然后使用 #polylines 渲染或使用 #fillPoly 填充。如果您使用该函数的第一个变体并希望绘制整个椭圆而不是弧 ,请传递 startAngle=0 和 endAngle=360。如果 startAngle 大于 endAngle,它们将被交换。下面的图说明了绘制蓝色弧的参数的含义
在这里插入图片描述

ellipse(Mat img, Point center, Size axes, double angle, double startAngle, double endAngle, Scalar color, int thickness, int lineType, int shift)
参数:
img 要绘制椭圆的图像
center 椭圆的中心点
axes 椭圆的两个轴的长度(Size类型,包含宽度和高度)
angle 椭圆的旋转角度(以度为单位)
startAngle 椭圆弧的起始角度(以度为单位)
endAngle 椭圆弧的结束角度(以度为单位)
color椭圆的颜色
thickness这是线条的厚度。如果设置为负数,则会填充椭圆
line_type边界类型。 参见 #LINE_*
shift点坐标中的小数位数
    //创建空白图像Mat mat = new Mat(500,500, CvType.CV_8UC3,new Scalar(255,255,255));//椭圆中心点Point point = new Point(250,250);//轴长Size axes = new Size(200,150);//旋转角度double angle = 0;//起始角度double startAngle= 0;//结束角度double endAngle = 360;Imgproc.ellipse(mat,point,axes,angle,startAngle,endAngle,new Scalar(0,200,0),2,Imgproc.LINE_8,0);//绘制椭圆double vals[]={200,200,100,100,0};RotatedRect box = new RotatedRect(vals);Imgproc.ellipse(mat,box,new Scalar(0,0,255),2,Imgproc.LINE_8);Imgcodecs.imwrite(FileUtil.resPath + "imgproc/ellipse.jpg",mat);

结果:

在这里插入图片描述

2.椭圆绘制

ellipse(Mat img, RotatedRect box, Scalar color, int thickness, int lineType)
参数:
img 要绘制椭圆的图像
box 这是一个 RotatedRect 对象,表示椭圆的边界框
axes 椭圆的两个轴的长度(Size类型,包含宽度和高度)
angle 椭圆的旋转角度(以度为单位)
startAngle 椭圆弧的起始角度(以度为单位)
endAngle 椭圆弧的结束角度(以度为单位)
color椭圆的颜色
thickness这是线条的厚度。如果设置为负数,则会填充椭圆
line_type边界类型。 参见 #LINE_*
shift点坐标中的小数位数

五、多边形填充

1.单个填充

  fillConvexPoly 用于绘制填充的凸多边形它不仅可以填充凸多边形,还可以填充任何单调的非自相交多边形,即轮廓最多与每条水平线(扫描线)相交两次的多边形(尽管其顶部和/或底部边缘可能是水平的)

fillConvexPoly(Mat img, MatOfPoint points, Scalar color, int lineType, int shift)
参数:
img 输入/输出图像
points 含多边形顶点坐标的 MatOfPoint 对象
color 填充多边形时使用的颜色
line_type边界类型。 参见 #LINE_*
shift点坐标中的小数位数
        Mat mat = new Mat(500,500, CvType.CV_8UC3,new Scalar(255,255,255));MatOfPoint matOfPoint = new MatOfPoint();matOfPoint.fromArray(new Point(100 ,100 ),new Point(400 ,100 ),new Point(400 ,400 ),new Point(100 ,400 ));//填充多边形Imgproc.fillConvexPoly(mat,matOfPoint,new Scalar(0,255,0),Imgproc.LINE_8,0);HighGui.imshow("fill",mat);HighGui.waitKey();mat.release();HighGui.destroyAllWindows();

2.多个填充

  fillPoly 用于填充由多个多边形轮廓所包围的区域。该函数可以填充复杂的区域,例如包含空洞的区域、具有自交点(即某些部分相互交叉)的轮廓等等.

fillPoly(Mat img, java.util.List pts, Scalar color, int lineType, int shift, Point offset)
参数:
img 输入/输出图像
pts 包含多边形顶点坐标的 java.util.List 对象
color 填充多边形时使用的颜色
line_type边界类型。 参见 #LINE_*
offset填充多边形时的偏移量,是一个 Point 对象
      Mat mat = new Mat(500,500, CvType.CV_8UC3,new Scalar(255,255,255));MatOfPoint matOfPoint = new MatOfPoint();MatOfPoint matOfPoint1 = new MatOfPoint();matOfPoint.fromArray(new Point(100 ,100 ),new Point(400 ,100 ),new Point(400 ,400 ),new Point(100 ,400 ));matOfPoint1.fromArray(new Point(50 ,50 ),new Point(200 ,50 ),new Point(200 ,200 ),new Point(50 ,200 ));List pts = new ArrayList<>();pts.add(matOfPoint); pts.add(matOfPoint1);//填充多边形Imgproc.fillPoly(mat,pts,new Scalar(0,255,0),Imgproc.LINE_8,0);HighGui.imshow("fill",mat);HighGui.waitKey();mat.release();HighGui.destroyAllWindows();

结果:
在这里插入图片描述

六、标记绘制

1.字段

列举部分

MARKER_CROSS 十字形标记
MARKER_DIAMOND 菱形标记
MARKER_SQUARE 正方形标记
MARKER_STAR 五角星标记

2.方法介绍

​   在图像中预定义的位置绘制标记

drawMarker(Mat img, Point position, Scalar color, int markerType, int markerSize, int thickness, int line_type)
参数:
img 输入/输出图像
position 标记的位置
color 标记的颜色
markerType标记的类型,表示标记的形状。可以使用Imgproc类中定义的常量,如Imgproc.MARKER_CROSS等
markerSize标记轴的长度(标记的大小) [默认 = 20 像素]
thickness标记的线条粗细
line_type线条类型。
    // 创建一个空白图像Mat img = Mat.zeros(500, 500, 16); // 16表示CV_8UC3,即3通道的8位无符号整数图像// 定义标记的位置、颜色和其他参数Point position = new Point(250, 250); // 在图像中心Scalar color = new Scalar(0, 255, 0); // 绿色int markerType = Imgproc.MARKER_CROSS;int markerSize = 20;int thickness = 2;int lineType = Imgproc.LINE_8;// 在图像上绘制标记Imgproc.drawMarker(img, position, color, markerType, markerSize, thickness, lineType);// 显示图像HighGui.imshow("DrawMarkerExample", img);HighGui.waitKey(0);HighGui.destroyAllWindows();

结果:

七、文本绘制

  如果使用指定的字体无法渲染某些符号,它们将被替换为问号。

1.字段

列举部分。

FONT_HERSHEY_COMPLEX 使用复杂的 Hershey 字体风格。这是默认的字体样式,提供多种字符集和可读性
FONT_HERSHEY_PLAIN 使用简单的 Hershey 字体风格。字体比 FONT_HERSHEY_COMPLEX 更简单,但仍然具有多种字符集
FONT_HERSHEY_SCRIPT_COMPLEX 使用复杂的 Hershey 手写字体风格。这种字体模仿手写文字的外观
FONT_HERSHEY_SIMPLEX 使用Hershey简单字体风格。这种字体提供了一种清晰、简洁的外观,适合于在图像上绘制文本时要求较高的可读性和易读性的场景
FONT_HERSHEY_TRIPLEX 使用三重的 Hershey 字体风格,提供更多的字符集和可读性

2.方法介绍

1.绘制一个文本字符串

putText(Mat img, java.lang.String text, Point org, int fontFace, double fontScale, Scalar color, int thickness, int lineType, boolean bottomLeftOrigin)
参数:
img 输入/输出图像
text 要绘制的文本字符串
org 指定文本字符串的起始位置(左下角或右下角,取决于bottomLeftOrigin参数)
fontFace 指定字体类型。OpenCV提供了一些预定义的字体,如FONT_HERSHEY_SIMPLEX、FONT_HERSHEY_PLAIN等
fontScale 指定字体大小。它表示字体相对于原始大小的缩放因子
color 指定文本的颜色
thickness文本线条线条粗细
line_type线条类型。
bottomLeftOrigin boolean类型,指定文本字符串的起始位置是否从图像的左下角开始。如果为true,则文本从左下角开始绘制;如果为false,则从图像的右下角开始绘制
        // 创建一个空白图像Mat img = Mat.zeros(200, 400, CvType.CV_8UC3);//绘制文本Imgproc.putText(img,"hello OpenCV",new Point(100,100),Imgproc.FONT_HERSHEY_SIMPLEX,1,new Scalar(0,255,0),1,Imgproc.LINE_AA,false);// 显示图像HighGui.imshow("img", img);HighGui.waitKey(0);HighGui.destroyAllWindows();

结果:

在这里插入图片描述

八、相关扩展方法

1.线段裁定

clipLine用于检查线段是否完全位于给定的图像边界内,并进行裁剪。如果线段与图像边界相交或超出边界,它将被裁剪到边界内。函数返回一个布尔值,指示线段是否被裁剪。

clipLine(Rect imgRect, Point pt1, Point pt2)
参数:
img 输入/输出图像
pts 包含多边形顶点坐标的 java.util.List 对象
color 填充多边形时使用的颜色
line_type边界类型。 参见 #LINE_*
offset填充多边形时的偏移量,是一个 Point 对象
      // 创建一个图像矩形范围Rect imgRect = new Rect(0, 0, 100, 100);// 创建线段的起点和终点Point pt1 = new Point(50, 50);Point pt2 = new Point(60, 150);// 剪裁线段,使其位于图像矩形范围内boolean clipped = Imgproc.clipLine(imgRect, pt1, pt2);if (clipped) {System.out.println("线段被剪裁后的起点:" + pt1);System.out.println("线段被剪裁后的终点:" + pt2);} else {System.out.println("线段完全位于图像矩形范围之外");}

结果

线段被剪裁后的起点:{50.0, 50.0}
线段被剪裁后的终点:{55.0, 99.0}

2.椭圆弧转换为多段线

ellipse2Poly用于将椭圆弧转换为多段线 如果arcStart的值大于arcEnd,那么这两个值会被交换。

ellipse2Poly(Point center, Size axes, int angle, int arcStart, int arcEnd, int delta, MatOfPoint pts)
参数:
center 椭圆的中心点坐标 (Point 类型)
axes 椭圆的半长轴和半短轴的长度 (Size 类型).
angle 椭圆的旋转角度
arcStart 椭圆弧的起始角度
arcEnd 椭圆弧的结束角度
delta 角度增量,用于计算椭圆弧上的点。增加这个值会增加多段线的精度
pts 输出参数,包含生成的椭圆边界点的 MatOfPoint 对象.
      //创建空白图像Mat mat = new Mat(500,500, CvType.CV_8UC3,new Scalar(255,255,255));//椭圆中心点Point point = new Point(250,250);//轴长Size axes = new Size(200,150);//旋转角度int angle = 0;//起始角度int arcStart= 0;//结束角度int arcEnd = 360;//转换成线段MatOfPoint matOfPoint = new MatOfPoint();Imgproc.ellipse2Poly(point,axes,angle,arcStart,arcEnd,10,matOfPoint);System.out.println("matOfPoint.dump() = " + matOfPoint.dump());//绘制线段List pts = new ArrayList<>();pts.add(matOfPoint);Imgproc.polylines(mat,pts,true,new Scalar(255,0,0),2);Imgcodecs.imwrite(FileUtil.resPath + "imgproc/ellipse_2_poly.jpg",mat);

请自行验证结果

3.计算字体尺寸比例

getFontScaleFromHeight用于根据给定的像素高度计算字体尺寸比例。这对于绘制文本到图像上时非常有用,特别是当您需要确保文本的高度与给定的像素高度相匹配时。
请注意,此方法返回的是字体尺寸的比例因子,而不是具体的像素值或绝对大小。这意味着,如果您使用返回的比例因子与某个基础字体大小(例如 12)相乘,您将获得合适的字体大小以匹配给定的像素高度。

getFontScaleFromHeight(int fontFace, int pixelHeight, int thickness)
参数:
fontFace 字体类型
pixelHeight 目标像素高度.
thickness 文本的线条粗细

请自行验证结果

万水千山总是情,本栏完全公开免费。点赞+收藏30,瞬更下一篇
上一篇:Imgproc之色彩映射及颜色空间转换 下一篇: Imgproc之点集拟合

这篇关于19.java openCV4.x 入门-Imgproc之图形绘制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/908297

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听