计算机视觉(本科课程) 北京邮电大学 鲁鹏

article/2025/5/7 10:21:04

计算机视觉 2020 北京邮电大学本科课程

这里的计算机视觉中的数学都是比较简单的,不如图形学

课程部分内容

  • 计算机视觉 2020 北京邮电大学本科课程
    • 1. 卷积与边缘提取
      • 锐化
      • 边缘检测
    • 2. 拟合
      • 最小二乘
      • Robust estimator
      • RANSAC
      • Hough
      • Model selection
    • 3. Harris 角点
    • 4.尺度不变区域与SIFT特征
      • LoG算子 Laplacian of Gaussian
      • SIFT 特征

1. 卷积与边缘提取

卷积的padding方式:

clip filter (black)

wrap around

copy edge

reflect across edge
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

锐化

原图-平滑图=边缘图

原图+边缘图=锐化图

在这里插入图片描述

I * e - I * g = detail

I * e + I*(e-g) = sharpened = I * (2e-g)

detail前方再加一个参数alpha,调节锐化度,最终约等于对原图乘一个拉普拉斯高斯分布

在这里插入图片描述


不用全1的方形滤波,改成圆形的高斯核(中心大四周小)
在这里插入图片描述
在这里插入图片描述

为了让滤波器核有意义,覆盖更多的有值区域,3sigma法则,3倍方差的区域能包含99%的值;so:卷积核的一半长度设置为三倍方差,标准正太sigam=1时,核为7*7

高斯核作用:滤除高频;对一个图像连续高斯两次==一次更大的高斯核卷积


降低卷积运算的复杂度:1)可分离的高斯核:G(x,y) = G(x) * G(y) ;2)两次小卷积代替大卷积


高斯滤波去除高斯噪声,中值滤波(非线性:排序选中止代替周围像素)去除椒盐噪声

边缘检测

确定那些是噪声边,更应该关注什么语义信息

image 看作信号,边缘看作出现了脉冲信号,检测脉冲信号的位置,对信号波形求导,找极值点

搞视觉的方便起见,delta = 1,距离为1的像素之间做差,再除以delta,近似为求导结果
∂ f ( x , y ) ∂ x = lim ⁡ ε → 0 f ( x + ε , y ) − f ( x , y ) ε \frac{\partial f(x, y)}{\partial x}=\lim _{\varepsilon \rightarrow 0} \frac{f(x+\varepsilon, y)-f(x, y)}{\varepsilon} xf(x,y)=ε0limεf(x+ε,y)f(x,y)
应用到图像中:
∂ f ( x , y ) ∂ x ≈ f ( x + 1 , y ) − f ( x , y ) 1 \frac{\partial f(x, y)}{\partial x} \approx \frac{f(x+1, y)-f(x, y)}{1} xf(x,y)1f(x+1,y)f(x,y)
图像求导实现
在这里插入图片描述

用【-1,1】的卷积核对原图操作,即对x方向求导,通常用【-1,0,1】用右边像素-左边像素来衡量我自己

可以求得某一像素的梯度的强度和方向,方向与边缘垂直,强度为勾股弦

其他的卷积核

Prewitt(利用左上左下右上右下像素来近似自己的梯度),

Sobel(卷积核可以分离为两个向量成绩,第一个高斯滤波向量,第二个边缘提取向量,对噪声鲁棒),

Roberts(用斜上方-自己,近似自己的梯度)


噪声对边缘提取有很大影响,一般需要先用一个卷积核去噪,再求梯度

运算速度更快:先对卷积核求梯度,再乘上原图
在这里插入图片描述

高斯核梯度可视化
在这里插入图片描述

回顾

  • 平滑核:高斯滤波去除高频;卷积核总和=1,保证不改变原图的强度
  • 梯度核:有负值;卷积核总和=1,保证平坦区域不会检测出边缘
    在这里插入图片描述

Canny算子

  1. 高斯梯度滤波
  2. 计算梯度强度和方向
  3. 非最大化抑制,细化边缘
  4. 双门限,两头一夹

在这里插入图片描述

边缘检测 可以辅助图像分割

2. 拟合

边缘检测的线无法用数学描述;从问题出发,选择什么拟合算法

最小二乘

可以通过纯矩阵运算求得,缺点:无法拟合垂直的线

在这里插入图片描述


使用全最小二乘,到 ax+by=d 的距离最小,推导略

极大似然估计的角度理解(妙啊)

在这里插入图片描述

假设每一个观测点是由噪声产生的,噪声又符合正态分布,距离所有观测点最近的直线 等价于 所有观测点对应的噪声的概率值都尽可能大(即epsilon–>0, Probability(epsilon)–>max)

所以,采取最大似然估计法。
P ( x 1 , y 1 , … , x n , y n ∣ a , b , d ) = ∏ i = 1 n P ( x i , y i ∣ a , b , d ) ∝ ∏ i = 1 n exp ⁡ ( − ( a x i + b y i − d ) 2 2 σ 2 ) P\left(x_{1}, y_{1}, \ldots, x_{n}, y_{n} \mid a, b, d\right)=\prod_{i=1}^{n} P\left(x_{i}, y_{i} \mid a, b, d\right) \propto \prod_{i=1}^{n} \exp \left(-\frac{\left(a x_{i}+b y_{i}-d\right)^{2}}{2 \sigma^{2}}\right) P(x1,y1,,xn,yna,b,d)=i=1nP(xi,yia,b,d)i=1nexp(2σ2(axi+byid)2)

L ( x 1 , y 1 , … , x n , y n ∣ a , b , d ) = − 1 2 σ 2 ∑ i = 1 n ( a x i + b y i − d ) 2 L\left(x_{1}, y_{1}, \ldots, x_{n}, y_{n} \mid a, b, d\right)=-\frac{1}{2 \sigma^{2}} \sum_{i=1}^{n}\left(a x_{i}+b y_{i}-d\right)^{2} L(x1,y1,,xn,yna,b,d)=2σ21i=1n(axi+byid)2

Robust estimator

鲁棒的最小二乘,超过某一范围的点就不考虑了

原本的最小二乘,添加一个非线性变换

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NxTjs0Zg-1602489327194)(北京邮电大学计算机视觉(本科).assets/image-20201010170002191.png)]

鲁棒估计是非线性优化问题,最小二乘求得的解可用作参数初始化;sigma一般选平均残差的1.5倍

RANSAC

应对比较多的偏离点,需要迭代求解,可用于指纹匹配

Hough

多条线拟合

在这里插入图片描述

可用于汽车检测,训练车轮和车辆中心点的关系,确定每个局部组件的可能方向

测试新车时,首先检测车轮组件,得到方向,找到所有组件的集中的地方,为车的位置

在这里插入图片描述

Model selection

没有数学模型可以刻画,用模型估计,比如snake方法

3. Harris 角点

好的特征点:1)可重复可迁移 2)显著区分性大 3)紧凑 3)局部性

应用:图像对齐拼接,3D重建,动作追踪,物体识别,数据检索

角点:significant change in all directions

Harris 角点检测的过程

  1. 计算窗口内的能量函数

E ( u , v ) = ∑ x , y w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] 2 E(u, v)=\sum_{x, y} w(x, y)[I(x+u, y+v)-I(x, y)]^{2} E(u,v)=x,yw(x,y)[I(x+u,y+v)I(x,y)]2

泰勒展开的原因:简化计算,使E变成与u,v直接关联的函数
E ( u , v ) ≈ E ( 0 , 0 ) + [ u v ] [ E u ( 0 , 0 ) E v ( 0 , 0 ) ] + 1 2 [ u v ] [ E u u ( 0 , 0 ) E u v ( 0 , 0 ) E u v ( 0 , 0 ) E v v ( 0 , 0 ) ] [ u v ] E(u, v) \approx E(0,0)+\left[\begin{array}{ll} u & v \end{array}\right]\left[\begin{array}{l} E_{u}(0,0) \\ E_{v}(0,0) \end{array}\right]+\frac{1}{2}\left[\begin{array}{lll} u & v \end{array}\right]\left[\begin{array}{cc} E_{u u}(0,0) & E_{u v}(0,0) \\ E_{u v}(0,0) & E_{v v}(0,0) \end{array}\right]\left[\begin{array}{l} u \\ v \end{array}\right] E(u,v)E(0,0)+[uv][Eu(0,0)Ev(0,0)]+21[uv][Euu(0,0)Euv(0,0)Euv(0,0)Evv(0,0)][uv]

E u ( u , v ) = ∑ x , y 2 w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] I x ( x + u , y + v ) E u u ( u , v ) = ∑ x , y 2 w ( x , y ) I x ( x + u , y + v ) I x ( x + u , y + v ) + ∑ x , y 2 w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] I x x ( x + u , y + v ) E u v ( u , v ) = ∑ x , y 2 w ( x , y ) I y ( x + u , y + v ) I x ( x + u , y + v ) + ∑ x , y 2 w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] I x y ( x + u , y + v ) \begin{aligned} E_{u}(u, v) &=\sum_{x, y} 2 w(x, y)[I(x+u, y+v)-I(x, y)] I_{x}(x+u, y+v) \\ E_{u u}(u, v) &=\sum_{x, y} 2 w(x, y) I_{x}(x+u, y+v) I_{x}(x+u, y+v)+\sum_{x, y} 2 w(x, y)[I(x+u, y+v)-I(x, y)] I_{x x}(x+u, y+v) \\ E_{u v}(u, v) &=\sum_{x, y} 2 w(x, y) I_{y}(x+u, y+v) I_{x}(x+u, y+v)+\sum_{x, y} 2 w(x, y)[I(x+u, y+v)-I(x, y)] I_{x y}(x+u, y+v) \end{aligned} Eu(u,v)Euu(u,v)Euv(u,v)=x,y2w(x,y)[I(x+u,y+v)I(x,y)]Ix(x+u,y+v)=x,y2w(x,y)Ix(x+u,y+v)Ix(x+u,y+v)+x,y2w(x,y)[I(x+u,y+v)I(x,y)]Ixx(x+u,y+v)=x,y2w(x,y)Iy(x+u,y+v)Ix(x+u,y+v)+x,y2w(x,y)[I(x+u,y+v)I(x,y)]Ixy(x+u,y+v)

带入值

E ( 0 , 0 ) = 0 E u ( 0 , 0 ) = 0 E v ( 0 , 0 ) = 0 \begin{array}{l} E(0,0)=0 \\ E_{u}(0,0)=0 \\ E_{v}(0,0)=0 \end{array} E(0,0)=0Eu(0,0)=0Ev(0,0)=0

E u u ( 0 , 0 ) = ∑ x , y 2 w ( x , y ) I x ( x , y ) I x ( x , y ) E v v ( 0 , 0 ) = ∑ x , y 2 w ( x , y ) I y ( x , y ) I y ( x , y ) E u v ( 0 , 0 ) = ∑ x , y 2 w ( x , y ) I x ( x , y ) I y ( x , y ) \begin{aligned} E_{u u}(0,0) &=\sum_{x, y} 2 w(x, y) I_{x}(x, y) I_{x}(x, y) \\ E_{v v}(0,0) &=\sum_{x, y} 2 w(x, y) I_{y}(x, y) I_{y}(x, y) \\ E_{u v}(0,0) &=\sum_{x, y} 2 w(x, y) I_{x}(x, y) I_{y}(x, y) \end{aligned} Euu(0,0)Evv(0,0)Euv(0,0)=x,y2w(x,y)Ix(x,y)Ix(x,y)=x,y2w(x,y)Iy(x,y)Iy(x,y)=x,y2w(x,y)Ix(x,y)Iy(x,y)

则E简化为

E ( u , v ) ≈ [ u v ] M [ u v ] M = ∑ x , y w ( x , y ) [ I x 2 I x I y I x I y I y 2 ] E(u, v) \approx\left[\begin{array}{lll} u & v \end{array}\right] M\left[\begin{array}{l} u \\ v \end{array}\right] \\ M=\sum_{x, y} w(x, y)\left[\begin{array}{cc} I_{x}^{2} & I_{x} I_{y} \\ I_{x} I_{y} & I_{y}^{2} \end{array}\right] E(u,v)[uv]M[uv]M=x,yw(x,y)[Ix2IxIyIxIyIy2]
其中,E(u, v) 是一个二次方程,可表示成一个二次曲面,E(u,v)取常数值的时候,得到关于u,v的椭圆切面

通过分析M矩阵,就可以知道窗口的能量

分析M矩阵(二阶矩矩阵):

当x,y方向正交时,IxIy=0
M = ∑ x , y w ( x , y ) [ I x 2 I x I y I x I y I y 2 ] = [ λ 1 0 0 λ 2 ] M=\sum_{x, y} w(x, y)\left[\begin{array}{cc} I_{x}^{2} & I_{x} I_{y} \\ I_{x} I_{y} & I_{y}^{2} \end{array}\right]=\left[\begin{array}{cc} \lambda_{1} & 0 \\ 0 & \lambda_{2} \end{array}\right] M=x,yw(x,y)[Ix2IxIyIxIyIy2]=[λ100λ2]
若Iy=0,E=lamda1
u^2,v再怎么变化,E都不变化,于是检测不出v方向;

所以lamda1和lamda2都要较大

E的椭圆切片可视化

在这里插入图片描述

M 矩阵可以分解出旋转矩阵
M = R − 1 [ λ 1 0 0 λ 2 ] R M=R^{-1}\left[\begin{array}{ll} \lambda_{1} & 0 \\ 0 & \lambda_{2} \end{array}\right] R M=R1[λ100λ2]R

在这里插入图片描述

特征值的大小决定了椭圆的长短轴,R决定了椭圆的旋转角度

每一个像素点都可以绘制一个椭圆:

在这里插入图片描述

可以看出,沿着长轴信号变化缓慢(lamda小),沿着短轴信号变化激烈(lamda大)

与旋转矩阵R没啥关系:Harris具有旋转不变性

  1. 计算完窗口的能量函数之后,得到二阶矩矩阵,和其特征值后

    计算 响应值 以判断lamda1 是不是和 lamda2 差不太多

    在这里插入图片描述

    在这里插入图片描述

    作者设计了一个响应函数:
    R = det ⁡ ( M ) − α trace ⁡ ( M ) 2 = λ 1 λ 2 − α ( λ 1 + λ 2 ) 2 R=\operatorname{det}(M)-\alpha \operatorname{trace}(M)^{2}=\lambda_{1} \lambda_{2}-\alpha\left(\lambda_{1}+\lambda_{2}\right)^{2} R=det(M)αtrace(M)2=λ1λ2α(λ1+λ2)2

  2. 每一个像素计算响应值之后,过滤

  3. 最大化抑制


Harris 角点的特性

Invariance 不变性: 图像变换之后,检测到的角点不变

Covariance 协相关不变性:图像变换之后,再叠加变换,又能使得检测到的角点不变

平移,旋转不变性

不具有尺度不变性

Partially invariant to affine intensity change

Corner location is covariant w.r.t translation

Corner location is covariant w.r.t rotation

Corner location is not covariant to scaling

4.尺度不变区域与SIFT特征

LoG算子 Laplacian of Gaussian

边缘提取的时候我们是用高斯(平滑作用)一阶导对原图做卷积,边缘出现在一阶导最大处

在这里插入图片描述

若用高斯二阶导做卷积,边缘出现再二阶导零点处

在这里插入图片描述

但是拉普拉斯响应(原始信号经过拉普拉斯卷积后得到拉普拉斯响应)会随sigma增加而衰弱

在这里插入图片描述

随着方差增加,高斯一阶导的相应衰弱,需要补偿一个sigma

在这里插入图片描述

对应拉普拉斯响应,需要补偿sigma平方

Scale-normalized 后效果

在这里插入图片描述


利用拉普拉斯核找blob区域:

在这里插入图片描述

拉普拉斯响应最大时,blob的半径和方差的关系为
σ = r / 2 \sigma=r / \sqrt{2} σ=r/2

在这里插入图片描述

检测到blob时,image中的黑圈圈和拉普拉斯的黑圈圈刚好对上

小sigma检测小圆圈,大sigma检测大圆圈,

用3个不同的尺度(不同的sigma)对原图卷积,取3个响应最大的那个,以该像素为中心,画一个半径为根号二倍sigma的圈。也是需要非最大化抑制的;

Scale-space blob detector

尺度越大,检测越慢

在这里插入图片描述


应用:

Harris-Laplacian:Harris解决光照,平移,旋转,拉普拉斯解决尺度不变性

SIFT特征:Scale-Invariant Keypoints IJCV 2004

SIFT 特征

DoG算子

DoG算子(高斯核之差)和Laplacian算子(高斯二阶导,补偿sigma平方)大致差一个常数倍;Laplacian算子太慢

在这里插入图片描述

1)尺度空间极值检测:通过使用高斯差分函数来计算并搜索所有尺度上的图像位置,用于识别对尺度和方向不变的潜在兴趣点。

在这里插入图片描述

2)关键点定位:通过一个拟合精细的模型在每个候选位置上确定位置和尺度

它以检测得到的关键点为中心,选择一个16 * 16的邻域,然后再把这个邻域再划分为4 * 4的子区域,然后对梯度方向进行划分成8个区间,这样在每个子区域内就会得到一个4 * 4 * 8=128维的特征向量,向量元素大小为每个梯度方向区间权值。提出得到特征向量后要对邻域的特征向量进行归一化,归一化的方向是计算邻域关键点的主方向,并将邻域旋转至根据主方向旋转至特定方向,这样就使得特征具有旋转不变性。然后再根据邻域内各像素的大小把邻域缩放到指定尺度,进一步使得特征描述子具有尺度不变性

这里写图片描述


http://chatgpt.dhexx.cn/article/U5gmXFbM.shtml

相关文章

助力培养高端复合型AI人才 飞桨首席AI架构师培养计划再启航

5月27日,由深度学习技术及应用国家工程研究中心与百度联合发起创办的AICA首席AI架构师培养计划第六期迎来开学典礼,来自能源、工业制造、金融、交通物流等数十个重点行业领域的105位企业CTO、科学家以及技术高管学员齐聚云端,正式开启首席AI架…

Python与OpenCV(二)——基于背景差分法的运动目标检测程序分析

背景差分法是传统运动目标检测算法中最常用的方法。其基本原理如图所示。 从图中可知,背景差分法是通过建立背景模型,比较当前帧与背景模型对应像素的差异点来检测运动目标的方法。 背景模型的建立主要通过两种方式:一种是选取一帧不含运动目…

大咖Talk丨崔运凯:AI组织的未来——自动驾驶场景下的制胜关键

文章来自亿欧Equal Ocean 2021年12月21日,由亿欧EqualOcean主办的“数字重塑世界-WIM2021世界创新者年会”在中国上海正式开幕。作为此次WIM2021峰会的主要组成部分,“GTM2021全球科技出行论坛”在12月21-22日在上海成功召开。 本次活动由亿欧EqualOcea…

运动目标追踪实现(opencv3)(二)

运动目标的追踪 最近刚开始做目标追踪,理解的还不成熟,博客有错处,欢迎在评论区指出。 有许多博主实现追踪用的卡尔曼方法,具体原理可以看一下这个 :http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/…

计算机竞赛 图像识别-人脸识别与疲劳检测 - python opencv

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是…

人员离岗自动识别系统 基于opencv架构

人员离岗自动识别系统通过opencvyolo网络机器学习模型,对现场人员离岗行为自动识别检测。如果监测到人员离岗立即抓拍预警。YOLO系列神经网络通过合理的设计,成功地将目标检测问题转化为回归问题,因而直接通过网络产生物体的位置和所属类别信…

马腾宇:AI 学界一颗冉冉升起的新星

2020-02-23 17:11 导语:追求long-term impact! 本科毕业于清华姚班,博士毕业于普林斯顿大学,如今年仅31岁的马腾宇,作为 AI 学界的一颗新星正冉冉升起。 马腾宇目前担任斯坦福大学助理教授,其主要研究兴…

c++_opencv的人脸识别起步三训练自己的模型

目录 1、Creating the CSV File2、读取CSV文件函数3、开始训练模型4、程序 1、Creating the CSV File 照片需要在程序中读取它,我决定使用CSV文件读取它。一个CSV文件包含文件名,紧跟一个标签。 /path/to/image.ext;0假设/path/to/image.ext是图像&…

201819101001 张佳兴

@[TOC]九九乘法表 累乘 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,…

OpenCV(五)——运动目标识别

课程一览: 目录 1.摄像头调用 2.视频的读取与保存 3.帧差法 4.光流法 5.背景减除法

Python-中北大学人工智能OpenCV人脸识别(根据图片训练数据,根据训练好的数据识别人脸)

文章目录 1. 根据训练照片训练数据模型2. 根据训练的数据文件,进行人脸识别 1. 根据训练照片训练数据模型 训练流程: 读取文件夹下的所有文件,使用PIL 库中的Image方法打开图片,并将其转化为灰度图片。加载人脸数据分类器&#x…

李腾飞 java_黑马师资团队之【李腾飞老师】

本帖最后由 火影七代目 于 2017-8-4 16:48 编辑 李腾飞老师在北京传智JavaEE就业254期又一次的创新了数据, 这也体现出来飞哥对学员真心的对待和耐心的授课, 看到下面的话语,也是学员对飞哥的恋恋不舍李腾飞老师在254期评分很高,得…

基于openCV的车牌识别(模板匹配)python版

利用提供的模板进行车牌识别: 模板: 测试数据: 整体思路分为3个步骤:①将图像中车牌位置截取出来;②将车牌安照字符进行分割;③对分割好的字符图像进行模板匹配。实验基于jupyter进行,具体代码…

OpenCV-顶帽运算(TOPHAT)

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 原理 形态学是图像处理中常见的名词,图像处理的形态学基本属于数学形态学的范畴,是一门建立在格论和拓扑…

小白都能学会的python+opencv,带你从人脸识别做到车牌识别,成为别人口中赞叹的高手!

一.第一步,对于小白来说,用什么编辑很难选择,怎么下载免费的编辑器也不会,会用电脑下载的又总是被下载许多附带的垃圾软件,这个问题让我来解决,这里我们首先需要安装两个软件以及配置一个pip豆瓣源&#xf…

基于VS与OpenCV的模板匹配学习(2):边缘匹配+图像金字塔

基于VS与OpenCV的模板匹配学习(2) 边缘模板匹配图像金字塔 基于C与OpenCV的模板匹配学习(1)OpenCV matchTemplate()示例 文章目录 基于VS与OpenCV的模板匹配学习(2)边缘模板匹配图像金字塔前言一、边缘检…

Struts2的基本流程的详细介绍

Struts2的基本流程 10级学员 张帅鹏课堂笔记 概述: Struts2框架由三部分构成:核心控制器、业务控制器和用户实现的业务逻辑组件。在这三部分中,struts2框架提供了核心控制器StrutsPrepareAndExecuteFilter,而用户需要实现业务控…

jQuery插件autoComplete介绍(10级学员 张帅鹏总结)

jQuery插件autoComplete介绍 概述:AutoComplete为自动填充,展示之意。用户在使用文本框搜索信息时,使用插件的autoplete方法绑定文本框。当在文本框中输入某个字符时,通过该方法中的指定的数据URL,返回相匹配的数据&a…

C语言 编写Vector方法

Vector是一个单口进出的数组结构有一点像栈的结构。 首先建立这样一个结构体,里面包含一个数组以及一个位置标记,数组来存放进入的元素,标记指向尾部最后一个没有存放东西的数组位置。当然数组元素可以自定义为任何格式,甚至也可…

多组数据的输入方法(c语言实现)

先说方法之前先来浅聊一下scanf 开始进入正题 1.EOF法 EOF(end of file)就是文件的结束&#xff0c;通常来判断文件的操作是否结束的标志。 EOF不是特殊字符&#xff0c;而是定义在头文件<stdio.h>的常量&#xff0c;等于-1&#xff1b; 就如牛客网上的一道题为例&…