【OpenCV实现鼠标绘图,轨迹栏做调色板,图像的基本操作】
文章目录
- 鼠标绘图
- 轨迹栏做调色板
- 图像的基本操作
鼠标绘图
在OpenCV中操作鼠标事件
函数:cv.setMouseCallback()
目的是在鼠标双击的地方画一个圆。首先,我们需要创建一个鼠标回调函数,该函数会在鼠标事件发生时执行。鼠标事件包括左键按下、左键松开、左键双击等等。通过获取每个鼠标事件的坐标(x, y),我们就能实现画圆的功能。
import numpy as np
import cv2 as cv# 创建一个黑色图像
img = np.zeros((512, 512, 3), np.uint8)# 鼠标回调函数,当鼠标左键双击时,在双击的位置画一个半径为100的蓝色圆
def draw_circle(event, x, y, flags, param):if event == cv.EVENT_LBUTTONDBLCLK:# 画一个半径为100的蓝色圆,圆心坐标为(x, y),颜色为(255, 0, 0),-1表示填充整个圆cv.circle(img, (x, y), 100, (255, 0, 0), -1)# 创建一个窗口,并将鼠标回调函数与窗口绑定
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)while True:# 显示图像cv.imshow('image', img)# 等待用户按键,如果按下的是'q'键,则退出循环if cv.waitKey(20) == ord('q'):break# 关闭窗口
cv.destroyAllWindows()
结果,双击画圆:

这段代码创建了一个大小为512x512的黑色图像,然后定义了一个鼠标回调函数draw_circle,该函数在鼠标左键双击时,在双击的位置画一个半径为100的蓝色(BGR值为(255, 0, 0))的圆。程序将这个回调函数与窗口"image"绑定,然后进入一个无限循环,显示图像,直到用户按下键盘上的"q"键,窗口才会关闭。
当我们创建一个交互式绘图程序时,我们需要考虑两种模式:画矩形和画圆形。为了实现这个目标,我们需要在鼠标回调函数中添加逻辑,以便根据用户的选择来绘制相应的图形。
import numpy as np
import cv2 as cvdrawing = False # 当鼠标按下的时候会为True
mode = True # True画矩形,按下'm'改变模式
ix, iy = -1, -1# 鼠标回调函数
def draw_circle(event, x, y, flags, param):global ix, iy, drawing, modeif event == cv.EVENT_LBUTTONDOWN:drawing = Trueix, iy = x, yelif event == cv.EVENT_MOUSEMOVE:if drawing == True:if mode == True:cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)else:cv.circle(img, (x, y), 5, (0, 0, 255), -1)elif event == cv.EVENT_LBUTTONUP:drawing = Falseif mode == True:cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)else:cv.circle(img, (x, y), 5, (0, 0, 255), -1)img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)while 1:cv.imshow('image', img)k = cv.waitKey(1) & 0xFFif k == ord('m'):mode = not modeelif k == ord('q'):breakcv.destroyAllWindows()
二:
import numpy as np
import cv2 as cv# 定义全局变量,初始模式为矩形
drawing = False # 当鼠标按下时变为True
mode = True # True表示矩形模式,False表示圆形模式
ix, iy = -1, -1 # 矩形或圆形的起始坐标# 鼠标回调函数
def draw_shape(event, x, y, flags, param):global ix, iy, drawing, modeif event == cv.EVENT_LBUTTONDOWN: # 当鼠标左键按下时drawing = Trueix, iy = x, yelif event == cv.EVENT_LBUTTONUP: # 当鼠标左键松开时drawing = Falseif mode: # 如果是矩形模式cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)else: # 如果是圆形模式radius = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))cv.circle(img, (ix, iy), radius, (0, 0, 255), -1)# 创建一个黑色图像
img = np.zeros((512, 512, 3), np.uint8)# 创建一个窗口,并将鼠标回调函数与窗口绑定
cv.namedWindow('Drawing')
cv.setMouseCallback('Drawing', draw_shape)while True:cv.imshow('Drawing', img)# 检测键盘按键,切换模式('r'键表示矩形模式,'c'键表示圆形模式)k = cv.waitKey(1) & 0xFFif k == ord('r'):mode = Trueelif k == ord('c'):mode = Falseelif k == 27: # 按下ESC键退出程序breakcv.destroyAllWindows()
在这个程序中,我们使用了全局变量drawing来追踪鼠标是否按下,mode来追踪当前的绘制模式(矩形或圆形),以及ix和iy来保存绘制形状的起始坐标。当用户按下鼠标左键时,drawing变为True,ix和iy保存了鼠标按下的位置。当鼠标松开时,根据当前的模式(矩形或圆形)在图像上绘制相应的形状。
轨迹栏做调色板
OpenCV窗口建立轨迹栏
函数:cv.getTrackbarPos(),cv.createTrackbar()等等
使用OpenCV中的轨迹条(Trackbar)功能。这个应用将会有一个用于显示颜色的窗口,并且提供了三个轨迹条,分别用来指定红色(R)、绿色(G)和蓝色(B)的分量。通过滑动这些轨迹条,窗口的颜色会相应地变化。初始颜色为黑色。
import numpy as np
import cv2 as cv# 回调函数,什么也不做
def nothing(x):pass# 创建一个黑色图像和一个窗口
img = np.zeros((300, 512, 3), np.uint8) # 创建一个黑色图像(300x512的RGB图像)
cv.namedWindow('image') # 创建一个名为'image'的窗口# 创建轨迹栏,参数分别为:轨迹条的名称、所属窗口的名称、默认值、最大值、回调函数
cv.createTrackbar('R', 'image', 0, 255, nothing) # 创建红色分量的轨迹条
cv.createTrackbar('G', 'image', 0, 255, nothing) # 创建绿色分量的轨迹条
cv.createTrackbar('B', 'image', 0, 255, nothing) # 创建蓝色分量的轨迹条# 创建开关轨迹条,用于开启或关闭窗口显示颜色
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image', 0, 1, nothing) # 创建开关轨迹条while 1:cv.imshow('image', img) # 在窗口中显示图像# 检测按键,如果按下'q'键则退出循环if cv.waitKey(1) & 0xFF == ord('q'):break# 获取轨迹条的当前位置r = cv.getTrackbarPos('R', 'image') # 获取红色分量轨迹条的位置g = cv.getTrackbarPos('G', 'image') # 获取绿色分量轨迹条的位置b = cv.getTrackbarPos('B', 'image') # 获取蓝色分量轨迹条的位置s = cv.getTrackbarPos(switch, 'image') # 获取开关轨迹条的位置# 根据轨迹条的位置设置图像颜色if s == 0:img[:] = 0 # 如果开关为关闭状态,将图像颜色设置为黑色else:img[:] = [b, g, r] # 如果开关为开启状态,根据轨迹条位置设置图像颜色cv.destroyAllWindows() # 关闭所有窗口
结果:

在这个应用中,我们会使用cv.createTrackbar()函数来创建这些轨迹条。这个函数的第一个参数是轨迹条的名称,第二个参数是要应用的窗口的名称,第三个参数是一个默认值,第四个参数是最大值,第五个参数是一个回调函数,用于监测轨迹条值的变化。在本例中,我们不需要回调函数,所以我们将跳过这一部分。
轨迹条的另一个重要应用是作为按钮或者开关。因为OpenCV默认并没有按钮功能,所以你可以使用轨迹条来实现这个功能。在我们的应用中,我们会创建一个开关,只有当开关处于导通状态时,窗口才会显示颜色,否则窗口将一直保持黑色。通过这种方式,我们可以实现一个简单的颜色选择器应用。
图像的基本操作
访问像素值并修改他们。
当处理图像时,你可以通过像素的横纵坐标来访问和修改像素值。在OpenCV中,颜色图像通常使用BGR(蓝、绿、红)通道来表示每个像素的颜色,而灰度图像只有一个单通道,表示像素的亮度。
访问像素值:
import numpy as np
import cv2 as cv# 加载图像
img = cv.imread('messi5.jpg')# 访问像素值,返回BGR值
px = img[100, 100]
print(px) # 输出:[157 166 200]# 访问蓝色通道值
blue = img[100, 100, 0]
print(blue) # 输出:157
在上述代码中,img[100, 100]返回了坐标为(100, 100)的像素的BGR值,img[100, 100, 0]返回了该像素的蓝色通道值。
修改像素值:
# 修改像素值为白色(255, 255, 255)
img[100, 100] = [255, 255, 255]# 验证修改后的像素值
print(img[100, 100]) # 输出:[255 255 255]
在上述代码中,img[100, 100]的像素值被修改为白色(255, 255, 255)。
这些基本操作允许你直接访问和修改图像的像素值,为图像处理提供了灵活性。请确保在修改像素值时,坐标值在图像的范围内,以避免访问超出图像边界的像素。
警告:
在处理图像时,简单地遍历每个像素并逐个访问或修改它们通常会非常缓慢,特别是对于大型图像。Numpy是一个针对快速矩阵运算优化过的库,所以它的目标是通过矢量化操作来提高性能。对于单个像素的访问和修改,直接遍历图像的每个像素并逐个处理会效率低下。
在Numpy中,可以使用array.item()和array.itemset()来更高效地访问和修改单个像素的值。这两个方法始终返回或设置标量值。如果需要访问或修改B、G、R通道的值,可以分别使用array.item()来获取每个通道的值。
访问图像属性
图像的特征包括:
形状(Shape):图像的形状描述了它的尺寸,通常以行数、列数和通道数表示。在彩色图像中,通道数为3(表示红、绿、蓝通道),在灰度图像中,通道数为1。你可以使用img.shape获取图像的形状。
print(img.shape) # 输出:(342, 548, 3)
像素数量(Size):图像中像素点的总数量,可以通过img.size获得。
print(img.size) # 输出:562248
数据类型(Data Type):图像的数据类型表示像素值的存储格式。在OpenCV中,通常使用uint8(8位无符号整数)来表示像素值的范围为0到255。
print(img.dtype) # 输出:uint8
这些特征对于了解图像的结构和存储格式非常重要。特别是在调试时,检查图像的数据类型(img.dtype)可以帮助你避免许多与数据类型相关的错误。通过这些特征,可以确定图像的维度、通道数、像素总数以及像素值的表示范围,为图像处理和分析提供了基础信息。
设置一个感兴趣的区域(ROI)
图像处理中,通常需要对图像的特定区域进行操作。这种操作称为兴趣区域(Region of Interest,ROI)操作。通过在图像中找到特定区域,我们可以提高处理的精度和速度,因为我们只需在一个相对较小的区域上执行操作。
在Python中,使用Numpy的索引功能可以很容易地获取和操作ROI。以下是一个示例,演示了如何从图像中选择一个包含球的区域,并将该区域复制到图像的另一部分:
# 选择图像中包含球的区域(ROI)
ball = img[280:340, 330:390]# 将球的区域复制到图像的另一部分(例如,将其粘贴到另一个位置)
img[273:333, 100:160] = ball
在上述示例中,img[280:340, 330:390]选择了图像中的一个特定区域,该区域包含球。然后,通过将这个区域赋值给ball,我们得到了一个ball变量,其中包含了球的图像区域。接着,我们将ball变量的内容复制到图像的另一个位置(例如,图像的[273:333, 100:160]区域),从而将包含球的区域粘贴到了图像的另一部分。
拆分和组合图像
在图像处理中,有时需要分开和合成图像的通道。OpenCV提供了cv.split()函数来将BGR图像分离成单独的通道,同时也提供了cv.merge()函数用于将单独的通道合成成一个BGR图像。另外,也可以通过Numpy的索引来直接访问和修改图像的特定通道。
分开图像通道:
# 使用cv.split()将BGR图像分离成单独的通道
b, g, r = cv.split(img)
在这个例子中,cv.split()函数将BGR图像分离成了三个单独的通道:蓝色(b)、绿色(g)和红色(r)。
合成图像通道:
# 使用cv.merge()将单独的通道合成为BGR图像
img = cv.merge((b, g, r))
在这个例子中,cv.merge()函数将单独的蓝色(b)、绿色(g)和红色(r)通道合成为一个BGR图像。
使用Numpy索引直接访问和修改通道
# 将所有的红色通道设置为0(即去除红色)
img[:, :, 2] = 0
在这个例子中,img[:, :, 2]直接访问并修改了图像的红色通道,将所有的红色值设置为0。
警告:
cv.split() 是一个开销很大的操作,因为它需要遍历整个图像。只有在必要的时候才使用它。否则,尽量使用Numpy的索引来直接访问和修改图像的通道,这样会更高效。
cv.copyMakeBorder()函数可以用来在图像周围添加边框。该函数有以下参数:
src:输入的图像。
top, bottom, left, right:对应方向填充的像素宽度。
borderType:想要添加的边框类型,可以是cv.BORDER_CONSTANT、cv.BORDER_REFLECT、cv.BORDER_REFLECT_101、cv.BORDER_REPLICATE 或 cv.BORDER_WRAP。
value:如果borderType是cv.BORDER_CONSTANT,需要在这里指定颜色值。
以下是一个使用cv.copyMakeBorder()函数演示的例子:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltBLUE = [255, 0, 0]
img1 = cv.imread('opencv-logo.png')# 添加不同类型的边框
replicate = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_WRAP)
constant = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_CONSTANT, value=BLUE)# 显示原始图像和添加边框后的图像
plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()
在这个例子中,cv.copyMakeBorder()函数被用来创建原始图像和带有不同边框类型的图像。这些边框类型包括:REPLICATE、REFLECT、REFLECT_101、WRAP 和 CONSTANT。每种类型的边框都会以不同的方式填充图像的边界。通过这个例子,你可以看到不同类型的边框效果。
相关文章:
【OpenCV实现鼠标绘图,轨迹栏做调色板,图像的基本操作】
文章目录 鼠标绘图轨迹栏做调色板图像的基本操作 鼠标绘图 在OpenCV中操作鼠标事件 函数:cv.setMouseCallback() 目的是在鼠标双击的地方画一个圆。首先,我们需要创建一个鼠标回调函数,该函数会在鼠标事件发生时执行。鼠标事件包括左键按下…...
2023年中国自动排气阀产业链、市场规模及存在问题分析]图[
自动排气阀是一种用于排除管道、容器或设备中累积的空气或气体的装置。在液体流动系统中,气体或空气可能会积聚在管道或容器中,影响流体流动、导致气锁和能效降低。自动排气阀的作用是在系统中的气体达到一定压力时,自动地释放气体࿰…...
服务器往浏览器推消息(SSE)应用
1,SSE 和 WebSocket 对比 SSE(服务器发送事件) SSE是一种基于HTTP的单向通信机制,用于服务器向客户端推送数据。它的工作原理如下: 建立连接:客户端通过发送HTTP请求与服务器建立连接。在请求中ÿ…...
Choreographer
系统面试的时候常会遇到,比如它是什么,是用来做什么用的。或许我们大概清楚,但不一定能表达清楚。 在Android框架中,Choreographer(舞台监督)是一个用于管理和协调UI线程上的动画和绘制操作的系统组…...
CentOS有IP地址,连接不上Xshell或使用Xshell时突然断开
问题原因:未在电脑主机的网络中进行IP地址配置 解决办法: 1.打开控制面板,选择‘网络与共享中心’ 2.选择“更改适配器设置” 3.右键点击以太网3“属性” 4.选择协议版本4,点击属性 5.IP地址填写CentOS的IP地址:192.…...
工业电子中的深力科分享一款PWM控制器 KA3525A
关于PWM控制器: PWM控制器是一种用于控制电机或其他设备的电路,它通过改变脉冲宽度调制(PWM)信号的占空比来控制设备的输出。PWM控制器可以使用单片机或开发板等设备来实现,通过设定占空比,可以轻松地控制…...
【小白专用】安装Apache2.4+ 安装PHP8.2+ php与sql server 2008 r2连接测试教程
PHP安装 1、PHP下载 PHP For Windows: Binaries and sources Releases 注意: 1.要下载Thread Safe,否则没有php8apache2_4.dll这个文件 2.如果是64位系统要下载x64的,x86的不行 3.下载Zip 2、PHP解压安装 将Zip进行解压,里…...
408计算机网络知识点简记 (背诵用
1. 物理层 1. 奈氏和香农 意义不同:奈氏准则鼓励用更优编码码元(2W是码元/s);香农给出数据传输上限C(1. 不可能高过C,2. 若低于C,一定有手段做到C) C = W ∗ l o g 2 ( 1 + S N ) C =W * log_2(1+\frac{S}{N}) C=W∗log2(1+NS) 信噪比 = 10 ∗ l o g 10 ( S N …...
SQL*PLUS对文本长度的限制
SQL*PLUS对文本长度的限制 一、可解决SQL * Plus行长限制的部分选项:二、SQL * plus 因为以上限制导致脚本执行过程可能遇到的错误1、CLOB字段超4000报ORA-22835或ORA-017042、CLOB处理:SP2-0027: 输入太长 (> 2499 个字符) 收到错误SP2-0027…...
配置Insecure Docker Registry支持http请求 (更改默认的https请求)
文章目录 小结问题解决参考 小结 本文记录了如何配置Insecure http docker registry,也就是使用http请求 (更改默认的https请求)Docker Registry仓库。 问题 在测试环境中没有配置SSL/TLS, 需要使用http请求Docker Registry&am…...
BAT032:批量替换当前目录下文件的部分字符
引严:编写批处理程序,实现批量替换当前目录下文件的部分字符。 一、新建Windows批处理文件 参考博客: CSDNhttps://mp.csdn.net/mp_blog/creation/editor/132137544 二、写入批处理代码 1.右键新建的批处理文件,点击【编辑】。…...
uni-app:js实现数组中的相关处理
一、查询数组中,某一项中的某个数据为指定值的项(find() 方法) 使用分析 使用数组的 find() 方法来查询 id 为 0 的那一项数据。这个方法会返回满足条件的第一个元素,如果找不到符合条件的元素,则返回 undefined。使用…...
51系列—基于51单片机的数字频率计(代码+文档资料)
本文主要说明基于51单片机的数字频率计设计,完整资料见文末链接 数字频率计概述 数字频率计是计算机、通讯设备、音频视频等科研生产领域不可缺少的测量仪器。它是一种用十进制数字显示被测信号频率的数字测量仪器。它的基本功能是测量正弦信号,方波信…...
【SA8295P 源码分析 (四)】44 - 如何替换 NON-HLOS.bin 中的 Wifi Firmware 固件
【SA8295P 源码分析】44 - 如何替换 NON-HLOS.bin 中的 Wifi Firmware 固件 1、提取 NON-HLOS.bin 中的 Wifi Firmware 出来2、把提取出来的 wifi 固件放到代码中3、重新打包生成 NON-HLOS.bin4、将生成的 NON-HLOS.bin 与 老的 NON-HLOS.bin 对比5、使用fastboot 下载测试wifi…...
Aspect Android埋点统计activity页面使用时长 onResume onPause,并保存时长
Aspect Android埋点统计activity页面使用时长 onResume onPause,并保存时长 标记: 1.项目下build.gradle dependencies {classpath com.android.tools.build:gradle:3.5.4classpath com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10 } 2.…...
第四章 选择结构程序设计
C语言有两种选择语句:(1)if语句,实现两个分支的选择结构; (2)Switch语句,实现多分支的选择结构。 1.求ax^2bxc0方程的解。 #include<stdio.h> #include<math.h> int …...
JAVA高级教程-Java List(2)
目录 3、List接口的使用(1)3、List接口的使用(3)4、排序,集合之间的转换 3、List接口的使用(1) package ArrayList01;import java.util.ArrayList; import java.util.Iterator; import java.ut…...
Spark--经典SQL50题
目录 连接数据库准备工作 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数 3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩 4、查询平均成绩…...
数据结构: AVL树
目录 1.AVL树的概念 2.AVL树的模拟实现 AVL树的结构定义 插入 对平衡因子的讨论 旋转 对旋转情况的讨论 1.单旋 1.1左单旋 1.2右单旋 2.双旋 2.1左右双旋 2.2右左双旋 检查是否是AVL树 1.AVL树的概念 当向二叉搜索树中插入新结点后,如果能保证每个结点…...
LeetCode-高频 SQL 50 题:连接 篇
目录 1378. 使用唯一标识码替换员工ID 题目描述: SQL语句: 1068. 产品销售分析 I 题目描述: SQL语句: 1581. 进店却未进行过交易的顾客 题目描述: SQL语句: 197. 上升的温度 题目描述࿱…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
