基于opencv答题卡识别判卷
我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万+粉丝,拥有2篇国家级人工智能发明专利。
社区特色:深度实战算法创新
获取全部完整项目数据集、代码、视频教程,请进入官网:zzgcz.com。竞赛/论文/毕设项目辅导答疑,v:zzgcz_com
1. 项目简介
本项目旨在开发一种自动化的试卷判分系统,通过图像处理技术对试卷中的多选题答案进行识别和评分。该项目采用了基于OpenCV的图像处理方法和深度学习模型,主要用于识别扫描图像中的试卷内容,提取考生的作答区域,并根据预设的正确答案进行自动评分。项目的核心技术包括边缘检测、轮廓识别、透视变换和Otsu阈值分割等。通过一系列图像处理操作,将输入的试卷图片转化为标准化的矩形结构,并根据候选区域的轮廓特征确定每道题目的答案。该项目的应用场景包括教育评估、考试系统自动化和作业批改等。最终实现了通过图像识别对多选题进行准确评分,极大提高了试卷批改的效率和准确性。
2.技术创新点摘要
本项目的主要创新点在于结合经典的图像处理技术与深度学习思想,实现了自动化试卷判分系统的准确答案识别和评分。项目中采用了一系列图像处理方法,包括边缘检测、透视变换、轮廓分析和Otsu阈值分割,这些技术相互配合,在无训练数据的情况下实现了对目标区域(试卷答案区)的精确定位和特征提取。此外,该系统通过对轮廓的几何特征进行分析和排序来定位每个答案的候选区域,并结合自定义规则(例如宽高比和面积等几何特征)过滤噪声区域,从而保证了答案提取的准确性和稳定性。
在答案识别部分,项目中采用了一个基于轮廓面积的局部特征提取方法,通过对每个选项区域的非零像素点数量进行统计,并使用最大值策略选择出考生最有可能的答案。这种方法的优势在于能够适应不同类型的扫描图像和字体大小变化,同时消除了因图像光照或模糊导致的噪声干扰。该项目还集成了自定义的答案映射表,通过与预设的答案键进行比对,实现了快速评分。
整体架构设计的亮点在于,通过图像预处理和深度学习思路的结合,实现了图像中复杂目标的精确识别和分类。在技术细节上,系统的创新体现在以下几个方面:1) 通过多种图像变换(如透视变换)将任意角度的试卷图像进行标准化处理,从而避免了输入图像角度不一致导致的定位误差;2) 通过Otsu阈值法实现了自适应的答案区分割策略,使得系统能在不同光照条件下保持较高的分割精度;3) 利用局部轮廓排序方法和面积分析准确定位每道题目答案,并结合深度学习框架中的卷积思想,通过逐像素计算非零值的分布特征,最终实现了高效的答案匹配与评分。该系统能够大幅提升传统考试批改工作的效率和准确度,是对传统试卷处理方式的有效改进。
3. 数据集与预处理
本项目主要处理的是扫描的试卷图像数据集,数据集的来源可以是扫描的纸质试卷或拍摄的电子试卷图像。这类数据集通常具有以下特点:图像分辨率和质量不一致、拍摄角度存在偏差、不同光照条件下可能出现局部阴影或模糊等问题。因此,在数据处理过程中,需要针对这些问题进行相应的图像预处理操作,以确保答案区域的提取和答案识别的准确性。
数据预处理流程:
- 图像读取与灰度化:首先将输入的彩色图像转换为灰度图,这一步骤能够有效降低计算复杂度,并消除颜色信息的干扰,使得后续的边缘检测更加稳定。
- 图像平滑与去噪:使用高斯模糊对图像进行平滑处理,减少图像中因噪声造成的误差。通过设置合适的滤波器大小,可以在保留主要轮廓特征的同时消除图像中的小噪声点。
- 边缘检测:采用Canny边缘检测算法提取图像中的明显边缘,便于后续轮廓的定位与提取。边缘检测能够帮助定位试卷区域以及答案区域的轮廓特征。
- 轮廓检测与排序:在检测到的边缘图中提取所有可能的轮廓,并通过轮廓面积和形状特征(如长宽比和位置)对答案区域进行排序和筛选。最终将包含候选答案的区域筛选出来,并按指定顺序排列,确保后续答案识别时不发生错位。
- 透视变换与图像矫正:为了消除图像拍摄角度和试卷摆放角度对答案定位的影响,使用透视变换将不规则的图像转换为标准的矩形图像。透视变换能够矫正图像中的倾斜角度,使试卷区域与参考答案的匹配更加精准。
- 二值化处理:使用Otsu自适应阈值分割法对矫正后的图像进行二值化处理,进一步提升答案区域的清晰度,确保在复杂光照条件下仍然能够分割出有效的答案区域。
4. 模型架构
1) 模型结构的逻辑
该项目的代码主要基于图像处理算法来完成答案识别与评分,而不是传统的深度学习模型。因此,并没有标准的神经网络层结构,但在图像处理的各个步骤中,包含了许多数学模型和算法逻辑。以下是主要的模型逻辑描述及其数学公式:
- 图像灰度化 (Grayscale Conversion) : 使用OpenCV中的
cv2.cvtColor
函数将彩色图像转换为灰度图像。数学上,每个像素点的灰度值可以表示为: - G r a y = 0.299 × R + 0.587 × G + 0.114 × B Gray = 0.299 \times R + 0.587 \times G + 0.114 \times B Gray=0.299×R+0.587×G+0.114×B
- 其中,R,G,B 分别表示红、绿、蓝通道的值。
- 图像平滑与高斯模糊 (Gaussian Blurring) : 使用高斯模糊处理来降低噪声并平滑图像,采用
cv2.GaussianBlur
。高斯模糊的数学表示为: - G ( x , y ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G(x, y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} G(x,y)=2πσ21e−2σ2x2+y2
- 其中,σ 为高斯函数的标准差。
- Canny边缘检测 (Canny Edge Detection) : 用于提取图像的边缘,通过计算图像的梯度变化来检测边缘。其数学表示为:
- G = G x 2 + G y 2 G = \sqrt{G_x^2 + G_y^2} G=Gx2+Gy2
- 其中,Gx 和 Gy 分别表示图像在 x 和 y 方向的梯度值。
- 透视变换与矩阵映射 (Perspective Transform) : 使用四点透视变换将图像转换为标准矩形。映射矩阵 MMM 的计算公式为:
- [ x ′ y ′ 1 ] = M × [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = M \times \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} x′y′1 =M× xy1
- 其中,M 是基于输入坐标和输出坐标计算的3x3矩阵,[x,y,1] 为输入坐标,[x′,y′,1] 为输出坐标。
- Otsu自适应阈值分割 (Otsu’s Binarization) : 使用Otsu方法计算最佳的全局阈值,以最小化类间方差。目标是找到一个阈值 ttt 使得图像的类内方差最小:
- σ w 2 ( t ) = q 1 ( t ) σ 1 2 ( t ) + q 2 ( t ) σ 2 2 ( t ) \sigma^2_w(t) = q_1(t)\sigma^2_1(t) + q_2(t)\sigma^2_2(t) σw2(t)=q1(t)σ12(t)+q2(t)σ22(t)
- 其中,q1 和 q2 是两类像素点的概率分布,σ12 和 σ22 是两类的方差。
2) 模型的整体训练流程
虽然本项目没有传统的深度学习训练流程,但可以将其看作一个基于图像处理的“训练”过程,其中包含以下步骤:
- 数据准备:项目使用输入的扫描图像作为数据源,并且不需要进行复杂的数据预处理(如数据增强、归一化等),只需对输入的图像进行灰度化和边缘检测处理。
- 特征提取与处理:通过轮廓检测和透视变换,将试卷中每个多选题的答案区域定位并提取出来。特征提取过程中,主要使用几何特征(轮廓面积、宽高比、位置)来判断是否属于有效的候选区域。
- 答案匹配与评分:使用非零像素统计法对每个答案区域进行特征提取,并与预设的答案进行比对。在答案比对过程中,使用了如下判别逻辑:
s c o r e = 正确答案数 总题目数 × 100 score = \frac{\text{正确答案数}}{\text{总题目数}} \times 100 score=总题目数正确答案数×100
这里,正确答案数是通过与预设答案进行逐个比对得到的。
- 模型评估与指标:本项目的核心评估指标是“答案识别准确率”,通过下述公式计算:
准确率 = 正确识别的答案个数 所有识别的答案总数 \text{准确率} = \frac{\text{正确识别的答案个数}}{\text{所有识别的答案总数}} 准确率=所有识别的答案总数正确识别的答案个数
本项目的目标是将识别准确率提升到接近100%,确保每个扫描图像都能够被精准判分。
整体来看,本项目通过图像处理技术(而非传统深度学习模型)完成了试卷答案的识别、定位与评分,并且引入了透视变换、Otsu自适应阈值等多种处理策略来提升系统在不同环境下的鲁棒性与准确性。
5. 核心代码详细讲解
1. 读取输入图像并进行灰度化和边缘检测
# 读取输入图像并生成副本
image = cv2.imread(args["image"])
contours_img = image.copy()
# 将图像转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imread(args["image"])
: 从指定路径读取输入图像文件,并以彩色图像格式加载。contours_img = image.copy()
: 创建一个图像副本,用于后续画出轮廓时使用,避免修改原始图像。cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
: 将原始彩色图像转换为灰度图像,减少颜色信息的干扰,同时降低计算复杂度。
# 进行高斯模糊处理,减少噪声
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
cv2.GaussianBlur(gray, (5, 5), 0)
: 应用5x5大小的高斯模糊滤波器来平滑图像,以去除小的噪声点,使得后续边缘检测更加稳定。参数(5, 5)
表示高斯核的大小,0
表示根据内置算法自适应地计算标准差。
# 使用Canny边缘检测,提取图像的边缘
edged = cv2.Canny(blurred, 75, 200)
cv2.Canny(blurred, 75, 200)
: 使用Canny算法提取图像边缘。Canny算法采用了双阈值方法,75
是最小阈值,200
是最大阈值。这一步能够提取出图像中的显著边缘,便于轮廓的检测和定位。
2. 检测并排序轮廓
# 使用findContours函数检测图像中所有的轮廓
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
# 在图像中绘制所有轮廓
cv2.drawContours(contours_img, cnts, -1, (0, 0, 255), 3)
cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
: 识别二值化图像中的轮廓。参数cv2.RETR_EXTERNAL
仅检测外部轮廓,cv2.CHAIN_APPROX_SIMPLE
使用点近似算法来减少存储每个轮廓点的数量。cv2.drawContours(contours_img, cnts, -1, (0, 0, 255), 3)
: 在图像副本中绘制所有检测到的轮廓,-1
表示绘制所有轮廓,颜色为红色(0, 0, 255)
,线条宽度为3
像素。
3. 透视变换与图像矫正
# 执行透视变换以获取标准化的试卷区域
warped = four_point_transform(gray, docCnt.reshape(4, 2))
four_point_transform(gray, docCnt.reshape(4, 2))
: 调用自定义函数four_point_transform
,通过将轮廓点映射到标准矩形坐标系中,矫正图像角度,消除图像拍摄角度不一致带来的误差。
def four_point_transform(image, pts):# 按顺序排列输入的4个顶点坐标rect = order_points(pts)(tl, tr, br, bl) = rect...# 计算透视变换矩阵,并对图像进行变换M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warped
order_points(pts)
: 先对输入的四个顶点进行排序,确保四个角点分别对应左上、右上、右下和左下。cv2.getPerspectiveTransform(rect, dst)
: 计算透视变换矩阵M
,根据输入顶点和目标顶点位置进行图像变换。cv2.warpPerspective(image, M, (maxWidth, maxHeight))
: 执行透视变换,将原图像变换为矩形的标准形态。
4. 二值化处理和答案识别
# 对矫正后的图像进行二值化处理,区分背景与前景
thresh = cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
: 使用Otsu阈值法进行二值化处理,将图像分为前景(白色)和背景(黑色)。cv2.THRESH_BINARY_INV
表示使用二值反转(即前景为白色时显示为黑色)。
# 检测并筛选出可能的答案圆圈轮廓
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
- 再次使用
cv2.findContours
检测二值化图像中的圆圈轮廓,并按比例和大小特征进行筛选,确定为有效的候选答案区域。
5. 选项识别与答案评分
# 对每个题目的候选区域进行特征提取,并进行答案比对for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):# 按从左到右顺序对候选区域进行排序cnts = sort_contours(questionCnts[i:i + 5])[0]bubbled = Nonefor (j, c) in enumerate(cnts):# 创建掩码图像,仅保留当前轮廓mask = np.zeros(thresh.shape, dtype="uint8")cv2.drawContours(mask, [c], -1, 255, -1)# 计算掩码区域的非零像素数量total = cv2.countNonZero(mask)if bubbled is None or total > bubbled[0]:bubbled = (total, j)
mask = np.zeros(thresh.shape, dtype="uint8")
: 创建一个与原图同大小的全黑掩码图像。cv2.drawContours(mask, [c], -1, 255, -1)
: 在掩码图像上填充当前轮廓区域,使其为白色(前景)。cv2.countNonZero(mask)
: 统计当前掩码图像中非零像素点的数量,判断考生在该选项处是否涂黑。
6. 模型优缺点评价
该项目的模型优势在于基于图像处理的非深度学习方法,通过经典的边缘检测、轮廓分析、透视变换和Otsu阈值等图像处理技术,在无训练数据的情况下实现了高效的答案区域提取和答案判别。该方法的优点主要体现在以下几个方面:1) 计算效率高:与深度学习模型相比,不需要大量计算资源即可完成多选题答案识别。2) 鲁棒性好:在不同图像分辨率、拍摄角度和光照条件下,经过预处理后的图像仍然能够稳定识别答案区域。3) 实现简单:不需要复杂的模型训练流程和大规模数据集,易于部署和维护。
然而,该模型也存在一定局限性:1) 无法处理复杂背景或噪声严重的图像:依赖于图像的清晰边缘和稳定的轮廓特征,当图像质量较差时(如模糊、强光反射、角度偏差过大),识别效果可能不理想。2) 缺乏通用性:仅能处理预定义格式的标准化试卷,对于其他类型的文档(如含有文本、表格等)适用性较差。3) 灵活性不足:无法动态适应答案区域位置变化(如多选题的题目数量和选项数量不同)。
改进方向:1) 引入深度学习模型:可以考虑使用深度学习的目标检测模型(如YOLO或Faster R-CNN)来替代传统的轮廓检测,从而提高复杂背景下的答案区域定位能力。2) 加入数据增强:在图像预处理时使用数据增强策略(如随机旋转、裁剪、噪声注入等),提高模型在不同拍摄条件下的鲁棒性。3) 优化透视变换算法:加入更复杂的几何校正方法,以适应更多种类的拍摄角度和变形情况,进一步提升模型的稳定性与识别精度。
↓↓↓更多热门推荐:
钢板表面缺陷检测基于HRNET模型
基于opencv的人脸闭眼识别疲劳监测
全部项目数据集、代码、教程进入官网zzgcz.com
相关文章:

基于opencv答题卡识别判卷
我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝,拥有2篇国家级人工智能发明专利。 社区特色:深度实…...

ShardingSphere分库分表产品介绍
目录 一、ShardingSphere分库分表产品介绍 二、客户端分库分表与服务端分库分表 1、ShardingJDBC客户端分库分表 2、ShardingProxy服务端分库分表 3、ShardingSphere混合部署架构 三、分库分表,能不分就不分! 1、为什么要分库分表? 2、…...
Java经典面试题-多线程打印
threadsynchronized 就好像一个圆圈,A->B->C->A。。。。。 synchronized能够保证多个线程进入实,只用一个线程能进入。 /**多线程交替打印* */ public class Task {private final Object lock new Object();private int count 0;public st…...

FireFox简单设置设置
文章目录 一 设置不显示标签页1原来的样子2新的样子3操作方法 二 设置竖直标签页栏1 效果图2 设置方法 三 设置firefox不提醒更新 一 设置不显示标签页 1原来的样子 2新的样子 3操作方法 地址栏输入 about:config搜索icon,双击选项列表中browserchrome.site icons的值&#…...

Sollong手机——一站式Web3生态解决方案
从定义上讲,Web3公司也属于互联网公司,不过与传统互联网公司相比,他们有一个很明显的特征:他们不断尝试做去中心化的事,一步步将数据和金融的控制权从美联储(央行和金融机构)、苹果(…...
《重生到现代之从零开始的数据结构生活》—— 顺序表1
线性表 线性表:是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使 ⽤的 数据结构,常⻅的线性表有顺序表、链表、栈、队列、字符串等等 线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连…...

2本书让你轻松入门大模型!《大模型入门:技术原理与实战应用》+《自然语言处理:大模型理论与实践》
随着大模型技术的不断完善和普及,我们将进入一个由数据驱动、智能辅助的全新工作模式和生活模式。个人和企业将能够利用大模型来降本增效,并创造全新的用户体验。 人工智能是人类探索未来的重要领域之一,以GPT为代表的大模型应用一经推出在短…...
【JDK17 | 1】Java 17 深入剖析:新特性与变革
引言 Java 17 是 Oracle 发布的一个重要版本,它不仅是一个长期支持(LTS)版本,还引入了许多新的特性和改进,为开发者提供了更强大的工具和更优雅的编程体验。在本专栏的文章中,我们将对 Java 17 的新特性进行深入剖析,帮助开发者更好地理解和利用这一版本。 1. 新特性概述…...
strtok
strtok函数原型 char *strtok(conset char *str,conset char *dst); 功能: 将字符串分割成一个一个片段 当strtok()在参数str的字符串中发现参数dst中包含的分割字符时,则会将该字符改为\0字符 当连续出现…...
零信任身份安全的基本原则
零信任身份安全的核心原则就是 “持续验证,永不信任”。可以通过以下6个方面理解: 对“谁”和“什么”进行认证和授权 在零信任身份安全模型中,对用户和设备的身份进行认证和授权是至关重要的。认证是确认用户或设备是其所宣称的身份的过程…...

【AAOS】Android Automotive 9模拟器源码下载及编译
源码下载 repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r61 repo sync -c --no-tags --no-clone-bundle 源码编译 source build/envsetup.sh lunch aosp_car_x86_64-userdebug make -j8 运行效果 emulator Home界面 MAP All apps S…...

手动降级wsl中的numpy
下载完pytorch之后想验证一下cuda好不好使,在测试的时候发现一个warning python中报错如下 我下载的pytorch版本比较低,numpy太高,所以需要手动给numpy降级 pip install numpy\<2 降级后再进到python验证cuda就没有warning和报错了&…...

极客兔兔Gee-Cache Day7
protobuf配置: 从 Protobuf Releases 下载最先版本的发布包安装。解压后将解压路径下的 bin 目录 加入到环境变量即可。 如果能正常显示版本,则表示安装成功。 $ protoc --version libprotoc 3.11.2在Golang中使用protobuf,还需要protoc-g…...

R包:APAlyzer从RNA-seq数据计算APA表达丰度
文章目录 介绍教程实战案例数据脚本运行 介绍 今天安利APAlyzer工具,它是通过RNA-seq数据获取3′UTR APA, intronic APA等表达谱的R包。 APAlyzer将bam文件比对到PolyA-DB数据库识别APA。 Most eukaryotic genes produce alternative polyadenylation (APA) isofo…...

YOLOv11改进策略【损失函数篇】| 利用MPDIoU,加强边界框回归的准确性
一、背景 目标检测和实例分割中的关键问题: 现有的大多数边界框回归损失函数在不同的预测结果下可能具有相同的值,这降低了边界框回归的收敛速度和准确性。 现有损失函数的不足: 现有的基于 ℓ n \ell_n ℓn范数的损失函数简单但对各种尺度…...

dayu_widgets-简介
前言: 越来越多的人开始使用python来做GUI程序,市面上却很少有好的UI控件。即使有也是走的商业收费协议,不敢使用,一个不小心就收到法律传票。 一、原始开源项目: 偶然在GitHub上发现了这个博主的开源项目。https://github.com/phenom-films…...
改变数组页面重新渲染的操作/那些操作不会重新渲染页面以及解决方法
在前端开发中,当数组数据发生变化时,是否会导致页面重新渲染,以及如何进行相关操作,这取决于使用的具体框架或库(如React、Vue等)及其内部机制。以下是对这一问题的详细解答: 一、会导致页面重…...
米哈游Android面试题汇总及参考答案
Java 的内存回收机制是如何工作的? 在 Java 中,内存回收主要由垃圾回收器(Garbage Collector)来完成。 Java 的内存主要分为堆(Heap)和栈(Stack)等区域。其中,对象主要分配在堆上。当创建一个对象时,会在堆上为其分配内存空间。 垃圾回收器主要负责回收不再被使用的对…...

搜维尔科技:【应用】Xsens动作捕捉技术为奇幻电影注入活力
在英格兰古朴的小镇和连绵起伏的群山之间,坐落着一个虚构的小镇Anghenfil,在这里有一个早已被人遗忘的传说。在这部由英国电影制片人Ryan Garry自编自导的奇幻电影《Every Legend Ends》中,这个传说即将变成可怕的现实。 怪物苏醒&#…...
useradd命令:添加Linux新用户
一、命令简介 useradd 命令用于在 Linux 系统中创建新用户账号。 二、命令参数 useradd [选项] 用户名一些常用的选项包括: -c, --comment "Comment" : 为用户账号添加注释信息。-m, --create-home: 创建用户的家目录。-s, --shell /path/to/…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...

Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...