【OpenCV入门】第三部分——绘制图形与文字

news2024/10/6 18:33:39

文章结构

  • 线段的绘制
  • 矩形的绘制
  • 圆形的绘制
  • 多边形的绘制
  • 文字的绘制
    • 文字的斜体效果
    • 文字的垂直镜像效果
    • 在图像上绘制文字
  • 动态绘制图形

线段的绘制

使用 line() 方法可绘制长短不一的、粗细各异的、五颜六色的线段。

img = cv2.line(img,pt1,pt2,color,thickness)
  • img: 画布
  • pt1: 线段的起点坐标
  • pt2: 线段的终点坐标
  • color: 绘制线段时的线条颜色
  • thickness: 绘制线段时的线条宽度

当使用line()方法绘制线段时,要指定线条颜色。

实例1: 绘制线段
使用line()方法分别绘制颜色为蓝色,线条宽度为5的线段。

import cv2
import numpy as np

# np.zeros() 创建了一个画布
# (300,300,3) 一个300×300,具有3个颜色空间(即Red、Green和Blue)的画布
# np.uint8 OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
canvas = np.zeros((300,300,3), np.uint8)

# 在画布上,绘制一条起点坐标为(50,50)、终点坐标为(250,50)、蓝色的、线条宽度为5的线段
canvas = cv2.line(canvas,(50,50),(250,50),(255,0,0),5)

cv2.imshow("line", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
在这里插入图片描述
如果想换成白色背景,则可以使用以下代码:

canvas = np.ones((300,300,3),np.uint8)*255

如果想随机绘制线段,需要借助numpy.random下的uniform()方法。uniform()方法的作用是从一个均匀分布的数据中随机采样。

numpy.random.uniform(low,high,size)
  • low: 采样下界,float类型,默认值为0.0
  • high: 采样上界,float类型,默认值为1.0
  • size: 输出样本数目,int类型或者元组类型,默认值为None

需要注意两个问题:一个是样本的取值范围,即包含low,但不包含high;另一个是uniform()方法返回的是一个float类型的值,为了能将这个值应用到本实例,需要将其转换成int类型的值。

实例2: 绘制99条长度、方向、宽度、颜色随机的线段

import cv2
import numpy as np

# np.zeros() 创建了一个画布
# (300,300,3) 一个300×300,具有3个颜色空间(即Red、Green和Blue)的画布
# np.uint8 OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
canvas = np.zeros((300, 300, 3), np.uint8)

for i in range(0, 100):
    pt1x = int(np.random.uniform(0, 300))  # 线段的起点横坐标在1 ~ 299的范围内随机取值
    pt1y = int(np.random.uniform(0, 300))  # 线段的起点纵坐标在1 ~ 299的范围内随机取值
    pt2x = int(np.random.uniform(0, 300))  # 线段的终点横坐标在1 ~ 299的范围内随机取值
    pt2y = int(np.random.uniform(0, 300))  # 线段的终点纵坐标在1 ~ 299的范围内随机取值
    r = int(np.random.uniform(0, 256))  # R通道在0 ~ 255的范围内随机取值
    g = int(np.random.uniform(0, 256))  # G通道在0 ~ 255的范围内随机取值
    b = int(np.random.uniform(0, 256))  # B通道在0 ~ 255的范围内随机取值
    thickness = int(np.random.uniform(1, 6))  # 线条宽度在1 ~ 5的范围内随机取值
    canvas = cv2.line(canvas, (pt1x, pt1y), (pt2x, pt2y), (r, g, b), thickness)

cv2.imshow("line", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

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

矩形的绘制

rectang()方法既可以绘制矩形边框,也可以绘制实心矩形。

img = cv2.rectangle(img, pt1, pt2, color, thickness)
  • img: 画布
  • pt1: 矩形的左上角坐标
  • pt2: 矩形的右下角坐标
  • color: 绘制矩形时的线条颜色
  • thickness: 绘制矩形时的线条宽度
  • img: 画布

实例3: 绘制一个矩形边框
绘制一个青色的、线条宽度为20的矩形边框。

import numpy as np
import cv2

canvas = np.zeros((300,300,3),np.uint8)

# 在画布上绘制一矩形边框
canvas = cv2.rectangle(canvas,(50,50),(200,150),(255,255,0),20)
cv2.imshow("Rectangle",canvas)
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
在这里插入图片描述
如果将代码改成以下形式,将会出现一个实心矩形:

import numpy as np
import cv2

canvas = np.zeros((300,300,3),np.uint8)

# 在画布上绘制一矩形边框
canvas = cv2.rectangle(canvas,(50,50),(200,150),(255,255,0),-1) # 将thickness改为-1
cv2.imshow("Rectangle",canvas)
cv2.waitKey()
cv2.destroyAllWindows()

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

圆形的绘制

circle()方法既可以绘制圆形边框,也可以绘制实心圆形。

 img = cv2.circle(img,center,radius,color,thickness)
  • img: 画布
  • center: 圆形的圆心坐标
  • radius: 圆形的半径
  • color: 绘制圆形时的线条颜色
  • thickness: 绘制圆形时的线条宽度
  • img: 画布

实例4: 绘制同心圆

import numpy as np
import cv2

canvas = np.zeros((300, 300, 3), np.uint8)

# shape[1]表示画布的宽度,center_X表示圆心的横坐标
# 圆心的横坐标等于画布宽度的一半
center_X = int(canvas.shape[1] / 2)

# shape[0]表示画布的高度,center_Y表示圆心的纵坐标
# 圆心的纵坐标等于画布高度的一半
center_Y = int(canvas.shape[0] / 2)

for r in range(0, 150, 30):
    cv2.circle(canvas, (center_X, center_Y), r, (0, 255, 0), 5)

cv2.imshow("Circles", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

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

实例5: 绘制27个随机实心圆

import numpy as np
import cv2

canvas = np.zeros((300, 300, 3), np.uint8)

for i in range(0,28):

    # 获得随机的圆心横坐标,这个横坐标在[0,299]范围内取值
    center_X = np.random.randint(0,high=300)

    # 获得随机的圆心纵坐标,这个横坐标在[0,299]范围内取值
    center_Y = np.random.randint(0,high=300)

    # 获得随机的半径,这个半径在[11,70]范围内取值
    radius = np.random.randint(11,high=71)

    # 获得随机的线条颜色,这个颜色由3个在[0,255]范围内的随机数组成的列表表示
    color = np.random.randint(0,high=256,size=(3,)).tolist()
    
    # 绘制一个圆心坐标为(center_X,center_Y)、半径为radius、颜色为color的实心圆形
    cv2.circle(canvas, (center_X, center_Y), radius, color, -1)

cv2.imshow("Circles", canvas)
cv2.waitKey()
cv2.destroyAllWindows()

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

注意:因为OpenCV中的颜色值是一个列表,而randint返回的是一个数值或者数组,所以color = np.random.randint(0,high = 256,size = (3,)).tolist()中的.tolist()不能忽略。

多边形的绘制

使用polylines()方法绘制的多边形既可以是封闭的,也可以是不封闭的。

img = cv2.polylines(img, pts, isClosed, color, thickness) 
  • img: 画布
  • pts: 由多边形各个顶点的坐标组成的列表,这个列表是一个NumPy的数组类型
  • isClosed: 如果值为True,表示一个闭合的多边形;如果值为False,表示一个不闭合的多边形
  • color: 绘制多边形时的线条颜色
  • thickness: 绘制多边形时的线条宽度

实例6: 绘制一个等腰梯形边框

import numpy as np # 导入Python中的numpy模块
import cv2

# np.zeros():创建了一个画布
# (300, 300, 3):一个300 x 300,具有3个颜色空间(即Red、Green和Blue)的画布
# np.uint8:OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
canvas = np.zeros((300, 300, 3), np.uint8)
# 按顺时针给出等腰梯形4个顶点的坐标
# 这4个顶点的坐标构成了一个大小等于“顶点个数 * 1 * 2”的数组
# 这个数组的数据类型为np.int32
pts = np.array([[100, 50], [200, 50], [250, 250], [50, 250]], np.int32)
# 在画布上根据4个顶点的坐标,绘制一个闭合的、红色的、线条宽度为5的等腰梯形边框
canvas = cv2.polylines(canvas, [pts], True, (0, 0, 255), 5)
cv2.imshow("Polylines", canvas) # 显示画布
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
在这里插入图片描述
如果改成以下代码,会得到一个不封闭的矩形:

canvas = cv2.polylines(canvas, [pts], False, (0, 0, 255), 5)

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

文字的绘制

使用用于绘制文字的putText()方法,不仅能够设置字体的样式、大小和颜色,而且能够使字体呈现斜体的效果,还能够控制文字的方向,进而使文字呈现垂直镜像的效果。

img = cv2.putText(img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)
  • img: 画布
  • text: 要绘制的文字内容
  • org: 文字在画布中的左下角坐标
  • fontFace: 字体样式
  • fontScale: 字体大小
  • color: 绘制文字时的线条颜色
  • thickness:(可选)绘制文字时的线条宽度
  • lineType:(可选)线形(线形指的是线的产生算法,有4和8两个值,默认值为8)
  • bottomLeftOrigin:(可选)绘制文字时的方向(默认值为False)

字体样式及其含义如下:
在这里插入图片描述

实例7: 绘制文字“OpenCV”

import numpy as np # 导入Python中的numpy模块
import cv2

# np.zeros():创建了一个画布
# (100, 300, 3):一个100 x 300,具有3个颜色空间(即Red、Green和Blue)的画布
# np.uint8:OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
canvas = np.zeros((100, 300, 3), np.uint8)
# 在画布上绘制文字“OpenCV”,文字左下角的坐标为(20, 70)
# 字体样式为FONT_HERSHEY_TRIPLEX
# 字体大小为2,线条颜色是绿色,线条宽度为5
cv2.putText(canvas, "OpenCV", (20, 70), cv2.FONT_HERSHEY_TRIPLEX, 2, (0, 255, 0), 5)
cv2.imshow("Text", canvas) # 显示画布
cv2.waitKey()
cv2.destroyAllWindows()

结果如下:
在这里插入图片描述
如果不借助其他库或者模块的话,使用putText()方法绘制中文时会出现乱码。

文字的斜体效果

FONT_ITALIC可以与其他文字类型一起使用,使字体在呈现指定字体样式效果的同时,也呈现斜体效果。

实例8: 绘制指定字体样式的文字并呈现斜体效果

import numpy as np # 导入Python中的numpy模块
import cv2

# np.zeros():创建了一个画布
# (100, 300, 3):一个100 x 300,具有3个颜色空间(即Red、Green和Blue)的画布
# np.uint8:OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
canvas = np.zeros((100, 300, 3), np.uint8)
# 字体样式为FONT_HERSHEY_TRIPLEX和FONT_ITALIC
fontStyle = cv2.FONT_HERSHEY_TRIPLEX + cv2.FONT_ITALIC
# 在画布上绘制文字“OpenCV”,文字左下角的坐标为(20, 70)
# 字体样式为fontStyle,字体大小为2,线条颜色是绿色,线条宽度为5
cv2.putText(canvas, "OpenCV", (20, 70), fontStyle, 2, (0, 255, 0), 5)
cv2.imshow("Text", canvas) # 显示画布
cv2.waitKey()
cv2.destroyAllWindows()

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

文字的垂直镜像效果

当bottomLeftOrigin为True时,文字将呈现垂直镜像效果。

实例9: 绘制呈现垂直镜像效果的“OpenCV”

import numpy as np # 导入Python中的numpy模块
import cv2

# np.zeros():创建了一个画布
# (200, 300, 3):一个200 x 300,具有3个颜色空间(即Red、Green和Blue)的画布
# np.uint8:OpenCV中的灰度图像和RGB图像都是以uint8存储的,因此这里的类型也是uint8
canvas = np.zeros((200, 300, 3), np.uint8)
# 字体样式为FONT_HERSHEY_TRIPLEX
fontStyle = cv2.FONT_HERSHEY_TRIPLEX
# 在画布上绘制文字“OpenCV”,文字左下角的坐标为(20, 70)
# 字体样式为fontStyle,字体大小为2,线条颜色是绿色,线条宽度为5
cv2.putText(canvas, "OpenCV", (20, 70), fontStyle, 2, (0, 255, 0), 5)
# 使文字“OpenCV”呈现垂直镜像效果,这时lineType和bottomLeftOrigin变成了必须参数
# 其中,lineType取默认值8,bottomLeftOrigin的值为True
cv2.putText(canvas, "OpenCV", (20, 100), fontStyle, 2, (0, 255, 0), 5, 8, True)
cv2.imshow("Text", canvas) # 显示画布
cv2.waitKey()
cv2.destroyAllWindows()

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

在图像上绘制文字

当在图像上绘制文字时,不需要再导入NumPy模块。

实例10: 在图像上绘制文字

import cv2

image = cv2.imread("2.jpg") # 读取2.jpg
# 字体样式为FONT_HERSHEY_TRIPLEX
fontStyle = cv2.FONT_HERSHEY_TRIPLEX
# 在image上绘制文字“OpenCV”,文字左下角的坐标为(20, 90),
# 字体样式为fontStyle,字体大小为1,线条颜色是黄色
cv2.putText(image, "Flower", (20, 90), fontStyle, 1, (0, 255, 255))
cv2.imshow("Text", image) # 显示画布
cv2.waitKey()
cv2.destroyAllWindows()

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

动态绘制图形

实例11: 弹球动画
在一个宽高都为200像素的白色图像中,绘制一个半径为20像素的蓝色小球。让小球做匀速直线运动,一旦圆形碰触到图像边界则发生反弹。

想要实现这个功能需要解决两个问题:如何计算运动轨迹和如何实现动画。

(1)通过图像坐标系计算运动轨迹

小球在运动的过程中可以把移动速度划分为上、下、左、右四个方向。左右为横坐标移动速度,上下为纵坐标移动速度。小球向右移动时横坐标不断变大,向左移动时横坐标不断变小,由此可以认为:小球向右的移动速度为正数,向左的移动速度为负数。纵坐标同理,因为图像坐标系的原点为背景左上角顶点,越往下延伸纵坐标越大,所以小球向上的移动速度为负数,向下的移动速度为正数。
在这里插入图片描述
假设小球移动一段时间之后,移动的轨迹如图4.24 所示,分别达到了四个位置,2号位置和3号位置发生了反弹,也就是移动速度发生了变化,导致了移动方向发生变化。整个过程中,四个位置的速度分别如下所示:

  • 1:右下方向移动,横坐标向右,横坐标速度为 +Vx,纵坐标向下,纵标速度为+Vy
  • 2:右上方向移动,横坐标向右,横坐标速度为 +Vx,纵坐标向上,纵坐标速度为-Vy
  • 3:左上方向移动,横坐标向左,横坐标速度为 -Vx,纵坐标向上,纵坐标速度为-Vy
  • 4:左上方向移动,没有碰到边界,依然保持着与3号位置相同移动速度。

由此可以得出,小球只需要改变速度的正负号就可以改变移动的方向,所以在程序中可以将小球的横坐标速度和纵坐标速度设定成一个不变的值,每次小球碰到左右边界,就更改横坐标速度的正负号,碰到上下边界,就更改纵坐标速度的正负号。

(2)通过time模块实现动画效果
Python自带一个time时间模块,该模块提供了一个sleep()方法可以让当前线程休眠一段时间。

time.sleep(seconds)
  • seconds: 休眠的秒数,可以是小数。

动画实际上是有多个画面在短时间内交替放映实现的视觉效果。每一个画面被称为一帧。使用time模块每1/60s计算一次小球的移动轨迹,并将移动后的结果绘制到图像上。

import cv2
import time
import numpy as np

width, height = 200, 200  # 画面的宽和高
r = 20  # 圆半径
x = r + 20  # 圆心和坐标起始坐标
y = r + 100  # 圆形纵坐标起始坐标
x_offer = y_offer = 4  # 每一帧的移动速度

while cv2.waitKey(1) == -1:  # 按下任何按键之后
    if x > width - r or x < r:  # 如果圆的横坐标超出边界
        x_offer *= -1  # 横坐标速度取相反值
    if y > height - r or y < r:  # 如果圆的纵坐标超出边界
        y_offer *= -1  # 纵坐标速度取相反值
    x += x_offer  # 圆心按照横坐标速度移动
    y += y_offer  # 圆心按照纵坐标速度移动
    img = np.ones((width, height, 3), np.uint8) * 255  # 绘制白色背景面板
    cv2.circle(img, (x, y), r, (255, 0, 0), -1)  # 绘制圆形
    cv2.imshow("img", img)  # 显示图像
    time.sleep(1 / 60)  # 休眠1/60s,也就是每秒60帧

cv2.destroyAllWindows()  # 释放所有窗体

如果waitKey括号里的值为0、空或者负数,则它在按下按键之前只执行一次循环,它会无限等待按下按键而x,y的值不变。看上去就是圆形不动。所以将括号内的值设置为一毫秒,当未按下按键时,每一毫秒都会执行一次循环,x,y的值都会改变,这看起来就能让圆形动起来,直到按下任意按键,跳出循环,释放所有窗体。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

苹果使用3D打印技术制造Apple Watch Series 9手表外壳

据彭博社的马克・古尔曼报道&#xff0c;苹果公司正在使用 3D 打印技术来制造即将推出的部分Apple Watch Series 9 的外壳。这种制造工艺可以节省传统数控加工所需的大量金属材料&#xff0c;同时缩短生产时间。这与之前苹果分析师郭明錤的说法相吻合。 苹果公司自2021年推出Ai…

【三等奖方案】小样本数据分类任务赛题「痛!太痛了!」团队解题思路

第十届CCF大数据与计算智能大赛&#xff08;2022 CCF BDCI&#xff09;已圆满结束。大赛官方竞赛平台DataFountain&#xff08;简称DF平台&#xff09;将陆续释出各赛题获奖队伍的方案思路。 本方案为【小样本数据分类任务】赛题的三等奖获奖方案&#xff0c;赛题地址&#xf…

亚马逊自动广告如何投放?这些技巧你了解嘛!

现如今&#xff0c;亚马逊店铺为了能够提升产品的转化率&#xff0c;为了增加产品曝光率&#xff0c;会选择投放站内广告&#xff0c;现在大多数的亚马逊店铺都有在站内投放广告&#xff0c;不然的话要想获取到自然流量实在是太难了。 很多没有投放站内广告的亚马逊店铺&#…

【数据结构】C语言队列(详解)

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--C语言实现队列 目录 一.队列概念及结构 1.1队列的概念 1.2队列的结构 二.队列的实现 2.1头文…

Mybatis 里面的缓存机制

Mybatis 里面设计的二级缓存是用来提升数据的检索效率&#xff0c;避免每次数据的访问都需要去查询数据库。 一级缓存&#xff0c;是 SqlSession 级别的缓存&#xff0c;也叫本地缓存&#xff0c;因为每个用户在执行查询的时 候都需要使用 SqlSession 来执行&#xff0c; 为了避…

案例分享:西河水库安全监测信息化系统实施方案

一、项目概述1.1项目背景西河水库信息化工作已开展多年&#xff0c;但是由于西河水库监测设备都已经老化或者损坏&#xff0c;现有设备已渐渐不能满足新时期西河水库信息化和现代化发展需求。因此&#xff0c;灌区管理局拟在运用现代信息和通信技术手段感测、分析、整合水库运行…

【Git】(六)子模块跟随主仓库切换分支

场景 主仓库&#xff1a;TestGit 子模块&#xff1a;SubModule 分支v1.0 .gitmodules文件 [submodule "Library/SubModule"]path Library/SubModuleurl gitgitee.com:sunriver2000/SubModule.gitbranch 1.0.0.0 分支v2.0 .gitmodules文件 [submodule "Li…

Mapbox-gl 关闭所有Popup,以及关闭按钮出现黑色边框bug

1.官方示例 var popup new mapboxgl.Popup().addTo(map);popup.remove(); 很明显&#xff0c;需要记录popup对象&#xff0c;管理起来比较麻烦。 2.本人采用div的方式关闭所有的popup&#xff0c;在map对象上新增加方法 map.closePopupmapView.popupClear function(){$(&q…

Idea中使用Statistic插件统计工程项目代码量

1. 功能背景 公司要对一个项目进行代码统计&#xff0c;这么多类&#xff0c;总不能让我一个一个数据&#xff0c;于是想到了Statistic插件。让我们一起看看Statistic插件怎么使用吧。 2. Statistic插件 首先需要知道Idea统计项目代码行数&#xff0c;主要是使用Statistic插…

概念解析 | 无线感知的新篇章:异构网络感知的原理与挑战

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:异构网络感知。 无线感知的新篇章:异构网络感知的原理与挑战 Interference Management in HetNets 在当今的无线通信领域,我们面临着一个重大的挑战:如何在有限的频谱资源…

【Redis】Redis 的学习教程(五)之 Redis 事务、持久化、集群

1. 事务 1.1 事务的概述 Redis 事务通过 MULTI 、EXEC、DISCARD、WATCH 几个命令来实现 MULTI&#xff1a;开启事务EXEC&#xff1a;提交事务DISCARD&#xff1a;放弃事务WATCH&#xff1a;为 Redis 事务提供 check-and-set &#xff08;CAS&#xff09;行为 Redis 事务可以…

创业新机会?全球将有36%的员工永久远程办公!

刚刚过去的2020年是极其不平凡的一年&#xff0c;这一年面对的困难&#xff0c;严重程度超出了所有人的预料&#xff0c;很多公司都遇到的困难就是无法按时复工&#xff0c;这对于创业公司而言&#xff0c;无异于生死大考。 为了活下去&#xff0c;很多公司都开启了远程办公的…

欧科云链研究院探析Facebook稳定币发行经历会不会在PayPal重演

引言 作者最近的报告-探析PayPal发行稳定币是否会重蹈Facebook覆辙-近期被英国的金融时报&#xff08;中文版&#xff09;刊登。由于该报告在欧科云链研究院内部反响较好&#xff0c;下面就带大家简单的剖析这篇报告的主要内容。 *这篇文章主要由对比分析&#xff08;已删减&a…

【高阶数据结构】AVL树 {概念及实现;节点的定义;插入并调整平衡因子;旋转操作:左单旋,右单旋,左右双旋,右左双旋;AVL树的验证及性能分析}

AVL树 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明…

定位与轨迹-百度鹰眼轨迹开放平台-学习笔记

1. 百度鹰眼轨迹的主要功能接口 百度的鹰眼轨迹平台&#xff0c;根据使用场景不同&#xff0c;提供了web端、安卓端等各种类型的API与SDK&#xff0c;本文章以web端API为例&#xff0c;介绍鹰眼轨迹的使用。 2. API使用前的准备 使用鹰眼轨迹API&#xff0c;需要两把钥匙&…

真香!Jenkins 主从模式解决问题So Easy~

01、Jenkins 能干什么 Jenkins 是一个开源软件项目&#xff0c;是基于 Java 开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。 中文官网&#xff1a;https://jenkins.io/zh/ …

OpenCV(十一):图像仿射变换

目录 1.图像仿射变换介绍 仿射变换&#xff1a; 仿射变换矩阵&#xff1a; 仿射变换公式&#xff1a; 2.仿射变换函数 仿射变换函数&#xff1a;warpAffine() 图像旋转&#xff1a;getRotationMatrix2D() 计算仿射变换矩阵&#xff1a;getAffineTransform() 3.demo 1.…

并发(CAS ABA问题)07

CAS public class Hsss {public static void main(String[] args) {AtomicInteger atomicIntegernew AtomicInteger(201);//CAS compareAndSet 比较并交换//如果我期望的值达到了&#xff0c;那么就更新&#xff0c;否则&#xff0c;就不更新atomicInteger.compareAndSet(201,2…

Java版电子招投标管理系统源码-电子招投标认证服务平台-权威认证

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…