目录

一、项目原理与核心技术

二、环境准备与工具包导入

1. 环境依赖

2. 工具包导入

三、自定义工具类 myutils.py 实现

四、主程序核心流程(银行卡识别.py)

1. 命令行参数设置

2. 银行卡类型映射

3. 辅助函数:图像展示

五、步骤 1:模板图像预处理与数字提取

1. 读取模板并预处理

2. 检测模板数字轮廓并排序

六、步骤 2:银行卡图像预处理与卡号识别

1. 读取银行卡图像并预处理

2. 数字区域定位(闭运算 + 二值化 + 轮廓检测)

3. 筛选有效数字区域

4. 模板匹配识别卡号

七、结果展示与输出

1. 打印识别结果

2. 显示最终结果图

八、运行示例与效果验证

1. 准备测试文件

2. 运行命令

3. 预期结果

九、常见问题与优化建议

1. 识别准确率低的原因与解决方法

2. 功能扩展建议


在金融场景中,自动识别银行卡号能极大提升业务处理效率,避免人工录入的误差。本文将详细介绍如何使用 Python+OpenCV 构建一套智能卡号识别系统,通过模板匹配的方式,从银行卡图片中精准提取卡号并判断卡类型,适合 OpenCV 初学者和计算机视觉入门学习者参考。


一、项目原理与核心技术

本系统核心采用模板匹配思想,通过预先制作的数字模板(OCR-A 字体,银行卡常用字体),与待识别银行卡图片中的数字区域进行匹配,计算相似度后确定对应数字。整体流程分为两大模块:模板图像预处理与数字提取、银行卡图像预处理与卡号识别。

涉及的关键技术如下:

  • 图像预处理:灰度化、二值化、形态学操作(顶帽、闭运算),用于突出数字区域、抑制背景干扰。
  • 轮廓检测与排序:通过cv2.findContours检测数字轮廓,并按 “从左到右” 顺序排序,确保数字识别顺序正确。
  • 模板匹配:使用cv2.matchTemplate计算待识别数字与模板的相似度,选择得分最高的模板作为识别结果。

二、环境准备与工具包导入

1. 环境依赖

  • Python 3.6+
  • OpenCV-Python(pip install opencv-python
  • NumPy(pip install numpy

2. 工具包导入

代码中需导入 OpenCV(核心图像处理)、NumPy(数值计算)、argparse(命令行参数解析),以及自定义工具类myutils(封装轮廓排序和图像缩放功能)。

import numpy as np
import argparse
import cv2
import myutils  # 自定义工具类,下文会提供完整代码

三、自定义工具类 myutils.py 实现

myutils.py封装了两个核心函数:轮廓排序图像缩放,是整个系统的基础工具,代码如下:

import cv2def sort_contours(cnts, method='left-to-right'):"""对轮廓进行排序(支持4种排序方式):param cnts: 输入的轮廓列表:param method: 排序方式,默认左到右(left-to-right),可选:right-to-left、top-to-bottom、bottom-to-top:return: 排序后的轮廓列表、对应的边界框列表"""reverse = False  # 是否逆序,默认正序i = 0  # 排序依据:0=x坐标(左右排序),1=y坐标(上下排序)# 若为右到左或下到上,设置逆序if method in ['right-to-left', 'bottom-to-top']:reverse = True# 若为上下排序,按y坐标排序if method in ['top-to-bottom', 'bottom-to-top']:i = 1# 计算每个轮廓的外接矩形,按指定维度排序bounding_boxes = [cv2.boundingRect(c) for c in cnts]# 同时对轮廓和边界框排序(确保一一对应)cnts, bounding_boxes = zip(*sorted(zip(cnts, bounding_boxes),key=lambda item: item[1][i], reverse=reverse))return list(cnts), list(bounding_boxes)  # 返回列表格式,兼容后续操作def resize(image, width=None, height=None, inter=cv2.INTER_AREA):"""图像缩放(保持宽高比,避免拉伸变形):param image: 输入图像:param width: 目标宽度(若为None,按高度缩放):param height: 目标高度(若为None,按宽度缩放):param inter: 插值方式,默认INTER_AREA(适合缩小图像,画质更清晰):return: 缩放后的图像"""dim = None  # 目标尺寸(宽,高)h, w = image.shape[:2]  # 获取原始图像高度和宽度# 若宽高均为None,返回原始图像if width is None and height is None:return image# 按高度缩放(宽度为None时)if 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 resized

四、主程序核心流程(银行卡识别.py)

主程序分为模板处理银行卡处理两大步骤,下面逐模块详细讲解。

1. 命令行参数设置

通过argparse设置两个必填参数:待识别银行卡图片路径(-i/--image)和数字模板图片路径(-t/--template),方便运行时灵活指定输入文件。

# 创建参数解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="path to input image(银行卡图片路径)")
ap.add_argument("-t", "--template", required=True, help="path to template OCR-A image(数字模板路径)")
args = vars(ap.parse_args())  # 解析参数,转为字典格式

2. 银行卡类型映射

根据银行卡号第一位数字,映射对应的卡类型(符合国际标准):

FIRST_NUMBER = {"3": "American Express(美国运通卡)","4": "Visa(维萨卡)","5": "MasterCard(万事达卡)","6": "Discover Card(发现卡)"
}

3. 辅助函数:图像展示

封装cv_show函数,方便在处理过程中查看每一步的图像结果:

def cv_show(name, img):"""显示图像(按任意键关闭窗口):param name: 窗口名称:param img: 待显示图像"""cv2.imshow(name, img)cv2.waitKey(0)  # 等待按键(0表示无限等待)cv2.destroyWindow(name)  # 关闭窗口

五、步骤 1:模板图像预处理与数字提取

模板图片(如kahao.png)包含 0-9 的 OCR-A 字体数字,需先提取每个数字的轮廓,作为后续匹配的 “模板库”。

1. 读取模板并预处理

  • 读取模板图像 → 转为灰度图 → 二值化(THRESH_BINARY_INV:黑底白字,突出数字)。
# 读取模板图像
template_img = cv2.imread(args["template"])
cv_show("模板原始图", template_img)# 1. 转为灰度图
template_gray = cv2.cvtColor(template_img, cv2.COLOR_BGR2GRAY)
cv_show("模板灰度图", template_gray)# 2. 二值化(黑底白字,便于轮廓检测)
# THRESH_BINARY_INV:反转二值化(原白色区域变黑色,原黑色变白色)
template_binary = cv2.threshold(template_gray, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show("模板二值化图", template_binary)

2. 检测模板数字轮廓并排序

  • cv2.findContours检测数字外轮廓 → 按 “从左到右” 排序(确保数字顺序为 0-9)→ 提取每个数字的 ROI(感兴趣区域)并缩放为统一尺寸(57×88),存入digits字典(键:0-9,值:对应数字的 ROI 模板)。
# 检测模板中的轮廓(只检测外轮廓,简化轮廓坐标)
_, template_cnts, _ = cv2.findContours(template_binary.copy(), cv2.RETR_EXTERNAL,  # 只检测外轮廓cv2.CHAIN_APPROX_SIMPLE  # 简化轮廓(只保留顶点)
)# 在模板图上绘制轮廓(红色,线宽3),验证轮廓检测结果
cv2.drawContours(template_img, template_cnts, -1, (0, 0, 255), 3)
cv_show("模板轮廓图", template_img)# 按“从左到右”排序轮廓(确保数字顺序为0-9)
sorted_cnts, _ = myutils.sort_contours(template_cnts, method="left-to-right")# 提取每个数字的ROI,构建模板库
digits = {}
for i, cnt in enumerate(sorted_cnts):# 计算轮廓的外接矩形(x:左上角x坐标,y:左上角y坐标,w:宽度,h:高度)x, y, w, h = cv2.boundingRect(cnt)# 提取ROI(数字区域)digit_roi = template_binary[y:y+h, x:x+w]# 缩放ROI为统一尺寸(57×88),便于后续匹配digit_roi = cv2.resize(digit_roi, (57, 88))cv_show(f"数字{i}模板", digit_roi)# 存入字典(键:数字0-9,值:对应ROI模板)digits[i] = digit_roiprint("模板库构建完成,包含数字0-9的ROI模板")

六、步骤 2:银行卡图像预处理与卡号识别

银行卡图片(如card1.pngcard2.png)需经过多步预处理,突出数字区域,再通过模板匹配识别卡号。

1. 读取银行卡图像并预处理

  • 读取图像 → 缩放(统一宽度为 300,避免尺寸差异影响后续处理)→ 转为灰度图 → 顶帽操作(突出亮细节,抑制暗背景,增强数字与背景的对比度)。
# 读取银行卡图像
card_img = cv2.imread(args["image"])
cv_show("银行卡原始图", card_img)# 缩放图像(宽度300,保持宽高比)
card_img_resized = myutils.resize(card_img, width=300)
cv_show("银行卡缩放图", card_img_resized)# 转为灰度图
card_gray = cv2.cvtColor(card_img_resized, cv2.COLOR_BGR2GRAY)
cv_show("银行卡灰度图", card_gray)# 顶帽操作(突出亮细节,消除亮背景干扰)
# 定义矩形卷积核(9×3,适合横向数字区域)
rect_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
# 顶帽 = 原始图像 - 开运算结果(开运算:先腐蚀后膨胀,用于去除小亮点)
card_tophat = cv2.morphologyEx(card_gray, cv2.MORPH_TOPHAT, rect_kernel)
cv_show("银行卡顶帽图(突出数字)", card_tophat)

2. 数字区域定位(闭运算 + 二值化 + 轮廓检测)

  • 闭运算(先膨胀后腐蚀):将数字区域连接成一个整体,便于定位 → 二值化(THRESH_OTSU自动找阈值,适合双峰图像)→ 再次闭运算(填补数字内部的小空隙)→ 轮廓检测(找到所有可能的数字区域)。
# 1. 第一次闭运算:连接数字区域(横向)
card_close1 = cv2.morphologyEx(card_tophat, cv2.MORPH_CLOSE, rect_kernel)
cv_show("第一次闭运算(连接数字)", card_close1)# 2. 二值化(OTSU自动阈值,适合数字与背景对比明显的图像)
_, card_thresh = cv2.threshold(card_close1, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU  # 二值化+自动阈值
)
cv_show("银行卡二值化图", card_thresh)# 3. 第二次闭运算:填补数字内部小空隙(使用5×5正方形核)
sq_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
card_close2 = cv2.morphologyEx(card_thresh, cv2.MORPH_CLOSE, sq_kernel)
cv_show("第二次闭运算(填补空隙)", card_close2)# 4. 检测数字区域轮廓
_, card_cnts, _ = cv2.findContours(card_close2.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)# 在银行卡图上绘制所有轮廓(红色,线宽3),验证轮廓检测结果
card_cnts_img = card_img_resized.copy()
cv2.drawContours(card_cnts_img, card_cnts, -1, (0, 0, 255), 3)
cv_show("银行卡轮廓检测图", card_cnts_img)

3. 筛选有效数字区域

通过宽高比(AR) 和尺寸范围筛选出真正的数字区域(排除无关轮廓,如卡面 logo、文字等):

# 存储有效数字区域的坐标(x, y, w, h)
valid_locs = []for cnt in card_cnts:x, y, w, h = cv2.boundingRect(cnt)ar = w / float(h)  # 宽高比(数字区域通常为横向,AR>2.5)# 筛选条件:宽高比2.5~4.0,宽度40~55,高度10~20(需根据实际图片调整)if 2.5 < ar < 4.0 and 40 < w < 55 and 10 < h < 20:valid_locs.append((x, y, w, h))# 按“从左到右”排序有效区域(确保卡号顺序正确)
valid_locs = sorted(valid_locs, key=lambda x: x[0])
print(f"找到{len(valid_locs)}个数字区域")

4. 模板匹配识别卡号

遍历每个有效数字区域,提取 ROI → 预处理(二值化)→ 检测单个数字轮廓 → 模板匹配(计算与每个模板的相似度)→ 选择得分最高的模板作为识别结果,最终拼接成完整卡号。

# 存储最终识别结果
card_number = []# 遍历每个有效数字区域
for i, (gx, gy, gw, gh) in enumerate(valid_locs):# 提取数字区域ROI(适当扩大边界5个像素,避免裁剪到数字)group_roi = card_gray[gy-5:gy+gh+5, gx-5:gx+gw+5]cv_show(f"数字区域{i}", group_roi)# 预处理:二值化(突出单个数字)_, group_binary = cv2.threshold(group_roi, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)cv_show(f"数字区域{i}二值化", group_binary)# 检测单个数字轮廓(每个数字区域包含4个数字,如“4000”)_, digit_cnts, _ = cv2.findContours(group_binary.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 按“从左到右”排序单个数字轮廓sorted_digit_cnts, _ = myutils.sort_contours(digit_cnts, method="left-to-right")# 识别当前区域的4个数字group_result = []for cnt in sorted_digit_cnts:# 提取单个数字的ROI并缩放为模板尺寸(57×88)x, y, w, h = cv2.boundingRect(cnt)digit_roi = group_binary[y:y+h, x:x+w]digit_roi = cv2.resize(digit_roi, (57, 88))cv_show("单个数字ROI", digit_roi)# 模板匹配:计算与每个模板的相似度(使用TM_CCOEFF方法,值越大相似度越高)match_scores = []for digit, digit_template in digits.items():# 模板匹配result = cv2.matchTemplate(digit_roi, digit_template, cv2.TM_CCOEFF)_, score, _, _ = cv2.minMaxLoc(result)  # 获取最大相似度得分match_scores.append(score)# 选择得分最高的模板对应的数字(np.argmax返回最大得分的索引,即数字0-9)best_digit = str(np.argmax(match_scores))group_result.append(best_digit)# 在银行卡图上绘制矩形框和识别结果(红色框,红色文字)cv2.rectangle(card_img_resized, (gx-5, gy-5),  # 左上角坐标(gx+gw+5, gy+gh+5),  # 右下角坐标(0, 0, 255), 1  # 红色,线宽1)# 绘制文字(位置在矩形框上方,字体大小0.65,红色,线宽2)cv2.putText(card_img_resized, "".join(group_result),  # 识别的数字(如“4000”)(gx, gy-15),  # 文字左上角坐标cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 将当前区域的识别结果添加到总卡号中card_number.extend(group_result)

七、结果展示与输出

1. 打印识别结果

输出银行卡类型(通过卡号第一位数字映射)和完整卡号:

# 打印银行卡类型和卡号
card_type = FIRST_NUMBER.get(card_number[0], "Unknown Card Type(未知卡类型)")
print(f"\n银行卡类型:{card_type}")
print(f"银行卡号:{' '.join(card_number[i:i+4] for i in range(0, len(card_number), 4))}")

2. 显示最终结果图

cv_show("银行卡号识别结果", card_img_resized)
cv2.destroyAllWindows()  # 关闭所有窗口


八、运行示例与效果验证

1. 准备测试文件

  • 模板图片:kahao.png(包含 0-9 的 OCR-A 字体数字)。

  • 银行卡图片:card1.png(卡号 4000 1234 5678 9010,)、card2.png(万事达卡,卡号 5412 7512 3456 7890)等。

2. 运行命令

在终端中执行以下命令(需替换为实际文件路径):

python 银行卡识别.py -i card1.png -t kahao.png

3. 预期结果

  • 依次弹出每一步的图像处理窗口(模板轮廓、银行卡顶帽图、数字区域 ROI 等)。
  • 最终输出:
    银行卡类型:Visa(维萨卡)
    银行卡号:4000 1234 5678 9010
    
  • 显示标注了卡号的银行卡图片,红色矩形框包围数字区域,上方显示识别的数字。

九、常见问题与优化建议

1. 识别准确率低的原因与解决方法

  • 问题 1:数字区域未被正确检测(轮廓筛选条件不合适)。
    解决:调整valid_locs筛选时的宽高比(AR)和尺寸范围(如宽度 40~60,高度 8~22),根据实际银行卡图片尺寸优化。
  • 问题 2:模板匹配得分低(数字 ROI 与模板尺寸不匹配)。
    解决:确保数字 ROI 缩放后的尺寸与模板尺寸一致(本文为 57×88),若模板字体不同,需重新制作 OCR-A 字体模板。
  • 问题 3:图像噪声干扰(如卡面反光、污渍)。
    解决:增加高斯模糊(cv2.GaussianBlur)预处理步骤,减少噪声影响,例如:
    card_gray = cv2.GaussianBlur(card_gray, (3, 3), 0)  # 在灰度图后添加高斯模糊
    

2. 功能扩展建议

  • 支持更多卡类型:在FIRST_NUMBER字典中添加更多卡类型映射(如 “2” 对应 MasterCard Maestro)。
  • 批量识别:修改代码支持批量读取文件夹中的银行卡图片,自动输出所有识别结果到文档(如 Excel、TXT)。
  • 实时识别:结合摄像头(cv2.VideoCapture),实现实时拍摄银行卡并识别卡号。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机二级Python

一.静态语言和脚本语言高级语言根据计算机执行机制的不同分为两类&#xff1a;静态语言和脚本语言静态语言的核心特征&#xff1a;变量的类型在编译时&#xff08;写代码时&#xff09;就必须确定并固定下来&#xff0c;即在使用一个变量前必须显式地声明它地类型一旦声明&…

Mybatis Log Plugin打印日志,会导致CPU升高卡死

原因 大量日志输出:MyBatis Log Plugin 会打印大量的 SQL 日志,包括 SQL 语句及其参数。如果项目中 SQL 查询频繁且复杂,日志量会非常大,导致 CPU 使用率升高,甚至卡死。 日志级别设置不当:如果将日志级别设置为 DEBUG 或 TRACE,MyBatis 会输出非常详细的日志信息,这会…

鸿蒙:深色模式适配和浅色模式的切换

前言&#xff1a; 有些时候我们需要对应用进行深色模式的适配处理&#xff0c;并且在不需要的时候切换到浅色状态&#xff0c;下面和大家一起照着官方文档来学习。 下面是官方文档的链接&#xff1a; https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-dark-…

Coze源码分析-资源库-删除插件-后端源码-数据访问和基础设施层

5. 数据访问层 5.1 仓储接口定义 插件仓储接口 文件位置&#xff1a;backend/domain/plugin/repository/plugin.go type PluginRepository interface {// DeleteDraftPlugin 删除插件草稿DeleteDraftPlugin(ctx context.Context, pluginID int64) error// DeleteAPPAllPlugins …

案例一: 对基础选择器的使用【网页盒子】

【1】样例&#xff1a;首先&#xff0c;观察到&#xff0c;几个元素竖着排列的&#xff0c;所以使用块级元素&#xff0c;而不是行内元素。【2】代码演示<head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width,…

爬虫项目优化:如何用 Redis 实现 “断点续爬”?避免重复采集电商数据

在电商数据采集场景中&#xff0c;爬虫常因网络波动、服务器重启、IP 封禁等问题中断。若缺乏断点续爬机制&#xff0c;重启后需从头开始&#xff0c;不仅浪费带宽与时间&#xff0c;还可能因重复采集导致数据冗余。Redis 凭借其高性能、原子操作、多样数据结构的特性&#xff…

决策树概念与原理

决策树简介决策树是一种树形结构树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果(仅举例无其他意义或隐喻)就像一个女孩去相亲&#xff0c;那么首先询问是否大于30&#xff0c;大于则不见&#xff0…

SQL面试题及详细答案150道(116-135) --- 高级查询与函数篇

《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。 前后端面试题-专栏总目录 文章目录 一、本文面试题目录 116. 如何使用CASE语句实…

VeRL:强化学习与大模型训练的高效融合框架

本文由「大千AI助手」原创发布&#xff0c;专注用真话讲AI&#xff0c;回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我&#xff0c;一起撕掉过度包装&#xff0c;学习真实的AI技术&#xff01; 1 概述&#xff1a;VeRL的起源与核心价值 VeRL&#xff08;Versatile…

2. 计算机系统基础知识

1 计算机系统概述 计算机系统 (Computer System) 是指用于数据管理的计算机硬件、软件及网络组成的系统。 计算机系统可划分为硬件(子系统)和软件(子系统)两部分。硬件由机械、电子元器件、磁介质和光介质等物理实体构成&#xff0c;例如处理器(含运算单元和控制单元)、存储器、…

国产EtherCAT从站芯片FCE1353与N32G435 MCU功能板测试流程

上期推荐&#xff0c;我们在前期介绍了FCE1353与国民N32G435 MCU开发板的基本情况&#xff0c;本期主要介绍此开发板的测试流程&#xff0c;以便用户拿到此板做功能验证、兼容性测试、可靠性测试时更加便捷地提高开发验证效率。01概述FCE1353_N32G435RBL7_GPIO_V1 开发板主要通…

向日葵亮点16功能解析:被控端“快速解锁”

向日葵16重磅上线&#xff0c;本次更新新增了诸多实用功能&#xff0c;提升远控效率&#xff0c;实现应用融合突破设备边界&#xff0c;同时全面提升远控性能&#xff0c;操作更顺滑、画质更清晰&#xff01;无论远程办公、设计、IT运维、开发还是游戏娱乐&#xff0c;向日葵16…

深度解析:IService 与 ServiceImpl 的区别

在使用 MyBatis-Plus 开发业务逻辑时&#xff0c;IService 和 ServiceImpl 是经常遇到的两个核心类。很多初学者会疑惑&#xff1a; 为什么要定义 IService&#xff1f;ServiceImpl 又解决了什么问题&#xff1f;它们之间到底有什么区别与联系&#xff1f; 本文将结合源码与应用…

YOLO12 改进、魔改|通道自注意力卷积块CSA-ConvBlock,通过动态建模特征图通道间的依赖关系,优化通道权重分配,在强化有效特征、抑制冗余信息

在分割的研究中&#xff0c;传统卷积神经网络&#xff08;CNN&#xff09;存在两大关键问题&#xff1a;一是池化操作虽能降低计算复杂度&#xff0c;却会导致特征图中有效空间信息丢失&#xff0c;尤其太阳暗条这类不规则、精细结构的特征易被削弱&#xff1b;二是传统 CNN 对…

JuiceFS分布式文件系统

对象存储虽然具备极高的扩展性和成本优势&#xff0c;却缺乏对POSIX语义的支持&#xff0c;导致许多应用无法直接使用。正是在这样的背景下&#xff0c;JuiceFS 应运而生——它巧妙地融合了对象存储的弹性与传统文件系统的易用性&#xff0c;为现代应用提供了一种全新的存储解决…

nginx配置前端请求转发到指定的后端ip

nginx conf配置 配置把“前端静态文件”和“后端接口”统一收在 同一个 server{} 块 里&#xff0c;通过 两条 location 做分流&#xff0c;其中 /api 这条 location 用到了一点“小技巧”把路径裁掉后再转发。下面按执行顺序逐句拆解&#xff0c;告诉你“请求是怎么被转发到 1…

HTML 各种标签的使用说明书

HTML 各种标签的使用说明书 1. HTML 简介 HTML&#xff08;HyperText Markup Language&#xff0c;超文本标记语言&#xff09;是用于创建网页的标准标记语言。它使用一系列标签来描述网页的结构和内容&#xff0c;这些标签被浏览器解释并渲染成用户看到的网页。HTML是构建We…

从关键词到语义理解:小陌引擎如何重构AI搜索优化逻辑?

引言&#xff1a;AI搜索时代的范式转变在传统互联网时代&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;是企业数字营销的核心策略&#xff0c;通过关键词密度、外链建设等技术手段提升网页在搜索引擎结果页&#xff08;SERP&#xff09;中的排名。然而&#xff0c;随着生…

ADE explorer遇到XVFB服务器的问题

遇到这个报错&#xff0c;是因为服务器没有安装xvfb的原因。yum install Xvfb即可解决问题。

期权的套利怎么理解?

期权套利是利用期权价格之间的不合理偏差&#xff0c;通过构建对冲组合获取无风险利润的策略。其核心逻辑基于“无套利定价原则”——若存在价格偏差&#xff0c;市场力量会迅速修正&#xff0c;套利者通过反向操作锁定利润。期权的套利怎么理解&#xff1f;一、主要套利类型与…