如何做网站可以吗搜索引擎优化工具
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:48
当前位置: 首页 > news >正文
如何做网站可以吗,搜索引擎优化工具,wordpress树形目录,字体转换器在线生成器文章目录 一、视频转幻灯片应用1.1 什么是背景减除#xff1f;1.1.1 背景减除简介1.1.2 bgslibrary 1.2 OpenCV背景减除技术1.3 差异哈希1.3.1 图像哈希技术1.3.2 dHash算法1.3.3 图像哈希的速度和准确性测试 1.4 视频转幻灯片应用的工作流程1.5 项目代码1.5.1 环境准备1.5.2 … 文章目录 一、视频转幻灯片应用1.1 什么是背景减除1.1.1 背景减除简介1.1.2 bgslibrary 1.2 OpenCV背景减除技术1.3 差异哈希1.3.1 图像哈希技术1.3.2 dHash算法1.3.3 图像哈希的速度和准确性测试 1.4 视频转幻灯片应用的工作流程1.5 项目代码1.5.1 环境准备1.5.2 辅助模块1.5.3 使用帧差分进行背景减除1.5.2 使用OpenCV对背景像素进行统计建模1.5.3 后处理1.5.4 命令行选项 1.6 GMG和KNN背景估计的比较1.7 改进与总结 二、U2-Net图像分割一种有效的背景减除方法2.1 简介2.2 RSU Block2.2.1 RSU Block结构2.2.2 RSU Block的代码实现 2.3 U2-Net架构2.4 U2-Net 的训练与评估策略2.4.1 训练数据集与数据增强2.4.2 损失函数与优化器2.4.3 评估数据集、指标与结果 2.5 U2-Net样例测试2.6 IS-Net改进的U2-Net图像分割算法2.6.1 简介2.6.2 损失函数2.6.3 推理结果 2.7 总结 《opencv优秀文章集合》《learnopencv系列一使用神经网络进行特征匹配LoFTR、XFeat、OmniGlue、视频稳定化、构建Chrome Dino游戏机器人》《learnopencv系列二U2-Net/IS-Net图像分割背景减除算法、使用背景减除实现视频转ppt应用》《learnopencv系列三GrabCut和DeepLabv3分割模型在文档扫描应用中的实现》
一、视频转幻灯片应用 原文《Build a Video to Slides Converter Application using the Power of Background Estimation and Frame Differencing in OpenCV》、GitHub源码OpenCV背景减除方法文档、 官方教程如何使用背景减除方法、背景减除库——bgslibrary、差异图像哈希 许多时候在YouTube等平台上发布的讲座视频并未提供幻灯片。本文将介绍如何构建一个稳健的应用使用基础帧差分和背景减除模型如KNN和GMG 将视频讲座转换为相应的幻灯片。
1.1 什么是背景减除
1.1.1 背景减除简介 背景减除是一种用于将视频序列中的前景物体与背景分离的技术其基本思想是对场景背景建模并从每一帧中减去以获得前景物体。这在物体跟踪、活动识别和人群分析等许多计算机视觉应用中都非常有用。因此我们可以将这一概念扩展到将幻灯片视频转换为相应幻灯片的任务其中运动的概念体现在视频序列中的各种动画中。 背景减除 背景建模主要包括三个步骤 背景模型初始化通过一系列图像帧建立初始的背景模型。前景检测当前帧与背景模型进行差分差异较大的像素点被视为前景。背景模型更新将当前帧的部分信息更新到背景模型中以适应场景中的变化如光照变化。 背景估计也可以应用于运动跟踪应用如交通分析和人群检测等。文章《background estimation for motion tracking 》将帮助您更好地理解这一概念。
1.1.2 bgslibrary bgslibraryBackground Subtraction Library是一个开源的背景减除背景分割库基于C开发使用OpenCV进行图像处理实现了40多种常用的背景建模和背景减除算法并可在Windows、Linux和MacOS系统上运行。bgslibrary支持的算法包括但不限于
基本算法 Frame DifferenceStatic Frame Difference 统计模型 Gaussian Mixture Model (GMM)Kernel Density Estimation (KDE)Adaptive Background Learning 自适应模型 ViBe (Visual Background Extractor)PBAS (Pixel-Based Adaptive Segmenter)SuBSENSE 非参数方法 Fuzzy Choquet IntegralMulti-Layer Background Subtraction 深度学习方法还支持一些基于深度学习的背景减除算法需要额外的依赖项。
windows系统中直接使用pip install pybgs安装如果是linux系统可以通过以下步骤安装 安装依赖项需要先安装OpenCV并确保CMake已安装。 克隆库 git clone https://github.com/andrewssobral/bgslibrary.git构建和编译 cd bgslibrary
mkdir build
cd build
cmake ..
make示例代码
import cv2
import pybgs# 打开视频文件或摄像头
capture cv2.VideoCapture(video.mp4) # 或者使用 0 打开摄像头# 使用 SuBSENSE 算法进行背景减除
bgs pybgs.SuBSENSE()while True:ret, frame capture.read()if not ret:break# 进行背景减除获取前景掩码foreground_mask bgs.apply(frame)# 显示原始帧和前景掩码cv2.imshow(Frame, frame)cv2.imshow(Foreground Mask, foreground_mask)# 按下 q 键退出循环if cv2.waitKey(30) 0xFF ord(q):break# 释放视频对象并关闭窗口
capture.release()
cv2.destroyAllWindows()更多示例见《bgslibrary-examples-python》。
1.2 OpenCV背景减除技术 一个常见的问题是能否仅通过前后帧的差分来建模背景。虽然这种方法在静态帧的视频中有效但对于动画显著的视频效果不佳。因此对于有显著动画的视频必须使用统计方法来建模背景而不是简单的帧差分。OpenCV提供了多种背景分离方法
背景减除算法主要原理优点缺点典型应用场景MOG2(Mixture of Gaussians)一种参数建模方法利用高斯混合概率密度函数实现高效自适应算法适应光照变化支持阴影检测适合动态背景以及具有多种颜色和纹理的复杂背景会产生很多细小的噪点。对剧烈的光照变化、复杂场景效果有限视频监控、交通监控、动态背景场景KNN一种非参数建模方法使用K近邻技术利用历史帧信息判断背景和前景对复杂背景和光线变化适应性强适合动态环境阴影处理能力弱参数选择敏感复杂环境的前景检测GMG一种结合了统计学建模和贝叶斯估计的背景减除算法通过短期的前景帧进行背景更新并使用贝叶斯估计来获得最有可能的背景模型。适应剧烈变化的环境快速检测新运动物体需要初始化时间较长处理复杂场景效果不稳定运动分析、场景剧烈变化的场合 MOG2背景减除算法函数解析 cv2.createBackgroundSubtractorMOG2(history500, varThreshold16, detectShadowsTrue)history: 训练背景模型使用的帧数值越大背景模型对历史帧的考虑越多适用于变化较慢的场景值越小则适用于快速变化的场景。varThreshold: 决定是否将一个像素标记为前景的阈值。detectShadows: 是否启用阴影检测功能True 时前景中的阴影部分会被标记为灰色区域。 KNN背景减除算法函数解析 cv2.createBackgroundSubtractorKNN(history500, dist2Threshold400.0, detectShadowsTrue)history: 训练背景模型使用的帧数。dist2Threshold: 控制阈值较大的值会减少误检。detectShadows: 是否检测阴影。 这些背景减除算法最终返回的是一个包含前景的掩模移动的物体会被标记为白色背景会被标记为黑色。背景减除算法的局限性
光照变化快速变化的光照可能会被误认为是前景。动态背景例如摇摆的树叶、波动的水面这些场景中的变化难以通过简单的背景建模处理。阴影处理部分算法可以处理阴影但阴影依旧可能导致误检。 在上述背景减除方法中我们将使用GMG和KNN模型因为它们相比于MOG2能够产生更好的效果。
1.3 差异哈希 在后处理部分当我们使用帧差分或背景减除技术筛选并保存我们需要的视频帧之后还是会有很多重复的帧可以使用图像哈希技术进行处理下面是 差异图像哈希的全文总结。
1.3.1 图像哈希技术 在FotoForensics平台团队正计划启用新的色情内容过滤功能以应对反复上传的少量违禁图像。目前的过滤器通过图像哈希来标记已知的违禁图片但图像稍微变化就无法检测到。因此需要一种方法来检测类似的图像。基本上如果你有一个大型图片数据库并且想要找到相似的图片那么你就需要一个生成加权比较的算法。
已尝试的几种哈希算法包括 aHash均值哈希将图像缩小为8x8的灰度图按像素亮度均值生成64位哈希。速度快但误报率高。 pHash感知哈希使用离散余弦变换DCT基于频率生成哈希准确性最好但计算复杂速度较慢。 dHash差异哈希按像素梯度生成哈希值通过比较相邻像素的亮度变化生成64位哈希值具有和aHash相当的速度但误报率更低。调整图像大小为9x8的差异哈希效果最佳可忽略亮度、对比度变化甚至一些色彩校正的影响。
1.3.2 dHash算法
在dHash算法中我们对图像进行处理以生成一个简化的哈希值用于描述图像的视觉特征。具体实现步骤如下 缩小尺寸 有效去除高频细节最快方法是缩小图像。将图像缩小到一个9x8的灰度图不仅能有效去除高频细节也能确保生成的哈希值对图像的大小和比例变化保持一定的稳定性。 为什么选择9x89列提供8个水平差分值即相邻像素亮度的差异而8行产生64位哈希8x8的差分矩阵。这种尺寸使哈希对小的几何变换不敏感比如轻微的拉伸或裁剪。 转为灰度图去除色彩影响 计算像素差异生成哈希值 dHash的核心在于计算相邻像素间的亮度差异以表示图像的局部梯度变化。具体步骤如下 对于缩小后的9x8图像中的每一行从左到右依次计算相邻像素的亮度差。如果左侧像素亮度大于右侧像素设置哈希位为1否则设置为0。每行生成8个位总共8行最终生成64位的哈希值。 哈希值的比较 dHash生成的64位哈希值通过汉明距离Hamming Distance来比较相似度 计算两个图像哈希之间的汉明距离即两个哈希值的不同位数。当距离接近0时表示图像非常相似距离越大表明图像差异越大。通常设定一个阈值如10超过该阈值则认为两幅图像不同。
下面是一个Python示例代码用于实现dHash算法
from PIL import Imagedef dhash(image, hash_size8):# 缩小图像并转换为灰度resized image.resize((hash_size 1, hash_size), Image.ANTIALIAS).convert(L)# 获取像素数据pixels list(resized.getdata())# 计算像素差异diff []for row in range(hash_size):for col in range(hash_size):left_pixel pixels[row * (hash_size 1) col]right_pixel pixels[row * (hash_size 1) col 1]diff.append(1 if left_pixel right_pixel else 0)# 将二进制差异结果转为十六进制哈希decimal_value 0hex_string []for index, value in enumerate(diff):if value:decimal_value 2 ** (index % 8)if index % 8 7:hex_string.append(hex(decimal_value)[2:].rjust(2, 0))decimal_value 0return .join(hex_string)# 使用示例
image Image.open(example.jpg)
print(dhash(image))1.3.3 图像哈希的速度和准确性测试 FotoForensics对150,000张图片进行了测试以下是三种算法的测试结果和分析。
算法速度说明适用场景仅加载图像不进行任何处理16分钟仅加载150,000张图像的情况下耗时16分钟这为其他算法提供了一个速度基准。文件加载基准仅加载和缩放图像3.75小时图像缩放在大批量处理时会显著增加时间消耗文件缩放基准aHash3.75小时速度快但误报率极高比如一张应匹配32次的图片实际匹配到400多次对准确性要求不高的大规模筛选pHash7小时以上无误报也无漏报匹配的哈希差异值为2以下。但计算复杂需要离散余弦变换DCT速度慢精度要求高的场景dHash3.75小时速度快只需要简单的像素差分运算误报少。比如一张应匹配2次的图片误报了4次共匹配6次需要平衡速度和准确性的快速筛选 通过对算法的实验测试表明dHash在速度和准确性上是较优选择但结合dHash和pHash可以获得更好的过滤效果即先用dHash进行快速筛选然后用pHash对筛选结果进一步确认从而实现既高效又准确的匹配。FotoForensics也计划将dHashpHash结合使用过滤和检测违禁内容。
1.4 视频转幻灯片应用的工作流程 本应用应用同时采用帧差分技术用于处理静态帧和背景减除技术用于处理动画较多的视频来进行处理 通过帧差分进行背景减除 灰度形式提取视频帧计算连续帧之间的绝对差值并经过一些形态学操作计算前景掩码的百分比如果该百分比超过设定的阈值我们将保存该帧。 背景减除技术 提取视频帧。将每帧通过背景减除模型生成二值掩码并计算该帧中的前景像素百分比。如果该百分比超过特定阈值 T1则表示存在运动在我们的例子中是动画我们将等待运动稳定。一旦百分比降到阈值 T2 以下我们将保存相应的帧。
1.5 项目代码
1.5.1 环境准备
以下是本项目的文件结构
├── frame_differencing.py # 实现帧差分算法
├── post_process.py # 后处理模块
├── utils.py # 工具模块
└── video_2_slides.py # 主脚本负责运行整个应用程序文件video_2_slides.py包含运行应用的主要脚本其他的是运行应用所需要的模块。注意 你需要安装opencv-contrib-python才能应用GMG背景减除方法。另外本项目使用的其他实用工具包括
img2pdf将生成的幻灯片图像转换为单个PDF文件。我们也可以使用PIL库将图像集转换为PDF但该方法需要先打开每个图像而使用img2pdf可以避免这个问题imagehash使用一种被称为图像哈希的流行图像处理技术去除所有相似生成的图像用于生成相应的幻灯片图像之后进行的后处理步骤。
1.5.2 辅助模块 先介绍utils模块中create_output_directory函数其作用是创建一个用于存储生成的幻灯片图像和最终PDF文件的输出目录。
def create_output_directory(video_path, output_path, type_bgsub):# 从视频路径中提取文件名并构造输出目录的完整路径vid_file_name video_path.rsplit(/)[-1].split(.)[0]output_dir_path os.path.join(output_path, vid_file_name,type_bgsub)# 如果已经存在输出目录则删除。if os.path.exists(output_dir_path):shutil.rmtree(output_dir_path)# 创建输出目录。os.makedirs(output_dir_path, exist_okTrue)print(Output directory created…)print(Path:, output_dir_path)print(**10,\n)return output_dir_pathvideo_path视频文件的路径。output_path生成的图像幻灯片要存储的输出目录路径。type_bgsub要执行的背景减除算法比如Frame_Diff、KNN或GMG。 接着是convert_slides_to_pdf函数其作用是将生成的幻灯片图像转换为单个PDF文件该函数接受create_output_directory的video_path和output_path。
def convert_slides_to_pdf(video_path, output_path):pdf_file_name video_path.rsplit(/)[-1].split(.)[0].pdfoutput_pdf_path os.path.join(output_path, pdf_file_name)print(Output PDF Path:, output_pdf_path)print(Converting captured slide images to PDF…)with open(output_pdf_path, wb) as f:f.write(img2pdf.convert(sorted(glob.glob(f{output_path}/*.png))))print(PDF Created!)print(**10,\n)这两个函数共同工作首先创建一个输出目录以存放生成的幻灯片然后将这些幻灯片合并为一个PDF文件简化了从视频到幻灯片的转换过程。
1.5.3 使用帧差分进行背景减除
1. 初始化变量
prev_frame None curr_frame None screenshots_count 0 # 跟踪过程中保存的截图数量 capture_frame False # 决定是否捕获当前帧是否有明显变化 frame_elapsed 0 # 自上次捕获帧以来经过的帧数 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7)) # 创建椭圆形7*7卷积核# 2. 读取视频第一帧并保存第一帧肯定是要保存在最终幻灯片图集里 cap cv2.VideoCapture(video_file) success, first_frame cap.read()if success:# 将帧转换为灰度。first_frame_gray cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)prev_frame first_frame_grayscreenshots_count1filename f{screenshots_count:03}.pngout_file_path os.path.join(output_dir_path, filename)print(fSaving file at: {out_file_path})# 保存帧。cv2.imwrite(out_file_path, first_frame)循环处理后续帧 将当前帧转换为灰度图像并与前一帧进行比较计算差异对差异图像进行二值化处理阈值设置为80。对二值化后的差异图像进行膨胀操作以捕捉更多的运动。计算非零像素的百分比如果这个百分比大于或等于MIN_PERCENT_THRESH保持为0.06则认为当前帧有显著运动设置capture_frameTrue。如果检测到显著运动并且自上次捕获帧以来经过的帧数frame_elapsed达到ELAPSED_FRAME_THRESH则保存当前帧为图像文件并重置capture_frame标志和帧间隔计数frame_elapsed。更新prev_frame为当前帧以便在下一次迭代中使用。
3. 循环处理每一帧
while cap.isOpened():ret, frame cap.read()if not ret:breakframe_gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)curr_frame frame_grayframe_diff cv2.absdiff(curr_frame, prevframe), frame_diff cv2.threshold(frame_diff, 80, 255, cv2.THRESH_BINARY)# 执行膨胀以捕获运动。frame_diff cv2.dilate(frame_diff, kernel) # 计算帧中非零像素的百分比。p_non_zero (cv2.countNonZero(frame_diff) / (1.0*frame_gray.size))*100if p_non_zeroMIN_PERCENT_THRESH and not capture_frame:capture_frame Trueelif capture_frame:frame_elapsed1if frame_elapsed ELAPSED_FRAME_THRESH:capture_frame Falseframe_elapsed0screenshots_count1filename f{screenshots_count:03}.pngout_file_path os.path.join(output_dir_path, filename)print(fSaving file at: {out_file_path})cv2.imwrite(out_file_path, frame)# 4. 更新prev_frame为当前帧以便在下一次迭代中使用 prev_frame curr_frame# 5. 统计并释放资源
print(**10,\n)
print(Statistics:)
print(—*5)
print(fTotal Screenshots captured: {screenshots_count})
print(—*10,\n)
cap.release()Clip 1. 帧差分后的前景掩模 frame_elapsed 变量和 ELAPSED_FRAME_THRESH 阈值的设置是为了控制捕获帧的频率 避免过度捕获同时提高效率。如果每次检测到显著运动就立即保存帧可能会导致连续保存多个相似的帧尤其是在快速运动的场景中。这可能会导致输出的图像文件数量过多且包含大量重复信息。 基于多次实验设 ELAPSED_FRAME_THRESH85 效果较好。不同的视频场景中运动的频率和速度可能不同需要适当调整。
1.5.2 使用OpenCV对背景像素进行统计建模 上述简单的帧差分方法只适用于视频中主要包含静态帧的场景。对于那些包含太多动画的视频需要使用统计方法对背景像素进行建模比如GMG下面是完整流程
import os
import time
import sys
import cv2
import argparse
from frame_differencing import capture_slides_frame_diff
from post_process import remove_duplicates
from utils import resize_image_frame, create_output_directory, convert_slides_to_pdf# 初始化变量
FRAME_BUFFER_HISTORY 15 # 用于背景建模的帧缓冲区历史长度
DEC_THRESH 0.75 # 前景阈值
DIST_THRESH 100 # 像素与样本之间距离的平方用于决定像素是否接近该样本MIN_PERCENT 0.15 # 确定连续帧之间运动是否运动的阈值
MAX_PERCENT 0.01 # 确定连续帧之间运动是否停止的阈值def capture_slides_bg_modeling(video_path, output_dir_path, type_bgsub, history, threshold, MIN_PERCENT_THRESH, MAX_PERCENT_THRESH):print(fUsing {type_bgsub} for Background Modeling…)print(—*10)# 根据type_bgsub的值初始化相应的背景减除器if type_bgsub GMG:bg_sub cv2.bgsegm.createBackgroundSubtractorGMG(initializationFrameshistory, decisionThresholdthreshold)elif type_bgsub KNN:bg_sub cv2.createBackgroundSubtractorKNN(historyhistory, dist2Thresholdthreshold, detectShadowsFalse) capture_frame Falsescreenshots_count 0# Capture video frames.cap cv2.VideoCapture(video_path)if not cap.isOpened():print(Unable to open video file: , video_path)sys.exit()start time.time()# 循环处理视频帧while cap.isOpened(): ret, frame cap.read()if not ret:break# 复制原始帧以便后续保存orig_frame frame.copy() # 调整帧大小至640宽度保持宽高比frame resize_image_frame(frame, resize_width640) # 应用背景减除器得到前景掩码fg_maskfg_mask bg_sub.apply(frame) # 计算前景掩码中非零像素的百分比p_non_zerop_non_zero (cv2.countNonZero(fg_mask) / (1.0 * fg_mask.size)) * 100# 如果当前帧的前景像素百分比小于MAX_PERCENT阈值这意味着帧中的运动已经停止# 将capture_frame标志设置为True准备捕获帧。if p_non_zero MAX_PERCENT_THRESH and not capture_frame:capture_frame Truescreenshots_count 1png_filename f{screenshots_count:03}.pngout_file_path os.path.join(output_dir_path, png_filename)print(fSaving file at: {out_file_path})cv2.imwrite(out_file_path, orig_frame)# 如果capture_frame已经被设置为True但当前帧的前景像素百分比大于或等于MIN_PERCENT阈值# 这意味着帧中又有新的运动发生因此重置capture_frame为False停止捕获帧。elif capture_frame and p_non_zero MIN_PERCENT_THRESH:capture_frame False# 统计和资源释放end_time time.time()print(10,\n)print(Statistics:)print(—*10)print(fTotal Time taken: {round(end_time-start, 3)} secs)print(fTotal Screenshots captured: {screenshots_count})print(—*10,\n)cap.release()video_path视频文件的路径。output_dir_path输出目录路径其中快照和PDF将被存储。type_bgsub我们想要选择的背景减除算法类型。例如GMG或KNN。history用于模拟背景的帧历史默认15。threshold相应背景减除算法所需的阈值。 对于GMG decisionThreshold 0.75指超过该值就标记为前景的阈值对于KNN使用阈值dist2Threshold 100像素和样本之间的平方距离以决定一个像素是否接近该样本。 为了降低计算成本我们禁用了detectShadows标志并将帧调整到较低的尺寸同时保持长宽比不变。下面是GMG背景减除和KNN背景减除的后得到的前景掩膜效果对比
最后一步我们可以将所有捕获的快照转换为单个pdf也可以将快照转换为PowerPoint ppts
1.5.3 后处理 现在我们已经使用背景建模获得了幻灯片图像但此时许多生成的屏幕截图是大致相似。因此我们需要消除这些图像中的相似或重复项。 我们使用图像哈希技术来识别相似的图像而不是传统的加密哈希算法如MD5或SHA-1因为后者对像素值的微小差异过于敏感。目前有多种图像哈希方法如平均哈希、感知哈希、差异哈希、小波哈希等。本应用选择使用差异哈希因为它计算速度快且比平均哈希和感知哈希更稳健。 我们使用imagehash库进行图像哈希处理使用前可以通过pip install imagehash安装。差异哈希的函数调用形式为
imagehash.dhash(PIL_Image, hash_size)哈希算法的输入是PIL图像而不是numpy数组hash_size表示输出哈希值的大小以位为单位。例如hash_size为8会产生一个64位的哈希值8*8以十六进制格式表示。增加哈希大小允许算法在其哈希中存储更多细节。对于我们的应用设置hash_size12。
import imagehash
from PIL import Image
import os# 该函数接受图像集目录路径和哈希大小作为参数
def find_similar_images(base_dir, hash_size8):# 对文件名进行排序snapshots_files sorted(os.listdir(base_dir))hash_dict {} # 存储图像集内的唯一哈希值duplicates [] # 存储相似图像文件num_duplicates 0 # 计算目录中重复图像的数量print(—*5,Finding similar files,—*5)# 遍历文件更新hash_dict和duplicates列表分别存储相似文件的哈希值和文件名。for file in snapshots_files:read_file Image.open(os.path.join(base_dir, file))comp_hash str(imagehash.dhash(read_file, hash_sizehash_size))if comp_hash not in hash_dict:hash_dict[comp_hash] fileelse:print(Duplicate file: , file)duplicates.append(file)num_duplicates1print(\nTotal duplicate files:, num_duplicates)print(—–*10)return hash_dict, duplicates后处理的最后一步是删除duplicates列表中的所有重复文件。
def remove_duplicates(basedir):, duplicates find_similar_images(base_dir, hash_size12)if not len(duplicates):print(No duplicates found!)else:print(Removing duplicates…)for dup_file in duplicates:file_path os.path.join(base_dir, dup_file)# 对于每个重复文件构建其完整路径并删除该文件。如果文件不存在则打印一条消息。if os.path.exists(file_path):os.remove(file_path)else:print(Filepath: , file_path, does not exists.) print(All duplicates removed!)print(**10,\n)1.5.4 命令行选项
如前所述video_2_slides.py包含主执行脚本。它有以下参数来运行脚本。
parser argparse.ArgumentParser(descriptionThis script is used toconvert video frames into slide PDFs.)
parser.add_argument(-v, –video_file_path, helpPath to the videofile, typestr)
parser.add_argument(-o, –out_dir, default output_results,helpPath to the output directory, typestr)
parser.add_argument(–type, choices[Frame_Diff, GMG, KNN],default GMG, help type of backgroundsubtraction to be used , typestr)
parser.add_argument(–no_post_process, actionstore_true,defaultFalse,helpflag to apply post processing or not)
parser.add_argument(–convert_to_pdf, actionstore_true,defaultFalse, helpflag to convert the entireimage set to pdf or not)args parser.parse_args()video_file_path输入视频文件的路径。out_dir输出目录的路径其中结果将被存储。type要应用的背景减除方法类型。可以是Frame_Diff、GMG默认或KNN之一。no_post_process标志指定是否应用后处理步骤。如果没有指定后处理步骤始终作为默认应用。convert_topdf标志指定是否将图像集合转换为单个PDF文件。
1.6 GMG和KNN背景估计的比较 我们在几个幻灯片视频上运行了GMG和KNN方法发现KNN背景估计方法的FPS几乎是其GMG的四倍。然而在一些视频样本中我们发现KNN方法遗漏了一些帧。 我们没有选择MOG2背景减除技术因为它在过渡阶段捕获了大多数视频帧并倾向于遗漏重要帧。如果进一步调参可能有更好的结果。
1.7 改进与总结
本文的目标是构建一个简单的Python应用程序将语音旁白视频讲座转换为幻灯片 静态帧视频对于大部分是静态帧的视频简单的帧差分方法就能取得不错的结果。 动画场景对于含有显著动画的场景可以使用概率方法如高斯混合模型GMG和KNN来模拟背景像素。 当视频包含静态帧且同时有面部相机运动时这些方法无法有效区分面部运动和动画导致冗余帧的出现。即便在后处理阶段通过图像哈希方法来检测相似帧有时依然无法消除所有冗余的幻灯片。建议可以尝试用余弦相似度等更精准的相似性检测技术来判断帧的相似度以减少冗余。
可能的改进方向深度学习方法。 也可采用深度学习方法通过面部特征提取将提取到的面部特征传递给非参数化的监督学习分类器如KNN分类器用以区分面部移动和实际内容变化从而获得更独特的关键帧样本,有效减少冗余帧的数量尤其适用于面部移动明显的讲座场景。适用场景总体而言这个应用在处理旁白讲座时效果非常好因为此类讲座通常画面内容变化较少且以静态幻灯片为主。而对于包含互动的讲座尤其是内容频繁变化或场景复杂的情况文中提到的几种方法可能仍然不够理想未来可能需要探索其他更复杂的技术来处理这类场景。
二、U2-Net图像分割一种有效的背景减除方法 原文《Enhancing Image Segmentation using U2-Net: An Approach to Efficient Background Removal》、Github代码论文《U2-Net: Going Deeper with Nested U-Structure for Salient Object Detection》、U-2-Net代码库论文《Highly Accurate Dichotomous Image Segmentation (DIS)》、IS-Net代码库、DIS 5 K v1.0数据集 2.1 简介 U2-Net 是一种用于图像分割的深度学习模型特别是在前景提取和物体分割方面表现出色以其有效和直接的方法在广告、电影制作和医学成像等领域具有重要意义。另外本文还将讨论IS-Net即U2-Net的增强版本并展示其优越的结果。 传统的深度学习分割架构如全卷积网络 FCNs在通过多层网络提取局部特征时虽然能够捕捉更多的语义信息但由于多次池化操作特征图分辨率降低导致全局上下文信息的缺失。新方法如 DeepLab 通过多种膨胀卷积atrons convolutions增加网络感受野从而减小信息损失然而这会在高分辨率图像训练时带来显著的计算成本。 U2-Net 采用双层嵌套的修改版 U-Net 结构能够同时处理多层深度特征提取和多尺度信息平衡局部和全局上下文的捕获。其核心构件是 ReSidual U-block (RSU)结合了残差块和 U-Net 对称编码-解码结构的优点。 U2-Net 在训练时不依赖预训练的分类骨干网络能够从头开始训练表现更佳同时减少了内存消耗和计算成本。接下来将详细探讨 RSU 块的结构和特点。
2.2 RSU Block
2.2.1 RSU Block结构
RSU-LL 表示编码器中的层数块的结构可以表示为 RSU-L(Cin, M, Cout)其中
Cin 是输入特征图的通道数M 是编码器中间层的通道数Cout 是输出特征图的通道数 RSU-L 块的输出特征图的空间分辨率与输入特征图保持一致。 下面是RSU-7 block的结构图其主要组成部分包括 图1ReSidual-U块L7 输入卷积层将输入特征图形状为 H × W × C i n H \times W \times C{in} H×W×Cin转换为中间特征图 F 1 ( x ) \mathcal{F}1(x) F1(x)形状为 H × W × C o u t H \times W \times C{out} H×W×Cout用于学习局部特征。 对称的 U-Net 编码-解码块对特征图 F 1 ( x ) \mathcal{F}_1(x) F1(x) 进行编码学习多尺度特征 U ( F 1 ( x ) ) \mathcal{U(F}1(x)) U(F1(x))。这些多尺度特征从编码器层下采样后的特征图中提取经过拼接、卷积和上采样等步骤最终特征图的分辨率依然为 H × W × C o u t H \times W \times C{out} H×W×Cout。 下采样通过池化操作完成上采样使用“双线性”插值。 残差连接通过加法融合局部特征和多尺度特征形成 F 1 ( x ) U ( F 1 ( x ) ) \mathcal{F}_1(x) \mathcal{U(F}_1(x)) F1(x)U(F1(x))。 RSU 块类似于残差块但其学习的是多尺度特征而不仅仅是局部特征。下图中 F 1 \mathcal{F}_1 F1 和 F 2 \mathcal{F}_2 F2 是通过卷积层学习到的特征表示而 U ( F 1 ( x ) ) \mathcal{U(F}_1(x)) U(F1(x)) 则是通过编码-解码块学习到的多尺度特征。
图2残差块和ReSidual-U块之间的比较 下面是RSU-7 block的详细结构图输入特征图尺寸为320 x320 x3。
输入特征图的分辨率为 320x320x3其中 I、M、O 分别表示输入、中间和最终输出通道的数量。图中还展示了卷积、池化、拼接和上采样后的形状。REBNCONV 块是常规卷积后接批归一化和 ReLU 激活。填充和膨胀率均为 1*d默认d 1。图中 ⊕ 符号表示拼接操作。 通常卷积核会在输入特征图上逐像素滑动采样相邻像素。如果设置膨胀率为 2那么卷积核在采样时会隔开一个像素只采样每隔一个像素的位置。类似地如果膨胀率为 3那么卷积核会采样每隔两个像素的位置。膨胀率的作用和优点: 扩大感受野膨胀率可以在不增加卷积核大小的情况下扩展感受野使模型能从更大区域获取上下文信息。这对图像中的全局和多尺度特征提取特别有用尤其在图像分割、物体检测等需要捕捉大范围背景的任务中。减少计算开销相比直接增大卷积核尺寸膨胀卷积无需增加额外参数从而节省了计算资源。保持分辨率膨胀卷积可以在不进行下采样的情况下增大感受野从而避免图像特征图分辨率的降低。这在需要高分辨率特征的任务如前景分割中非常有用。 2.2.2 RSU Block的代码实现
REBNCONV模块对中间特征图应用卷积、Batch Norm 和 ReLU 激活即通常的卷积操作链。
class REBNCONV(nn.Module):def init(self,in_ch3,out_ch3,dirate1):super(REBNCONV,self).init()self.conv_s1 nn.Conv2d(in_ch,out_ch,3,padding1*dirate,dilation1*dirate)self.bn_s1 nn.BatchNorm2d(out_ch)self.relu_s1 nn.ReLU(inplaceTrue)def forward(self,x):hx xxout self.relu_s1(self.bn_s1(self.conv_s1(hx)))return xout_upsample_like 函数接收两个特征图 src 和 tar并将 src 上采样至与 tar 具有相同的空间分辨率。
def _upsample_like(src,tar):src F.upsample(src,sizetar.shape[2:],modebilinear)return srcRSU7 模块的init 方法用于初始化编码器、解码器和池化层
class RSU7(nn.Module):#UNet07DRES(nn.Module):def init(self, in_ch3, mid_ch12, out_ch3):super(RSU7,self).init()self.rebnconvin REBNCONV(in_ch,out_ch,dirate1)self.rebnconv1 REBNCONV(out_ch,mid_ch,dirate1)self.pool1 nn.MaxPool2d(2,stride2,ceil_modeTrue)self.rebnconv2 REBNCONV(mid_ch,mid_ch,dirate1)self.pool2 nn.MaxPool2d(2,stride2,ceil_modeTrue)self.rebnconv3 REBNCONV(mid_ch,mid_ch,dirate1)self.pool3 nn.MaxPool2d(2,stride2,ceil_modeTrue)self.rebnconv4 REBNCONV(mid_ch,mid_ch,dirate1)self.pool4 nn.MaxPool2d(2,stride2,ceil_modeTrue)self.rebnconv5 REBNCONV(mid_ch,mid_ch,dirate1)self.pool5 nn.MaxPool2d(2,stride2,ceil_modeTrue)self.rebnconv6 REBNCONV(mid_ch,mid_ch,dirate1)self.rebnconv7 REBNCONV(mid_ch,mid_ch,dirate2)self.rebnconv6d REBNCONV(mid_ch*2,mid_ch,dirate1)self.rebnconv5d REBNCONV(mid_ch*2,mid_ch,dirate1)self.rebnconv4d REBNCONV(mid_ch*2,mid_ch,dirate1)self.rebnconv3d REBNCONV(mid_ch*2,mid_ch,dirate1)self.rebnconv2d REBNCONV(mid_ch*2,mid_ch,dirate1)self.rebnconv1d REBNCONV(mid_ch*2,out_ch,dirate1)rebnconvin该模块充当一个在编码-解码块外的附加层用于转换输入特征图以便传递给后续的编码-解码块。该层的输出特征图会在最终的解码器输出中相加。rebnconv1 至 rebnconv7表示编码器中的各个块。最大池化层 pool1 至 pool5 用于对编码器块 rebnconv1 至 rebnconv5 的特征图进行下采样。rebnconv6d 至 rebnconv1d表示解码器块从下至上逐层提取多尺度特征。
RSU7 模块的前向传播
def forward(self,x):hx xhxin self.rebnconvin(hx)hx1 self.rebnconv1(hxin)hx self.pool1(hx1)hx2 self.rebnconv2(hx)hx self.pool2(hx2)hx3 self.rebnconv3(hx)hx self.pool3(hx3)hx4 self.rebnconv4(hx)hx self.pool4(hx4)hx5 self.rebnconv5(hx)hx self.pool5(hx5)hx6 self.rebnconv6(hx)hx7 self.rebnconv7(hx6)hx6d self.rebnconv6d(torch.cat((hx7,hx6),1))hx6dup _upsample_like(hx6d,hx5)hx5d self.rebnconv5d(torch.cat((hx6dup,hx5),1))hx5dup _upsample_like(hx5d,hx4)hx4d self.rebnconv4d(torch.cat((hx5dup,hx4),1))hx4dup _upsample_like(hx4d,hx3)hx3d self.rebnconv3d(torch.cat((hx4dup,hx3),1))hx3dup _upsample_like(hx3d,hx2)hx2d self.rebnconv2d(torch.cat((hx3dup,hx2),1))hx2dup _upsample_like(hx2d,hx1)hx1d self.rebnconv1d(torch.cat((hx2dup,hx1),1))return hx1d hxin在前向传播中rebnconvin 层的输出会与解码器层 rebnconv1d 的输出进行最终的相加操作以获得最终输出。
RSU-KF 模块 此外RSU 模块还有一个变体 RSU-KF 模块K是编码器中的层数。该模块用膨胀卷积代替编码-解码块中的池化和上采样操作以缓解网络在更深层次上逐步丢失上下文信息的问题。
2.3 U2-Net架构 U2-Net 的核心结构是RSU Block通过双层嵌套结构构建。外层结构采用 U 形结构由 11 个stages组成每个stage包含一个配置好的 RSU 块。
图5. U2-Net 架构示意图。主要架构是一个类似 U-Net 的编码-解码器每个stage由RSU组成。 U2-Net 的结构包含以下三个组件 六个编码器阶段En_1 到 En_6其中 En_1 至 En_4 分别使用 RSU-7、RSU-6、RSU-5 和 RSU-4 块而 En_5 和 En_6 使用 RSU-4F 块。 五个解码器阶段De_1 到 De_5与相对称的编码器阶段对应。除 De_5 之外每个解码器阶段的输入为其上一阶段的输出与相对称的编码器阶段输出的上采样拼接结果De_5 结合了 En_5 和 En_6 的上采样拼接结果。 侧输出解码器阶段 De_1 到 De_5 和编码器阶段 En6 的输出特征图经过 3x3 卷积层再上采样到输入图像的分辨率320x320生成六个侧输出 S s i d e ( 6 ) \mathcal{S}^{(6)}{side} Sside(6) 到 S s i d e ( 1 ) \mathcal{S}^{(1)}{side} Sside(1)。这些侧输出经过 Sigmoid 激活生成概率图。然后将这些特征图拼接并通过一个 1x1 卷积和 Sigmoid 激活生成最终的融合概率图 S f u s e \mathcal{S}{fuse} Sfuse。
下表显示了U2-Net编码器和解码器级中RSU模块的完整配置参数 U2-Net 模块中的最终侧输出的实现过程如下
#side output
d1 self.side1(hx1d)d2 self.side2(hx2d)
d2 _upsample_like(d2,d1)d3 self.side3(hx3d)
d3 _upsample_like(d3,d1)d4 self.side4(hx4d)
d4 _upsample_like(d4,d1)d5 self.side5(hx5d)
d5 _upsample_like(d5,d1)d6 self.side6(hx6)
d6 _upsample_like(d6,d1)d0 self.outconv(torch.cat((d1,d2,d3,d4,d5,d6),1))return F.sigmoid(d0), F.sigmoid(d1), F.sigmoid(d2), F.sigmoid(d3), F.sigmoid(d4), F.sigmoid(d5), F.sigmoid(d6)侧输出计算 d1 到 d6是 解码器De_1 到 De_5 和编码器 En_6 的输出特征图先经过 3x3 卷积层再通过 _upsamplelike 函数将其上采样至与 d1 相同的空间分辨率而得到的。这确保了在拼接时各个特征图的大小一致。 特征拼接通过 torch.cat 将所有上采样后的侧输出d1 到 d6在通道维度上拼接并通过一个 1x1 的卷积层 outconv 处理以获得更丰富的特征表示。 激活函数应用最后使用 Sigmoid 激活函数对所有单独的输出和拼接后的输出进行处理生成最终的概率图为模型的前景分割任务提供了丰富的信息。 U2-Net 还提供了一个缩小版模型 U2-NetP适用于边缘设备推理减少了 RSU 块的输入、中间和输出通道数。 2.4 U2-Net 的训练与评估策略
2.4.1 训练数据集与数据增强
数据集作者使用了 DUTS 图像数据集进行二分类分割包含 10,553 张图像。通过水平翻转数据量增加到 21,106 张训练图像。数据增强训练过程中图像先被调整为 320×320 像素然后随机进行垂直翻转最后随机裁剪为 228×288 像素。
2.4.2 损失函数与优化器 损失函数训练损失定义为侧输出概率图和最终融合输出图的加权和 L ∑ m 1 M w s i d e ( m ) l s i d e ( m ) w f u s e l f u s e \mathcal{L} \sum{m1}^{M} {w^{(m)}{side}l^{(m)}{side}} w{fuse}l{fuse} Lm1∑Mwside(m)lside(m)wfuselfuse 其中 M M M 设置为 6表示六个侧输出显著图权重均为 1。每个损失项 l l l 使用标准的二元交叉熵损失 l − ∑ ( r , c ) ( H , W ) [ P G ( r , c ) log P S ( r , c ) ( 1 − P G ( r , c ) ) log ( 1 − P S ( r , c ) ) ] l - \sum{(r,c)}^{(H,W)} {[P{G(r,c)}\log P{S(r,c)} (1-P{G(r,c)})\log (1-P{S(r,c)})}] l−(r,c)∑(H,W)[PG(r,c)logPS(r,c)(1−PG(r,c))log(1−PS(r,c))] 其中 P G ( r , c ) P{G(r,c)} PG(r,c) 和 P S ( r , c ) P{S(r,c)} PS(r,c) 分别表示真实标签和预测概率的像素值。 优化器使用 Adam 优化器初始学习率为 1 e − 3 1e-3 1e−3超参数设置为默认值具体为 b e t a s ( 0.9 , 0.999 ) betas(0.9, 0.999) betas(0.9,0.999) e p s 1 e − 8 eps1e-8 eps1e−8 w e i g h t d e c a y 0 weightdecay0 weightdecay0。
2.4.3 评估数据集、指标与结果 评估数据集使用六个基准数据集进行评估包括 DUT-OMRON5168 张、DUTS-TE5019 张、HKU-IS4447 张、ECSSD1000 张、PASCAL-S850 张和 SOD300 张。 评估指标 精确率-召回曲线PR曲线beta-F-score 衡量分数越高越好 F β ( 1 β 2 ) × P r e c i s i o n × R e c a l l β 2 × P r e c i s i o n R e c a l l F{\beta} \frac{(1\beta^2) \times Precision \times Recall}{\beta^2 \times Precision Recall} Fββ2×PrecisionRecall(1β2)×Precision×RecallMAE表示真实掩膜和预测图之间的误差值越低越好 M A E 1 H × W ∑ r 1 H ∑ c 1 W ∣ P ( r , c ) − G ( r , c ) ∣ MAE \frac{1}{H \times W}\sum{r1}^{H}\sum{c1}^{W}{|P(r,c) - G(r,c)|} MAEH×W1r1∑Hc1∑W∣P(r,c)−G(r,c)∣加权 F-score用于克服可能的比较不公分数越高越好 F β w ( 1 β 2 ) P r e c i s i o n w ⋅ R e c a l l w β 2 ⋅ P r e c i s i o n w R e c a l l w F_{\beta}^{w} (1\beta^2)\frac{Precision^{w} \cdot Recall^w}{\beta^2 \cdot Precision^w Recall^w} Fβw(1β2)β2⋅PrecisionwRecallwPrecisionw⋅RecallwS-measure评估预测非二元显著图和真实图之间的结构相似性分数越高越好 S ( 1 − α ) S r α S o S (1-\alpha)S_r \alpha S_o S(1−α)SrαSorelax boundary F-measure定量估计预测掩膜的边界质量分数越高越好。
与20 种最先进方法进行对比结果如下 U2-Net 在 DUT-OMRON、HKU-IS 和 ECSSD 数据集上几乎达到了最先进的结果在 DUTS-TE 和 SOD 数据集上接近第二名在 PASCAL-S 数据集上得分接近前三名。 红色、绿色和蓝色分别表示最佳、第二佳和第三佳性能 2.5 U2-Net样例测试 接下来我们将对一些示例图像进行推理并可视化结果。完整代码见《U2_Net_Model_Inference.ipynb》。
加载模型
import os
from PIL import Image
import numpy as npfrom torchinfo import summaryimport torch
import torchvision.transforms as Tfrom u2net import U2NET, U2NETPimport torchvision.transforms.functional as FDEVICE cuda:0 if torch.cuda.is_available() else cpu# 初始化U2-Net和U2-NetP模型
u2net U2NET(in_ch3,out_ch1)
u2netp U2NETP(in_ch3,out_ch1)#使用load_model辅助函数加载模型权重
def load_model(model, model_path, device):model.load_state_dict(torch.load(model_path, map_locationdevice))model model.to(device)return modelu2net load_model(modelu2net, model_pathu2net.pth, devicecuda:0)
u2netp load_model(modelu2netp, model_pathu2netp.pth, devicecuda:0)U2-Net模型有大约44M个参数U2-NetP模型比原始的U2-Net模型小38倍左右仅包含约113万个参数。
图像预处理与批处理 分辨率设置为320x320并使用ImageNet均值和标准差对其进行归一化。
数据预处理
MEAN torch.tensor([0.485, 0.456, 0.406])
STD torch.tensor([0.229, 0.224, 0.225])resize_shape (320,320)transforms T.Compose([T.ToTensor(),T.Normalize(meanMEAN, stdSTD)])# 批处理prepare_image_batch函数略
image_batch prepare_image_batch(image_dirTEST_IMAGE_DIR,resizeresize_shape,transformstransforms,deviceDEVICE)另外还将设置一个denim_image函数进行反向操作将归一化的图像反归一化到 [0, 255]以便进行可视化。
def denorm_image(image, mean, std):image_denorm torch.addcmul(mean[:,None,None], image, std[:,None, None])image torch.clamp(image_denorm*255., min0., max255.)image torch.permute(image, dims(1,2,0)).numpy().astype(uint8)return image推理
def prepare_predictions(model, image_batch):model.eval()all_results []for image in image_batch:with torch.no_grad():results model(image.unsqueeze(dim0))all_results.append(torch.squeeze(results[0].cpu(), dim(0,1)).numpy())return all_resultspredictions_u2net prepare_predictions(u2net, image_batch)
predictions_u2netp prepare_predictions(u2netp, image_batch)下面是一些结果
U2-Net中效果好于U2-NetP右 U2-NetP右的预测结果优于U2-Net中 两个模型效果都一般
2.6 IS-Net改进的U2-Net图像分割算法 论文《Highly Accurate Dichotomous Image Segmentation》 2.6.1 简介 U2-Net论文的作者提出了一种更为优秀的前景分割方法——IS-Net主要改进体现在以下几个方面 高维掩码级编码器IS-Net使用了一个专门的真实编码器来学习高维掩码级特征这一设计使得模型在处理复杂图像分割任务时能够提取更丰富的信息。 中间自监督学习IS-Net引入了一种中间自监督策略Intermediate Supervision, IS模型能够利用自身生成的特征与真实掩码进行对比和学习从而提高特征表示的质量 训练数据集IS-Net基于DIS5K数据集进行训练该数据集较大且标签更准确有助于提升模型的分割性能。 简化的架构与U2-Net不同IS-Net的分割组件不使用融合的侧输出模块简化了架构设计同时依然保持了高效的特征提取能力。 新颖的评估指标IS-Net提出了一种新的评估指标——HCEHuman Correction Efforts用于评估模型在实际应用中修正错误所需的工作量这为模型性能的评估提供了更直观的参考。
这些改进使IS-Net在前景分割任务中表现出更高的准确性和鲁棒性。
IS-Net架构包括两个组件
真实编码器 ground truth encoder用于学习高维的掩码级编码。图像分割组件与U2-Net相似用于学习高分辨率的多阶段和多级图像特征。 图5. IS-Net baseline(a) 显示了图像分割组件(b) 阐明了基于中间监督IS组件构建的真实编码器。
训练时输入图像分辨率为1024×1024采用两阶段训练流程 第一阶段训练自监督的真实编码器模型学习高维掩码级特征。编码器由6个阶段的RSU编码器块组成。 第一至第四阶段使用RSU-7、RSU-6、RSU-5和RSU-4模块第五和第六阶段使用RSU-4F模块。为了减少计算成本512×512的高分辨率真实掩码被通过步幅为2的卷积下采样后传递给编码器阶段。 第二阶段图像分割组件包括五个解码器阶段DE_1-DE_5和六个编码器阶段EN_1-EN_6模型从解码器级DE_1 - DE_5和最后的编码器级EN6生成侧输出概率图和中间特征未激活的logits。
2.6.2 损失函数 引入均方误差MSE损失进行特征同步通过中间监督进行学习。特征同步损失Lfs公式为 L f s ∑ d 1 D λ f s ∣ ∣ f d I − f d G ∣ ∣ 2 L{fs} \sum_{d1}^{D} \lambda ^{fs}||f^{I}_d - f^{G}_d||^2 Lfsd1∑Dλfs∣∣fdI−fdG∣∣2 其中 f d I f^{I}_d fdI 是从解码器阶段提取的图像特征 f d G f^{G}_d fdG 是在第一阶段学习的掩码级编码。D6表示分割模型的阶段DE_1-DE_5和EN_6 使用二元交叉熵损失BCE来计算侧输出图与真实掩码之间的损失。分割组件的训练被视为优化问题 a r g m i n θ s g ( L f s L s g ) \underset{\theta {sg}}{argmin}(L{fs} L_{sg}) θsgargmin(LfsLsg) 请注意IS-Net管道的推理过程中仅使用分割组件正如在之前的U2-Net模型中一样。 2.6.3 推理结果 接下来我们将对一些示例图像进行推理并可视化结果。完整代码见《IS_Net_Model_Inference.ipynb》。
from isnet import ISNetDISisnet ISNetDIS(in_ch3,out_ch1)
isnet load_model(modelisnet, model_pathisnet-general-use.pth, devicecuda:0)预处理不变但由于IS-Net管道不使用融合侧输出图我们将在推理中使用第一个解码器阶段DE_1的侧输出
def prepare_predictions(model, image_batch):model.eval()all_results []for image in image_batch:with torch.no_grad():results model(image.unsqueeze(dim0)) all_results.append(torch.squeeze(results[0][0].cpu(), dim(0,1)).numpy())return all_results让我们可视化几个推理样本并将它们与U2-Net中的样本进行比较 通常情况下IS-Net总是能生成比U2-Net更好的预测掩码但某些场景下会反过来。我们可以通过使用OpenCV的阈值处理工具来改善IS-Net的预测掩码。在处理时我们将阈值设置为10。
假设 prediction_mask 是IS-Net生成的预测掩码
prediction_mask … # 你的预测掩码# 阈值处理 threshold_value 10 # 阈值可以根据具体需求调整 _, thresholded_mask cv2.threshold(prediction_mask, threshold_value, 255, cv2.THRESH_BINARY)# 后处理可选 可以进一步使用形态学操作如膨胀和腐蚀来去除噪声或填补小孔。 kernel np.ones((3, 3), np.uint8) # 定义一个3x3的结构元素 processed_mask cv2.morphologyEx(thresholded_mask, cv2.MORPH_CLOSE, kernel) # 膨胀和腐蚀# 保存并显示结果 cv2.imshow(Processed Mask, processed_mask) cv2.waitKey(0) cv2.destroyAllWindows()2.7 总结 ReSidual-U块ReSidual-U结构RSU在学习多尺度全局上下文的同时也能从局部表示中学习成为U2-Net和IS-Net管道的核心。 U2-NetU2-Net是一个嵌套的双层RSU编码器-解码器结构能够以最小的计算和内存成本获取多层次和多尺度的深度特征表示无需预训练的分类骨干网络。 中间监督策略从目标分割掩码训练自监督的真实编码器有助于捕捉高维掩码级特征。 IS-Net管道IS-Net管道旨在利用训练好的真实编码器和多阶段特征图实现特征同步同时通过分割组件类似于U2-Net学习阶段内和多层次的图像特征。
- 上一篇: 如何做网站镜像网站底部的制作
- 下一篇: 如何做网站联盟开发设计公司网站
相关文章
-
如何做网站镜像网站底部的制作
如何做网站镜像网站底部的制作
- 技术栈
- 2026年03月21日
-
如何做网站结构分析wordpress类似qq空间
如何做网站结构分析wordpress类似qq空间
- 技术栈
- 2026年03月21日
-
如何做网站活动php网站开发案例论文
如何做网站活动php网站开发案例论文
- 技术栈
- 2026年03月21日
-
如何做网站联盟开发设计公司网站
如何做网站联盟开发设计公司网站
- 技术栈
- 2026年03月21日
-
如何做网站卖家具服装 东莞网站建设
如何做网站卖家具服装 东莞网站建设
- 技术栈
- 2026年03月21日
-
如何做网站美工的wordpress 内容可以是表格吗
如何做网站美工的wordpress 内容可以是表格吗
- 技术栈
- 2026年03月21日






