OpenCv高阶(8.0)——答题卡识别自动判分
文章目录
- 前言
- 一、代码分析及流程讲解
- (一)初始化模块
- 正确答案映射字典(题目序号: 正确选项索引)
- 图像显示工具函数
- (二)轮廓处理工具模块
- (三)几何变换核心模块
- 二、主处理流程
- 图像读取
- >>> 阶段1:图像预处理 <<<
- 1、灰度转换(注意:COLOR_BGRA2GRAY适用于含alpha通道图像,通常使用COLOR_BGR2GRAY)
- 2、高斯滤波(5x5卷积核去噪)
- 3、Canny边缘检测(双阈值设置)
- >>> 阶段2:答题卡定位 <<<
- 1、轮廓检测(仅检测最外层轮廓)
- 2、绘制所有轮廓(红色,3px线宽)
- 3、轮廓筛选(按面积降序排列)
- 4、执行透视变换
- >>> 阶段3:选项识别 <<<
- 1、灰度转换与二值化
- 2、自适应阈值处理(反色二值化+OTSU算法)
- 3、选项轮廓检测
- 4、绘制绿色轮廓(1px线宽)
- 5、选项筛选条件(宽高>20px,宽高比0.9-1.1)
- 6、轮廓排序(从上到下)
- >>> 阶段4:评分系统 <<<
- 1、遍历每道题(每5个选项为一题)
- 2、分数计算与显示
- 3、在图像左上角添加红色分数文本
- 4、结果展示
- 总结
前言
一、代码分析及流程讲解
(一)初始化模块
import numpy as np
import cv2
import os
正确答案映射字典(题目序号: 正确选项索引)
ANSWER_KEY = {0:1, 1:4, 2:0, 3:3, 4:1}
图像显示工具函数
def cv_show(name, value):"""可视化显示图像,按任意键继续"""cv2.imshow(name, value)cv2.waitKey(0)
(二)轮廓处理工具模块
轮廓定向排序函数
参数:
cnts: 轮廓列表
method: 排序方向(left-to-right/right-to-left/top-to-bottom/bottom-to-top)
返回值:
排序后的轮廓及边界框
def sort_contours(cnts, method='left-to-right'):reverse = Falsei = 0if method == 'right-to-left' or method == 'bottom-to-top':reverse = Trueif method == 'top-to-bottom' or method == 'bottom-to-top':i = 1# 获取轮廓边界框并排序boundingBoxes = [cv2.boundingRect(c) for c in cnts](cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))return cnts, boundingBoxes
保持宽高比的图像缩放函数
参数:
width: 目标宽度
height: 目标高度
inter: 插值方法
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))return cv2.resize(image, dim, interpolation=inter)
(三)几何变换核心模块
坐标点规范化排序(左上、右上、右下、左下)
实现方法:
1. 计算各点坐标和,最小值为左上,最大值为右下
2. 计算坐标差值,最小值为右上,最大值为左下
def order_points(pts):rect = np.zeros((4, 2), dtype='float32')s = pts.sum(axis=1)rect[0] = pts[np.argmin(s)] # 左上点rect[2] = pts[np.argmax(s)] # 右下点diff = np.diff(pts, axis=1)rect[1] = pts[np.argmin(diff)] # 右上点rect[3] = pts[np.argmax(diff)] # 左下点return rect
透视变换函数
参数:
image: 原始图像
pts: 源图像四个坐标点
处理流程: 1. 坐标点规范化排序。2. 计算变换后图像尺寸。 3. 生成透视变换矩阵。 4. 执行透视变换
def four_point_transform(image, pts):rect = order_points(pts)(tl, tr, br, bl) = rect# 计算目标图像尺寸(取最大宽高)widthA = np.sqrt(((br[0]-bl[0])**2) + (br[1]-bl[1])**2)widthB = np.sqrt(((tr[0]-tl[0])**2) + (tr[1]-tl[1])**2)maxWidth = max(int(widthA), int(widthB))heightA = np.sqrt(((tr[0]-br[0])**2) + (tr[1]-br[1])**2)heightB = np.sqrt(((tl[0]-bl[0])**2) + (tl[1]-bl[1])**2)maxHeight = max(int(heightA), int(heightB))# 构建目标坐标矩阵dst = np.array([[0, 0],[maxWidth-1, 0],[maxWidth-1, maxHeight-1],[0, maxHeight-1]], dtype="float32")# 执行透视变换M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warped
二、主处理流程
图像读取
image = cv2.imread('../data/images/test_01.png')
contours_img = image.copy()
>>> 阶段1:图像预处理 <<<
1、灰度转换(注意:COLOR_BGRA2GRAY适用于含alpha通道图像,通常使用COLOR_BGR2GRAY)
gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
2、高斯滤波(5x5卷积核去噪)
blurred = cv2.GaussianBlur(gray, (5,5), 0)
cv_show('blurred', blurred)
3、Canny边缘检测(双阈值设置)
edged = cv2.Canny(blurred, 75, 200)
cv_show('edged', edged)
>>> 阶段2:答题卡定位 <<<
1、轮廓检测(仅检测最外层轮廓)
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
2、绘制所有轮廓(红色,3px线宽)
cv2.drawContours(contours_img, cnts, -1, (0,0,255), 3)
cv_show('contours_img', contours_img)
3、轮廓筛选(按面积降序排列)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
for c in cnts:# 多边形近似(精度=2%周长)peri = cv2.arcLength(c, True)approx = cv2.approxPolyDP(c, 0.02*peri, True)if len(approx) == 4: # 识别四边形轮廓doCnt = approxbreak
4、执行透视变换
warped_t = four_point_transform(image, doCnt.reshape(4, 2))
warped_new = warped_t.copy()
cv_show('warped', warped_t)
>>> 阶段3:选项识别 <<<
1、灰度转换与二值化
warped_gray = cv2.cvtColor(warped_t, cv2.COLOR_BGRA2GRAY)
2、自适应阈值处理(反色二值化+OTSU算法)
thresh = cv2.threshold(warped_gray, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cv_show('thresh', thresh)
3、选项轮廓检测
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
4、绘制绿色轮廓(1px线宽)
warped_contours = cv2.drawContours(warped_t.copy(), cnts, -1, (0,255,0), 1)
cv_show('warped_contours', warped_contours)
5、选项筛选条件(宽高>20px,宽高比0.9-1.1)
questionCnts = []
for c in cnts:(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)if w >= 20 and h >= 20 and 0.9 <= ar <= 1.1:questionCnts.append(c)
6、轮廓排序(从上到下)
questionCnts = sort_contours(questionCnts, method="top-to-bottom")[0]
>>> 阶段4:评分系统 <<<
correct = 0
1、遍历每道题(每5个选项为一题)
for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):# 当前题目选项排序(左到右)cnts = sort_contours(questionCnts[i:i+5])[0]bubbled = None# 遍历每个选项for (j, c) in enumerate(cnts):# 创建选项掩膜mask = np.zeros(thresh.shape, dtype="uint8")cv_show('mask',mask)cv2.drawContours(mask, [c], -1, 255, -1) # 填充式绘制# 应用掩膜统计像素thresh_mask_and = cv2.bitwise_and(thresh, thresh, mask=mask)cv_show('thresh_mask_and',thresh_mask_and)total = cv2.countNonZero(thresh_mask)# 记录最大填涂区域if bubbled is None or total > bubbled[0]:bubbled = (total, j)# 答案比对color = (0, 0, 255) # 默认红色(错误)k = ANSWER_KEY[q]if k == bubbled[1]:color = (0, 255, 0) # 绿色(正确)correct += 1# 绘制结果轮廓cv2.drawContours(warped_new, [cnts[k]], -1, color, 3)
通过掩膜的方法依次遍历每个选项。
2、分数计算与显示
score = (correct / 5.0) * 100
print("[INFO] score: {:.2f}%".format(score))
3、在图像左上角添加红色分数文本
cv2.putText(warped_new, "{:.2f}%".format(score), (10, 20),cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
4、结果展示
cv_show('Original', image) # 显示原始图像
cv_show("Exas", warped_new) # 显示评分结果
cv2.waitKey(0) # 等待退出
总结
完整代码展示
import numpy as np
import cv2
import osANSWER_KEY={0:1,1:4,2:0,3:3,4:1}def cv_show(name,value):cv2.imshow(name,value)cv2.waitKey(0)def sort_contours(cnts,method='left-to-right'):reverse=Falsei=0if method=='right-to-left' or method=='bottom-to-top':reverse=Trueif method=='top-to-bottom' or method=='bottom-to-top':i=1boundingBoxes=[cv2.boundingRect(c) for c in cnts](cnts,boundingBoxes)=zip(*sorted(zip(cnts,boundingBoxes),key=lambda b:b[1][i],reverse=reverse))return cnts,boundingBoxesdef resize(image,width=None,height=None,inter=cv2.INTER_AREA):dim=None(h,w)=image.shape[:2]if width is None and height is None:return imageif width is None:r=height/float(h)dim=(int(w*r),height)else:r=width/float(w)dim=(width,int(h*r))resized=cv2.resize(image,dim,interpolation=inter)return resizeddef order_points(pts):#一共四个坐标点rect=np.zeros((4,2),dtype='float32')#按顺序找到对应的坐标0123,分别是左上右上右下、左下s=pts.sum(axis=1) #对矩阵的每一行进行求和操作rect[0]=pts[np.argmin(s)]rect[2]=pts[np.argmax(s)]diff=np.diff(pts,axis=1)rect[1]=pts[np.argmin(diff)]rect[3]=pts[np.argmax(diff)]return rectdef four_point_transform(image,pts):#获取输入的坐标点rect=order_points(pts)(tl,tr,br,bl)=rect#计算输入的w和h值widthA=np.sqrt(((br[0]-bl[0])**2) +( br[1] - bl[1])**2)widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + (tr[1] - tl[1]) ** 2)maxwidth=max(int(widthA),int(widthB))heightA=np.sqrt(((tr[0]-br[0])**2) +( tr[1] - br[1])**2)heightB=np.sqrt(((tl[0]-bl[0])**2) +( tl[1] - bl[1])**2)maxheight=max(int(heightA),int(heightB))dst=np.array([[0,0],[maxwidth,0],[maxwidth,maxheight],[0,maxheight]],dtype='float32')M=cv2.getPerspectiveTransform(rect,dst)warped=cv2.warpPerspective(image,M,(maxwidth,maxheight))return warped#预处理
image=cv2.imread('../data/images/test_01.png')
contours_img=image.copy()"灰度处理、做高斯滤波、边缘检测"
gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
blurred = cv2.GaussianBlur(gray,(5,5),0)
cv_show('blurred',blurred)
edged = cv2.Canny(blurred, 75, 200)
cv_show('edged',edged)#轮廓检测
cnts=cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
cv2.drawContours(contours_img,cnts,-1,(0,0,255),3)
cv_show('contours_img',contours_img)
doCnt=None#根据轮廓大小进行排序,准备透视变换
cnts=sorted(cnts,key=cv2.contourArea,reverse=True)
for c in cnts:peri=cv2.arcLength(c,True)approx=cv2.approxPolyDP(c,0.02*peri,True)if len(approx)==4:doCnt=approxbreak#执行透视变换
warped_t=four_point_transform(image,doCnt.reshape(4,2))
warped_new=warped_t.copy()
cv_show('warped',warped_t)
warped=cv2.cvtColor(warped_t,cv2.COLOR_BGRA2GRAY)#阈值处理
thresh=cv2.threshold(warped,0,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cv_show('thresh',thresh)
thresh_contours=thresh.copy()cnts=cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
warped_contours=cv2.drawContours(warped_t,cnts,-1,(0,255,0),1)
cv_show('warped_contours',warped_contours)questionCnts=[]
for c in cnts:(x,y,w,h)=cv2.boundingRect(c)ar=w/float(h)#根据实际情况指定标准if w>20 and h >20 and 0.9<ar<=1.1:questionCnts.append(c)#按照从上到下的顺序排序
questionCnts=sort_contours(questionCnts,method="top-to-bottom")[0]
correct=0 #计算正确率#依次取出每行的数据
for (q,i) in enumerate(np.arange(0,len(questionCnts),5)):cnts=sort_contours(questionCnts[i:i+5])[0]bubbled=None#遍历每一个结果for (j,c) in enumerate(cnts):mask=np.zeros(thresh.shape,dtype='uint8')cv2.drawContours(mask,[c],-1,255,-1)#-1代表填充cv_show('mask',mask)thresh_mask_and=cv2.bitwise_and(thresh,thresh,mask=mask)cv_show('thresh_mask_and',thresh_mask_and)total=cv2.countNonZero(thresh_mask_and)if bubbled is None or total>bubbled[0]:bubbled=(total,j)color=(0,0,255)k=ANSWER_KEY[q]if k==bubbled[1]:color=(0,255,0)correct+=1cv2.drawContours(warped_new,[cnts[k]],-1,color,3)cv_show('warped',warped_new)score=(correct/5.0)*100
print("[INFO] score:{:.2f}%".format(score))
cv2.putText(warped_new,"{:.2f}%".format(score),(10,20),cv2.FONT_HERSHEY_SIMPLEX,0.9,(0,0,255),2)cv_show('Oringinal',image)
cv_show("Exas",warped_new)
cv2.waitKey(0)
该代码通过经典的OpenCV图像处理技术,构建了一个完整的答题卡自动评分系统,展现了计算机视觉在自动化领域的典型应用。其模块化设计、清晰的代码结构和可调参数,为二次开发提供了良好的基础,具备较高的实用价值和扩展潜力。
相关文章:

OpenCv高阶(8.0)——答题卡识别自动判分
文章目录 前言一、代码分析及流程讲解(一)初始化模块正确答案映射字典(题目序号: 正确选项索引)图像显示工具函数 (二)轮廓处理工具模块(三)几何变换核心模块 二、主处理流程图像读取…...

Python语法特点与编码规范
注释 单行注释 把#号当做注释符号 多行注释 python中并没有规定多行注释标记,通常使用单引号作为多行注释 中文注释 规定文件所用编码,当时是为解决python2不支持中文的问题 #codingutf-8代码缩进 python采用代码缩进和冒号区分代码层次,…...

反本能---如何对抗你的习以为常
目录 一、概述 二、自我提升 (一)我们为什么总想拖延 (二)如何有效应对拖延 (三)如何更好的自我控制 (四)为啥付出了没有回报 (五)如何提高学习效率 三…...
为什么信号经过线束会有衰减?
信号在线束(电线、电缆)中传播时会发生衰减,通俗来说就像 “能量在路上被慢慢消耗”,可以用几个生活中的类比来理解: 1. 线束本身的 “阻力”—— 电阻损耗 类比:就像水流过水管时,水管内壁粗糙…...

(15)关于窗体的右键菜单的学习与使用,这关系到了信号与事件 event
(1)起因来源于 4.11 的老师讲的例题,标准的,规范的使用右键菜单的代码及参考资料如下: (2) 接着脱离上面的那个复杂的环境,用简单的例子测试一下 : 说明老师讲的都是对…...
人工智能在智能教育中的创新应用与未来展望
最近研学过程中发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...
PyTorch图像建模(图像识别、分割和分类案例)
文章目录 图像分类技术:改变生活的智能之眼图形识别技术图像识别过程图像预处理图像特征提取 图像分割技术练习案例:图像分类项目源码地址实现代码(简化版)训练结果(简化版)实现代码(优化版&…...

Ubuntu Desktop 24.04 常用软件安装步骤
文章目录 Ubuntu Desktop 24.04 常用软件安装步骤Snipaste F1快捷截图(超方便 | 我6台电脑每台都用)搜狗输入法快速浏览工具 | 空格键快速预览文件壁纸工具 | varietySSH 工具 | Termius 终端分屏工具 | TmuxCaffeine | 避免息屏小工具 一些设置将启动台…...

Linux iSCSI存储共享实验指南
实验介绍 1、在Linux平台上通过iSCSI协议实现IP-SAN存储共享 2、掌握存储导出(export)和存储导入(import)的配置方法 3、学习iSCSI存储的发现、连接、断开和管理操作 1、实验环境 两台同网段的Linux虚拟机(无需物理交换机) 操作系统:Lin…...
Maven打包SpringBoot项目,因包含SpringBootTest单元测试和Java预览版特性导致打包失败
SpringBoot启用Java预览版特性(无测试类) 在pom.xml文件中加入以下配置表示启用Java预览版 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>…...

git入门之HEAD介绍
目录 前言一、HEAD 的含义与作用二、游离状态的触发场景及特征1. 触发条件2. 游离状态的特征 三、游离状态的常见使用情况1. 临时查看历史代码2. 保留游离状态的提交 四、注意事项与最佳实践1. 风险防范2. 状态检测技巧 总结 前言 本文介绍Git核心概念HEAD的定义,作…...

车道线检测:自动驾驶的“眼睛”
在自动驾驶技术的庞大体系中,车道线检测扮演着至关重要的角色,它就像是自动驾驶汽车的“眼睛”,帮助车辆感知道路边界,从而实现安全、准确的行驶。今天,我们就来深入探讨一下车道线检测的奥秘,看看它是如何…...
中国软件行业 2024 年度分析报告
一、行业概况 1.1 定义与范畴 软件行业作为信息技术产业的核心组成部分,主要通过开发、销售及维护软件产品,或依托软件产品为用户提供各类服务。其涵盖软件产品、信息技术服务、信息安全以及嵌入式系统软件等多个细分领域。软件产品包含操作系统、办公软…...

力扣面试150题--填充每个节点的下一个右侧节点指针 II
Day 45 题目描述 思路 初次做法:考虑到每一节点都要指向它右边的第一个节点,那么我们需要从根向下,最好每次提前处理根节点指向它右边的节点,那么符合这样的遍历方法,很容易i想到前序遍历,但是前序遍历是…...

使用openvino和onnxruntime的SDK部署yolo11检测模型
这里的代码参考ultralytics代码库里面的examples文件夹下面的openvino和onnxruntime使用案例部署yolo11检测模型的代码。这两种部署框架和前面的tensorRT框架都是类似的,只是使用的接口不太一样。 PART A -- onnxruntime的使用 1.下载onnxruntime的推理框架 (1) …...

C 语言学习笔记(指针4)
内容提要 指针 函数指针与指针函数二级指针 指针 函数指针与指针函数 函数指针 定义 函数指针本质上是指针,是一个指向函数的指针。函数都有一个入口地址,所谓指向函数的指针,就是指向函数的入口地址。(这里的函数名就代表…...
PostgreSQL 数据库备份与恢复
1 逻辑备份(单库) postgres#pg_dump --help 使用方法: pg_dump [选项]... [数据库名字] 一般选项: -f, --fileFILENAME 输出文件或目录名 -F, --formatc|d|t|p 输出文件格式 (c 自定义压缩格式输出, d 目录, tar,p 备份为文本明…...
QT高DPI支持
核心函数: qputenv("QT_SCREEN_SCALE_FACTORS", envVar); 如: qputenv("QT_SCREEN_SCALE_FACTORS", "1.2"); 这是我个人目前用的效果最好的,可惜数值不能小于1,小于1的时候,会出问题。 需要程序…...

MySQL的相关操作
目录 一. 字符串函数 二. group by分组 2.1 作用 2.2 格式 2.3 举例 三. order by排序 3.1 格式 3.2 举例 四. limit 4.1 作用 4.2 举例 五. having 5.1 作用 5.2 举例 六. 正则表达式 七. 多表查询 7.1 定义 7.2 子查询 7.3 联合查询 纵向合并 7.4 交叉连…...
从elf文件动态加载的过程解释got,plt及got.plt,plt.sec
author: hjjdebug date: 2025年 05月 23日 星期五 17:29:34 CST desprib: 从elf文件动态加载的过程解释got,plt及got.plt,plt.sec 文章目录 1. 概念定义2. 测试源码3. 外部函数调用对应着 .plt.sec 中的一小段代码,4. .got.plt 将来存储实际的外部函数地址, 开始存储.plt中对应…...

鸿蒙HarmonyOS多设备流转:分布式的智能协同技术介绍
随着物联网和智能设备的普及,多设备间的无缝协作变得越来越重要。鸿蒙(HarmonyOS)作为华为推出的新一代操作系统,其分布式技术为实现多设备流转提供了强大的支持。本文将详细介绍鸿蒙多设备流转的技术原理、实现方式和应用场景。 …...

XXE(外部实体注入)
目录 学习xxe前提:了解xml格式 1. XML基础 2. XXE基础知识 2.1. 结构 2.2. 定义与原理 2.3. XML实体类型 2.4. 攻击类型 2.5. 防御措施 3. pikachu靶场xxe练习 学习xxe前提:了解xml格式 1. XML基础 文档结构包括XML声明、DTD文档类型定义&…...

jenkins凭据管理
用途: 存储构建需要与其他系统认证所使用的账户或者密码信息. Username with password类型存储Harbor或者其他系统的用户名和密码。GitLab API token类型存储Gitlab的用户API token。Secret text类型可以用来存储OpenShift等系统中的token。Certificate类型可以用户存储证书&am…...

驱动开发硬核特训 · Day 31:理解 I2C 子系统的驱动模型与实例剖析
📚 训练目标: 从驱动模型出发,掌握 I2C 子系统的核心结构;分析控制器与从设备的注册流程;结合 AT24 EEPROM 驱动源码与设备树实例,理解 i2c_client 与 i2c_driver 的交互;配套高质量练习题巩固理…...
9大开源AI智能体概况
项目GitHub 链接开发组织核心功能应用领域典型应用案例活跃度AutoGPT (176k⭐)链接Significant Gravitas 团队基于 GPT-4 的自主代理,能够自动分解任务并生成多步提示循环执行,支持调用工具(如网络搜索、文件操作等)。自动化办公、…...

【python】局域网内通过python远程重启另一台windows电脑
👉技__能👈:C/C/C#/Python/Java/PHP/Vue/Node.js/HTML语言 👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。 局域网内通过python远程重启另一台windows电脑 目录 局域网内通过python远程…...

超越感官的实相:声、光、气味的科学与哲学探微
在人类的感官世界中,声、光、气味是日常生活中最直接的现象:我们聆听音乐、观赏光影、呼吸花香。然而,若深入探究它们的本质,科学与哲学竟以截然不同的视角,揭示了一个超越感官的实相世界。本文将从经典物理学、佛教哲…...
Python邮件处理:POP与SMTP
poplib简介 poplib 是Python 3中的官方邮件库,实现了POP的标准:RFC1939,用于邮件的收取。与之类似的还有imaplib 。 (注:本文仅拿pop举例) poplib的使用方法,就是几步: 先创建一…...

什么是VR场景?VR与3D漫游到底有什么区别
在数字化时代,虚拟现实(Virtual Reality, 简称VR)场景与3D漫游作为两种前沿技术,改变着人们的生活方式和体验模式。通过计算机模拟真实或假想的场景,让用户仿佛身临其境,并能与虚拟环境进行互动。尽管VR场景…...

python学习day2:进制+码制+逻辑运算符
进制 Python 中的进制表示与转换 进制的基本概念 二进制、八进制、十进制、十六进制的定义与特点不同进制在计算机科学中的应用场景 Python 中的进制表示 二进制表示:使用 0b 前缀八进制表示:使用 0o 前缀十六进制表示:使用 0x 前缀示例…...