在日常办公自动化(OA)或财务数字化场景中,拍摄的票据常因角度问题出现倾斜、变形,不仅影响视觉呈现,更会导致 OCR 文字识别准确率大幅下降。本文将从技术原理到代码实现,手把手教你用 Python 打造票据图像自动矫正工具,解决实际场景中的图像预处理难题。​

一、核心依赖与整体功能​

实现票据矫正需依托 3 个关键库,各模块分工明确:​

  • OpenCV(cv2):承担图像读取、预处理、轮廓检测与透视变换的核心工作,是实现矫正功能的 “主力工具”。​
  • NumPy:负责图像坐标计算、矩阵运算,为透视变换提供数值支持,解决复杂的坐标映射问题。​
  • PIL(PIL.ImageChops):代码中虽暂未直接调用,但预留用于后续图像融合、对比度优化等扩展功能,提升工具灵活性。​

整体技术流程可简化为:图像读取→预处理(缩放 / 灰度化 / 二值化)→轮廓检测与筛选→透视变换矫正→结果输出,最终将倾斜、变形的票据转化为平整的标准矩形图像。​

二、关键函数拆解​

代码中 4 个核心函数构成了矫正工具的 “骨架”,每个函数对应一个关键技术环节,我们逐一解析其实现逻辑与作用。​

1. 图像显示函数:cv_show​

用于实时查看图像处理的中间结果,方便调试过程中定位问题(如轮廓是否检测准确、二值化效果是否达标)。​

def cv_show(name, img):​cv2.imshow(f'{name}', img) # 创建指定名称的窗口,显示图像​cv2.waitKey(0) # 无限等待按键输入,按任意键关闭窗口​
  • 参数说明:name为窗口名称(如 “原始票据”“轮廓检测结果”),便于区分不同处理阶段;img为待显示的图像数据。​
  • 注意点:若省略cv2.waitKey(0),窗口会因程序执行过快而一闪而过,无法观察图像细节。​

2. 图像缩放函数:resize​

解决原始图像尺寸过大导致的计算效率问题,同时保证图像宽高比不变,避免拉伸变形影响后续轮廓检测。​

def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None  # 存储缩放后的图像尺寸(宽,高)(h, w) = image.shape[:2]  # 获取原始图像的高度(h)和宽度(w)# 若未指定缩放尺寸,直接返回原始图像if width is None and height is None:return image# 仅指定高度时,按高度比例计算宽度(保持宽高比)if width is None:r = height / float(h)  # 缩放比例 = 目标高度 / 原始高度dim = (int(w * r), height)  # 计算缩放后的宽度(需转为整数,像素为整数单位)# 仅指定宽度时,按宽度比例计算高度else:r = width / float(w)  # 缩放比例 = 目标宽度 / 原始宽度dim = (width, int(h * r))  # 计算缩放后的高度# 执行缩放操作,INTER_AREA插值法适合缩小图像,能保留更多细节resized = cv2.resize(image, dim, interpolation=inter)return resized
  • 核心优势:通过 “比例计算 + 固定插值法”,既提升了后续轮廓检测的速度(如将图像高度缩放到 500 像素),又避免了图像拉伸导致的轮廓变形。​

3. 顶点排序函数:order_points​

透视变换的前提是明确票据四个顶点的正确顺序(左上→右上→右下→左下),该函数通过坐标特征实现自动排序,避免人工标注的繁琐。​

def order_points(pts):# 初始化空数组,存储排序后的4个顶点(形状为(4,2),每个元素为(x,y)坐标)rect = np.zeros((4, 2), dtype="float32")# 第一步:按“x+y”的和排序——和最小的是左上角(tl),和最大的是右下角(br)s = pts.sum(axis=1)  # 对每个顶点的x、y坐标求和(axis=1表示按行计算)rect[0] = pts[np.argmin(s)]  # argmin(s)获取和最小的索引,对应左上角rect[2] = pts[np.argmax(s)]  # argmax(s)获取和最大的索引,对应右下角# 第二步:按“y-x”的差排序——差最小的是右上角(tr),差最大的是左下角(bl)diff = np.diff(pts, axis=1)  # 按行计算y-x(后一个元素减前一个元素)rect[1] = pts[np.argmin(diff)]  # 差最小的索引对应右上角rect[3] = pts[np.argmax(diff)]  # 差最大的索引对应左下角return rect
  • 技术原理:利用平面直角坐标系中顶点的 “几何特征”(如左上角 x、y 均较小,右下角 x、y 均较大),无需人工干预即可实现自动排序,为透视变换提供准确的输入。​

4. 透视变换函数:four_point_transform​

票据矫正的 “核心引擎”,通过透视变换矩阵将倾斜的四边形(票据)映射为标准矩形,实现 “从倾斜到平整” 的关键一步。​

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))  # 目标高度取两者最大值# 第四步:定义目标矩形的四个顶点(标准矩形,从(0,0)开始)dst = np.array([[0, 0],                  # 目标左上顶点[maxWidth - 1, 0],       # 目标右上顶点(减1是因为像素坐标从0开始)[maxWidth - 1, maxHeight - 1],  # 目标右下顶点[0, maxHeight - 1]       # 目标左下顶点], dtype="float32")# 第五步:计算透视变换矩阵M(描述原始顶点到目标顶点的映射关系)M = cv2.getPerspectiveTransform(rect, dst)# 第六步:应用透视变换,得到矫正后的图像warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))return warped
  • 关键价值:透视变换突破了 “平行投影” 的限制,能处理任意角度的倾斜(如斜拍、侧拍的票据),是实现 “全场景矫正” 的核心技术。​

三、主流程执行步骤​

完成核心函数定义后,通过主流程代码将各环节串联,实现从 “读取图像” 到 “保存结果” 的完整闭环,步骤如下:​

1. 读取原始图像并预览​

# 读取票据图像(cv2.IMREAD_COLOR表示读取彩色图像,通道顺序为BGR)
image = cv2.imread('fapiao.jpg', cv2.IMREAD_COLOR)
cv_show('原始票据', image)  # 预览原始图像,确认图像读取正常
  • 注意事项:若图像路径错误(如文件不存在、路径含中文),image会返回None,后续代码会报错,需确保路径正确(建议使用绝对路径,如C:/images/fapiao.jpg)。​

2. 图像缩放(提升计算效率)​

# 计算缩放比例:原始图像高度 / 目标高度(此处目标高度设为500,可根据需求调整)
ratio = image.shape[0] / 500.0
orig = image.copy()  # 保存原始图像副本(后续矫正需基于原始尺寸)
image = resize(orig, height=500)  # 按目标高度缩放图像
cv_show('缩放后票据', image)  # 预览缩放后的图像
  • 为什么需要缩放?若原始图像尺寸为 2000×3000 像素,轮廓检测需处理大量像素,耗时较长;缩放到高度 500 像素后,计算量大幅降低,且不影响轮廓检测的准确性。​
  • 为什么保存orig?缩放后的图像仅用于 “轮廓检测”,最终矫正需基于原始图像尺寸(避免缩放导致的细节丢失),因此需保存原始图像副本。​

3. 图像预处理(突出票据轮廓)​

print('开始预处理:灰度化→二值化...')​# 1. 灰度化:将彩色图像转为单通道灰度图(减少计算量,消除色彩干扰)​gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)​# 2. 二值化:将灰度图转为黑白二值图(突出票据轮廓,抑制背景噪声)​# THRESH_BINARY:超过阈值设为255(白色),低于设为0(黑色);THRESH_OTSU:自动计算最佳阈值​edge = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]​
  • 预处理的意义:彩色图像含 3 个通道(BGR),噪声较多;灰度化后变为单通道,二值化进一步 “强化轮廓、弱化背景”,为后续轮廓检测扫清障碍。​

4. 轮廓检测与可视化​

# 检测图像中所有轮廓(RETR_LIST:获取所有轮廓;CHAIN_APPROX_SIMPLE:简化轮廓,减少点数)
# [-2]确保兼容不同OpenCV版本(部分版本返回值为(图像, 轮廓, 层级),部分为(轮廓, 层级))
cnts = cv2.findContours(edge.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]
# 绘制所有轮廓(在缩放图像副本上绘制,颜色为红色(0,0,255),线条宽度1)
image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 1)
cv_show('所有轮廓', image_contours)  # 预览轮廓检测结果
  • 轮廓的定义:图像中连续的、灰度值相同的像素组成的曲线,此处主要指票据的边界轮廓(如票据的四条边)。​
  • 可视化的作用:通过绘制轮廓,可直观确认是否检测到票据边界,若未检测到,需调整预处理参数(如增加模糊步骤)。​

5. 筛选票据轮廓(定位目标区域)​

print('筛选票据轮廓...')​# 按轮廓面积降序排序,取面积最大的轮廓(票据通常是图像中面积最大的物体)​screencnt = sorted(cnts, key=cv2.contourArea, reverse=True)[0]​print(f'最大轮廓原始点数:{screencnt.shape}') # 打印原始轮廓的点数(通常为数百个)​​# 轮廓近似:将复杂轮廓简化为多边形(减少点数),参数0.02*perimeter为近似精度​perimeter = cv2.arcLength(screencnt, True) # 计算轮廓周长(True表示轮廓闭合)​screencnt = cv2.approxPolyDP(screencnt, 0.02 * perimeter, True)​print(f'近似后轮廓点数:{screencnt.shape}') # 若检测正确,点数应为4(对应票据的四个角)​​# 绘制筛选后的票据轮廓(红色,线条宽度2,更醒目)​image_final_contour = cv2.drawContours(image.copy(), [screencnt], -1, (0, 0, 255), 2)​cv_show('票据轮廓', image_final_contour) # 预览筛选后的轮廓​
  • 核心逻辑:票据在图像中通常是 “面积最大的闭合区域”,因此按面积排序取第一;轮廓近似通过 “减少点数”,将不规则的轮廓简化为四边形(票据的形状),若近似后点数为 4,说明成功定位票据的四个顶点。​

6. 透视变换矫正与结果保存​

# 执行透视变换:screencnt是缩放图像的顶点,需乘以ratio还原为原始图像的顶点​warped = four_point_transform(orig, screencnt.reshape(4, 2) * ratio)​​# 保存矫正后的图像(路径可自定义)​cv2.imwrite('corrected_bill.jpg', warped)​# 创建可缩放窗口(避免图像过大/过小无法查看)​cv2.namedWindow('矫正后票据', cv2.WINDOW_NORMAL)​cv2.imshow('矫正后票据', warped) # 预览矫正结果​cv2.waitKey(0) # 等待按键输入​​# 关闭所有OpenCV窗口,释放内存资源​cv2.destroyAllWindows()​
  • 为什么乘以ratio?screencnt是基于缩放图像(高度 500 像素)的顶点坐标,而orig是原始尺寸图像,乘以ratio可将顶点坐标还原为原始尺寸,确保矫正后的图像与原始图像比例一致。​
  • 结果验证:打开保存的corrected_bill.jpg,若票据平整、无倾斜,说明矫正成功;若仍有变形,需检查顶点排序或透视变换参数。

四、功能扩展与实际应用​

该工具不仅适用于票据矫正,还可扩展到多个实际场景,满足不同需求:​

1. 扩展场景​

  • 证件矫正:身份证、银行卡、护照等证件的倾斜矫正,解决拍摄时的角度问题,提升证件识别准确率。例如在银行 APP 的 “证件上传” 功能中,用户拍摄的身份证常因手持角度导致倾斜,通过该工具矫正后,可减少 OCR 识别时的文字偏移误差,提高信息提取正确率。​
  • 文档扫描:书籍、合同、报表等纸质文档的扫描后矫正,替代传统扫描仪的 “自动平整” 功能,降低硬件成本。例如企业员工用手机拍摄纸质合同后,通过工具矫正倾斜、去除背景阴影,可生成与扫描仪效果接近的电子文档,方便后续存档或编辑。​
  • 工业检测:零件、产品的图像定位与矫正,为后续的尺寸测量、缺陷检测提供准确的图像输入。例如在汽车零部件检测中,摄像头拍摄的零件图像可能因摆放角度倾斜,导致尺寸测量偏差,通过该工具矫正后,可确保测量基准的准确性,提升检测精度。​

2. 功能升级建议​

若需将工具从 “基础版” 升级为 “实用版”,可新增以下功能:​

  • 自动背景去除:在矫正后添加背景去除逻辑(如通过颜色阈值分割、边缘检测 + 掩码操作),将票据从复杂背景中分离,生成 “白底黑字” 的清晰图像,进一步提升 OCR 识别效果。​
  • 批量处理功能:通过os库遍历指定文件夹下的所有票据图像(如jpg“png” 格式),自动完成 “读取→矫正→保存” 流程,适用于企业批量处理票据的场景,减少人工操作。​
  • 倾斜角度判断:通过cv2.minAreaRect计算票据轮廓的倾斜角度,若角度绝对值小于 3°(可自定义阈值),则跳过矫正步骤,避免不必要的计算,提升处理效率。​

五、完整代码汇总(可直接运行)​

为方便大家快速使用,以下是完整的可运行代码,包含所有功能模块及注释:

import numpy as np
import cv2
from PIL.ImageChops import screen  # 预留扩展功能使用# 1. 图像显示函数:用于调试时查看中间结果
def cv_show(name, img):cv2.imshow(f'{name}', img)cv2.waitKey(0)  # 按任意键关闭窗口# 2. 图像缩放函数:保持宽高比,提升计算效率
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 image# 仅指定高度,按比例计算宽度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# 3. 顶点排序函数:确保透视变换输入顶点顺序正确(左上→右上→右下→左下)
def order_points(pts):rect = np.zeros((4, 2), dtype="float32")# 按x+y求和排序:最小为左上,最大为右下s = pts.sum(axis=1)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]# 按y-x求差排序:最小为右上,最大为左下diff = np.diff(pts, axis=1)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rect# 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# 主流程:从图像读取到结果保存
if __name__ == "__main__":# 1. 读取原始图像image_path = "fapiao.jpg"  # 替换为你的票据图像路径image = cv2.imread(image_path, cv2.IMREAD_COLOR)if image is None:raise ValueError(f"无法读取图像,请检查路径:{image_path}")cv_show("1. 原始票据", image)# 2. 图像缩放(目标高度500,计算缩放比例)ratio = image.shape[0] / 500.0orig = image.copy()  # 保存原始图像image = resize(orig, height=500)cv_show("2. 缩放后票据", image)# 3. 预处理:灰度化→二值化(突出轮廓)print("正在进行图像预处理...")gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 高斯模糊(可选,用于减少噪声,根据图像情况决定是否添加)# gray = cv2.GaussianBlur(gray, (5, 5), 0)edge = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 4. 轮廓检测与可视化cnts = cv2.findContours(edge.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 1)cv_show("3. 所有轮廓", image_contours)# 5. 筛选票据轮廓(面积最大+近似为四边形)print("正在筛选票据轮廓...")# 按面积降序排序,取最大轮廓screencnt = sorted(cnts, key=cv2.contourArea, reverse=True)[0]print(f"最大轮廓原始点数:{screencnt.shape}")# 轮廓近似(简化为多边形)perimeter = cv2.arcLength(screencnt, True)screencnt = cv2.approxPolyDP(screencnt, 0.02 * perimeter, True)print(f"近似后轮廓点数:{screencnt.shape}")# 检查是否为四边形(4个顶点)if len(screencnt) != 4:raise ValueError("未检测到票据的4个顶点,请调整预处理参数或检查图像质量")# 绘制筛选后的票据轮廓image_final_contour = cv2.drawContours(image.copy(), [screencnt], -1, (0, 0, 255), 2)cv_show("4. 票据轮廓(4顶点)", image_final_contour)# 6. 透视变换矫正与结果保存print("正在进行票据矫正...")warped = four_point_transform(orig, screencnt.reshape(4, 2) * ratio)# 保存矫正后的图像save_path = "corrected_bill.jpg"cv2.imwrite(save_path, warped)print(f"矫正完成,图像已保存至:{save_path}")# 显示矫正结果cv2.namedWindow("5. 矫正后票据", cv2.WINDOW_NORMAL)cv2.imshow("5. 矫正后票据", warped)cv2.waitKey(0)# 关闭所有窗口,释放资源cv2.destroyAllWindows()

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

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

相关文章

vue3+TS项目配置unocss

配置unocss (1)安装依赖 npm i unocss unocss/preset-uno unocss/preset-attributify -D npm install unocss/transformer-directives(2)根目录新建uno.config.ts文件 import { defineConfig } from "unocss"; impor…

嵌入式硬件工程师的每日提问

一、LDO与DC-DC的对比1)同:两者都是将不稳定的直流输入电压转换为稳定的直流输出电压。2)异:LDO:线性调节,通过内部功率晶体管,工作在线性区,稳定输出电压。类比:将湍急的…

从零到一使用Linux+Nginx+MySQL+PHP搭建的Web网站服务器架构环境——LNMP(下)

从零到一使用LinuxNginxMySQLPHP搭建的Web网站服务器架构环境——LNMP(上)https://coffeemilk.blog.csdn.net/article/details/151350565 一、Nginx与PHP-FPM整合原理 1.1、PHP-FPM配置文件 Nginx与PHP-FPM整合原理序号说明1 PHP-FPM是一个第三方的Fast…

论文阅读-Correlate and Excite

文章目录1 背景2 创新点3 方法3.1 总体结构3.2 代价体计算3.3 引导式代价体激励(GCE)3.4 TopK视差回归4 效果参考资料1 背景 在IGEV中构建几何编码体CGC_GCG​时用到了本文将要描述的CoEx,IGEV中没有说明为什么要这样做,本文就是…

探索大语言模型(LLM):Open-WebUI的安装

前言 Open-WebUI 是一款专为大模型设计的开源可视化交互工具,它通过类 ChatGPT 的直观界面,让用户无需代码即可管理、调试和调用本地或云端的大语言模型(LLMs),成为私有化部署的便捷工具,本文将介绍如何部…

企业远程访问方案选择:何时选内网穿透,何时需要反向代理?

企业远程访问需求日益增长,无论是远程办公、分支互联还是服务发布,选择合适的网络方案都至关重要。内网穿透和反向代理是两种常见的技术手段,但它们的设计目标和适用场景截然不同。本文将客观分析两者的特点,帮助企业做出更合理的…

ARM指令集(Instruction Set)细节

ARM指令集(Instruction Set)细节 本文旨在深入探讨 ARM 指令集(Instruction Set)的细节。这是一个非常广泛的主题,我会将其分解为关键概念、不同版本的区别以及核心特性,并提供一些示例。 ARM 指令集的核心在于 RISC(精简指令集计算机&#x…

Vue基础知识-Vue集成 Element UI全量引入与按需引入

一、方式一:全量引入 Element UI全量引入即一次性加载 Element UI 所有组件和样式,优点是配置简单,适合快速开发;缺点是打包体积较大,生产环境可能存在冗余。1. 安装 Element UI全量引入只需安装 Element UI 核心依赖&…

leetcode26(字母异位词分组)

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。示例 1:输入: strs ["eat", "tea", "tan", "ate", "nat", "bat"]输出: [["bat"],["nat","…

光平面标定 (Laser Plane Calibration) 的原理和流程

光平面标定 (Laser Plane Calibration) 是线激光3D相机系统中最为关键且精巧的一步,它直接决定了最终的测量精度。 核心目标 光平面标定的目标是:精确地求出激光器发射出的那个扇形激光平面,在相机坐标系下的数学方程。 这个方程通常表示为一般式: Ax + By + Cz + D = 0…

项目1——单片机程序审查,控制系统项目评估总结报告

执行摘要 本报告对基于STM32F103RET6的老虎机控制系统进行了全面的技术评估。通过深入分析代码结构、系统架构、安全机制和潜在风险,为项目的进一步开发和部署提供专业建议。 核心发现 ✅ 系统架构: 设计合理,模块化程度高⚠️ 安全性: 存在输入验证和并…

【Qt应用程序】

Qt应用程序摘要概述快速开始Qt在线下载与安装Visual Studio开发Qt项目VS配置Qt扩展VS创建Qt项目配置qDebug调试信息配置源程序的字符集项目结构对象树与内存回收基础数据类型信号槽定时器窗口QWidgetQMainWindowQDialog窗口布局窗口中添加右键菜单控件按钮类容器类自定义控件事…

机器学习实战(一): 什么是机器学习

机器学习:让机器学会思考的魔法前言 在当今数字化的浪潮中,人工智能无疑是最引人注目的技术之一,而机器学习正是其核心驱动力。它不再是科幻电影中的遥远设想,而是已经渗透到我们日常生活的方方面面,从智能推荐到自动驾…

java流水号生成方式

1、基于时间戳生成流水号利用当前时间戳生成流水号,可以确保唯一性。通过格式化时间戳,可以生成固定位数的流水号。SimpleDateFormat sdf new SimpleDateFormat("yyyyMMddHHmmssSSS"); String serialNumber sdf.format(new Date());特点&…

前端工具大全:前端开发工具、前端调试工具、前端性能优化工具与构建工具的对比与最佳实践

在现代前端开发中,工具链已经成为开发效率与代码质量的关键。无论是 编辑器与 IDE、构建与打包工具、调试工具 还是 性能优化工具,每一个环节都有成熟的解决方案。 然而,工具太多也容易让团队选择困难:该选 VS Code 还是 WebStorm…

ABAP 使用ECHARTS实现图表展示

最近发现ECHARTS可以整合到SAP中的开源项目,可以丝滑的在SAP中展示各种图表,还是相当惊艳的。 ECHARTS官方网站:https://echarts.apache.org/examples/zh/index.html 今天顺手在开发环境成功安装了,做下记录: 1、ABA…

hot100-贪心算法(附图解思路)

贪心算法的核心,就是用局部最优去代替全局最优。一般的步骤就是去试思路,然后举反例,如果举不出反例,基本可以看作是正确的方法。121. 买卖股票的最佳时机(Best Time to Buy and Sell Stock)难度&#xff1…

从齿轮到智能:机器人如何重塑我们的世界【科普类】

新晋码农一枚,小编会定期整理一些写的比较好的代码和知识点,作为自己的学习笔记,试着做一下批注和补充,转载或者参考他人文献会标明出处,非商用,如有侵权会删改!欢迎大家斧正和讨论!…

python超市购物 2025年6月电子学会python编程等级考试一级真题答案解析

python超市购物 2025年6月 python编程等级考试一级真题 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】 1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解

浅谈代理流程自动化 (APA)

一、什么是APA Agentic Process Automation (APA)APA 利用大型语言模型 (LLM) 自动执行复杂的动态工作流程。它可以自主构建、执行和调整工作流程,同时将人员干预降至最低。与依赖基于规则的系统的传统机器人流程自动化 (RPA&…