当前位置: 首页 > news >正文

人脸图像数据增强

为什么要做数据增强

在计算机视觉相关任务中,数据增强(Data Augmentation)是一种常用的技术,用于扩展训练数据集的多样性。它包括对原始图像进行一系列随机或有规律的变换,以生成新的训练样本。数据增强的主要目的是增加模型的泛化能力、提高模型的鲁棒性,并减轻过拟合的风险。以下是进行数据增强的几个重要原因:

  1. 增加数据样本数量:数据增强可以通过生成变体来增加训练样本的数量。这对于具有有限标记样本的任务非常重要,因为更多的数据样本有助于提高模型的性能。

  2. 泛化能力:数据增强可以引入多样性,使模型能够更好地泛化到新的、未见过的数据。这有助于模型在真实世界的各种情况下表现良好,而不仅仅是在训练时的数据分布中表现良好。

  3. 鲁棒性:通过对数据进行多样性的变换,模型可以更好地处理因噪声、光照变化、旋转、缩放等因素引起的图像变化。这提高了模型在复杂环境中的稳健性。

  4. 降低过拟合风险:数据增强可以减轻模型过拟合的风险,因为它迫使模型不仅仅学会记住训练数据,还要学会对数据的变化做出反应。这有助于提高模型对新数据的适应能力。

  5. 类别平衡:在多类别分类任务中,某些类别的样本数量可能较少。数据增强可以帮助平衡各个类别的样本数量,以防止模型偏向于出现频率较高的类别。

  6. 节省标注成本:在某些情况下,收集和标记大量的训练数据可能非常昂贵和耗时。通过数据增强,您可以使用较少的标记样本来训练模型,同时保持性能。

常见的数据增强技术包括图像翻转、旋转、缩放、裁剪、颜色变换、加噪声等。选择哪些数据增强技术以及如何应用它们通常取决于具体任务和数据集的特点。数据增强在许多计算机视觉任务中都被广泛使用,包括图像分类、目标检测、分割、人脸识别等。通过增强数据的多样性,可以提高模型的性能并使其更适应复杂的现实世界场景。

人脸图像数据增强

对于人脸图像数据增强,有多种方法可以提高模型的鲁棒性和性能。以下是一些常见的人脸图像数据增强方法:

  1. 旋转和翻转: 随机旋转或翻转图像,以改变人脸的角度和方向,使模型更具鲁棒性。
  2. 缩放和裁剪: 随机调整图像的大小并进行裁剪,以模拟不同尺度和视角下的人脸。
  3. 亮度和对比度调整: 修改图像的亮度、对比度和色彩平衡,以增加模型的鲁棒性。
  4. 噪声添加: 向图像中添加随机噪声,以模拟真实世界中的图像变化。
  5. 颜色扭曲: 扭曲图像的颜色通道,使图像对于不同的照明条件更具鲁棒性。
  6. 遮挡和变形: 在图像中添加遮挡物或变形,以增加模型对于不完整或变形人脸的处理能力。
  7. 人脸关键点扰动: 对图像中的人脸关键点进行随机扰动,以改变面部特征的位置。
  8. 风格迁移: 将不同图像的风格应用到人脸图像上,以增加多样性。
  9. 镜像对称: 镜像对称图像,以生成左右对称的人脸数据。
  10. 增加噪声数据: 引入合成噪声数据,以增加模型对于嘈杂环境下的鲁棒性。

这些增强方法可以单独使用,也可以组合使用。

实现

以下是个人实现的一些人脸增强方式,不会对原始人脸数据造成太大的干扰,进而不会引入脏数据:

  • 旋转:范围在(-20°, 20°) 表示向左向右旋转
def rotate_image(image):rows, cols, _ = image.shapeangle = random.randint(-20, 20)M = cv2.getRotationMatrix2D((cols/2, rows/2), angle, 1)rotated_image = cv2.warpAffine(image, M, (cols, rows))return rotated_image
  • 翻转:只水平翻转
def flip_image(image):return cv2.flip(image, 1)
  • 缩放:范围是原先的(0.8, 1.2)之间
def scale_image(image, scale_factor):scale_factor = random.uniform(0.8, 1.2)rows, cols, _ = image.shapenew_size = (int(cols * scale_factor), int(rows * scale_factor))scaled_image = cv2.resize(image, new_size)return scaled_image
  • 改变亮度对比度
def adjust_brightness_contrast(image):alpha = random.uniform(0.5, 1.5)beta = random.randint(10, 50)return cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
  • 改变颜色
def color_distortion(image, color_matrix):# color_matrix = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]])return cv2.transform(image, color_matrix)
  • 加椒盐噪声
def salt_and_pepper_noise(image, salt_prob=0.01, pepper_prob=0.01):noisy_image = image.copy()total_pixels = image.sizenum_salt = int(total_pixels * salt_prob)salt_coords = [np.random.randint(0, i-1, num_salt) for i in image.shape]noisy_image[salt_coords[0], salt_coords[1]] = 255num_pepper = int(total_pixels * pepper_prob)pepper_coords = [np.random.randint(0, i-1, num_pepper) for i in image.shape]noisy_image[pepper_coords[0], pepper_coords[1]] = 0return noisy_image
  • 直方图均衡化
def equalizeHist_image(image):image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)return cv2.equalizeHist(image)
  • 自适应直方图均衡化
def clahe_image(image):b, g, r = cv2.split(image)clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(5, 5))clahe_b = clahe.apply(b)clahe_g = clahe.apply(g)clahe_r = clahe.apply(r)return cv2.merge((clahe_b, clahe_g, clahe_r))
  • 油画与非真实感渲染
def detailEnhance_image(image):return cv2.detailEnhance(image, None, 20, 0.8)
  • 局部区域亮度调整
def illumination_change(image):img_zero = np.zeros(image.shape, dtype=np.uint8)return cv2.illuminationChange(image, mask=img_zero, alpha=0.2, beta=0.4)
  • 人脸中心点加强或者变暗
def enhance_reduce(image, strength=100):# strength > 0 enhance, strength < 0 reducex, y, _ = image.shaperadius = np.random.randint(10, int(min(x, y)), 1)pos_x = np.random.randint(0, (min(x, y)-radius), 1)pos_y = np.random.randint(0, (min(x, y)-radius), 1)pos_x = int(pos_x[0])pos_y = int(pos_y[0])radius = int(radius[0])for j in range(pos_y-radius, pos_y+radius):for i in range(pos_x-radius, pos_x+radius):distance = math.pow((pos_x-i), 2) + math.pow((pos_y-j), 2)distance = np.sqrt(distance)if distance < radius:result = 1 - distance/radiusresult = result*strengthif strength > 0:image[i, j, 0] = min((image[i, j, 0]+result), 255)image[i, j, 1] = min((image[i, j, 1]+result), 255)image[i, j, 2] = min((image[i, j, 2]+result), 255)else:image[i, j, 0] = max((image[i, j, 0]+result), 0)image[i, j, 1] = max((image[i, j, 1]+result), 0)image[i, j, 2] = max((image[i, j, 2]+result), 0)image = image.astype(np.uint8)return image
  • 遮盖
def mask(image, low=10, high=50):x, y, _ = image.shapemask_size = np.random.randint(low, high, 1)pos_x = np.random.randint(low, (min(x, y)-high), 1)pos_y = np.random.randint(low, (min(x, y)-high), 1)pos_x = int(pos_x[0])pos_y = int(pos_y[0])mask_size = int(mask_size[0])image[pos_x:pos_x+mask_size, pos_y:pos_y+mask_size] = 0return image

将上述合并为一个类:

import os
import cv2
import sys
import json
import math
import random
import numpy as npclass ImageAugment:def rotate_image(self, image):rows, cols, _ = image.shapeangle = random.randint(-20, 20)M = cv2.getRotationMatrix2D((cols/2, rows/2), angle, 1)rotated_image = cv2.warpAffine(image, M, (cols, rows))return rotated_imagedef flip_image(self, image):return cv2.flip(image, 1)def scale_image(self, image, scale_factor):scale_factor = random.uniform(0.8, 1.2)rows, cols, _ = image.shapenew_size = (int(cols * scale_factor), int(rows * scale_factor))scaled_image = cv2.resize(image, new_size)scaled_image = cv2.resize(scaled_image, (112, 112))return scaled_imagedef adjust_brightness_contrast(self, image):alpha = random.uniform(0.5, 1.5)beta = random.randint(10, 50)return cv2.convertScaleAbs(image, alpha=alpha, beta=beta)def color_distortion(self, image, color_matrix):return cv2.transform(image, color_matrix)def salt_and_pepper_noise(self, image, salt_prob=0.01, pepper_prob=0.01):noisy_image = image.copy()total_pixels = image.sizenum_salt = int(total_pixels * salt_prob)salt_coords = [np.random.randint(0, i-1, num_salt) for i in image.shape]noisy_image[salt_coords[0], salt_coords[1]] = 255num_pepper = int(total_pixels * pepper_prob)pepper_coords = [np.random.randint(0, i-1, num_pepper) for i in image.shape]noisy_image[pepper_coords[0], pepper_coords[1]] = 0return noisy_imagedef equalizeHist_image(self, image):image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)return cv2.equalizeHist(image)def clahe_image(self, image):b, g, r = cv2.split(image)clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(5, 5))clahe_b = clahe.apply(b)clahe_g = clahe.apply(g)clahe_r = clahe.apply(r)return cv2.merge((clahe_b, clahe_g, clahe_r))def detailEnhance_image(self, image):return cv2.detailEnhance(image, None, 20, 0.8)def illumination_change(self, image):img_zero = np.zeros(image.shape, dtype=np.uint8)return cv2.illuminationChange(image, mask=img_zero, alpha=0.2, beta=0.4)def enhance_reduce(self, image, strength=100):# strength > 0 enhance, strength < 0 reducex, y, _ = image.shaperadius = np.random.randint(10, int(min(x, y)), 1)pos_x = np.random.randint(0, (min(x, y)-radius), 1)pos_y = np.random.randint(0, (min(x, y)-radius), 1)pos_x = int(pos_x[0])pos_y = int(pos_y[0])radius = int(radius[0])for j in range(pos_y-radius, pos_y+radius):for i in range(pos_x-radius, pos_x+radius):distance = math.pow((pos_x-i), 2) + math.pow((pos_y-j), 2)distance = np.sqrt(distance)if distance < radius:result = 1 - distance/radiusresult = result*strengthif strength > 0:image[i, j, 0] = min((image[i, j, 0]+result), 255)image[i, j, 1] = min((image[i, j, 1]+result), 255)image[i, j, 2] = min((image[i, j, 2]+result), 255)else:image[i, j, 0] = max((image[i, j, 0]+result), 0)image[i, j, 1] = max((image[i, j, 1]+result), 0)image[i, j, 2] = max((image[i, j, 2]+result), 0)image = image.astype(np.uint8)return imagedef mask(self, image, low=10, high=50):x, y, _ = image.shapemask_size = np.random.randint(low, high, 1)pos_x = np.random.randint(low, (min(x, y)-high), 1)pos_y = np.random.randint(low, (min(x, y)-high), 1)pos_x = int(pos_x[0])pos_y = int(pos_y[0])mask_size = int(mask_size[0])image[pos_x:pos_x+mask_size, pos_y:pos_y+mask_size] = 0return imageif __name__ == '__main__':ia = ImageAugment()image_path = sys.argv[1]image = cv2.imread(image_path)rotated_image = ia.rotate_image(image)flipped_image = ia.flip_image(image)scaled_image = ia.scale_image(image, scale_factor=1.2)adjusted_image = ia.adjust_brightness_contrast(image)color_matrix = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]])color_distorted_image = ia.color_distortion(image, color_matrix)salt_image = ia.salt_and_pepper_noise(image)equalize_image = ia.equalizeHist_image(image)clahe_image = ia.clahe_image(image)detailenhance_image = ia.detailEnhance_image(image)illumination_image = ia.illumination_change(image)enhance_image = ia.enhance_reduce(image, 100)reduce_image = ia.enhance_reduce(image, -100)mask_image = ia.mask(image)# savecv2.imwrite('rotated.jpg', rotated_image)cv2.imwrite('flipped.jpg', flipped_image)cv2.imwrite('scaled.jpg', scaled_image)cv2.imwrite('adjusted.jpg', adjusted_image)cv2.imwrite('colorDistorted.jpg', color_distorted_image)cv2.imwrite('salt.jpg', salt_image)cv2.imwrite('equalize.jpg', equalize_image)cv2.imwrite('clahe.jpg', clahe_image)cv2.imwrite('detailenhance.jpg', detailenhance_image)cv2.imwrite('illumination.jpg', illumination_image)cv2.imwrite('enhance.jpg', enhance_image)cv2.imwrite('reduce.jpg', reduce_image)cv2.imwrite('mask.jpg', mask_image)

结果如下:

  • origin image:
    在这里插入图片描述

  • rotate:

在这里插入图片描述

  • flip:

在这里插入图片描述

  • scale:

在这里插入图片描述

  • adjust:

在这里插入图片描述

  • colorDistorted:

在这里插入图片描述

  • salt:

在这里插入图片描述

  • equalize:

在这里插入图片描述

  • clahe:

在这里插入图片描述

  • detailenhance:

在这里插入图片描述

  • illumination:

在这里插入图片描述

  • enhance and reduce:

在这里插入图片描述

在这里插入图片描述

  • mask:

在这里插入图片描述

参考

  • https://blog.csdn.net/qq_39450134/article/details/121886296
  • https://blog.csdn.net/u011808673/article/details/90752958
  • https://www.youbiguo.com/py/273.html

相关文章:

人脸图像数据增强

为什么要做数据增强 在计算机视觉相关任务中&#xff0c;数据增强&#xff08;Data Augmentation&#xff09;是一种常用的技术&#xff0c;用于扩展训练数据集的多样性。它包括对原始图像进行一系列随机或有规律的变换&#xff0c;以生成新的训练样本。数据增强的主要目的是增…...

Android 查看按键信息的常用命令详解

Android 查看按键信息的常用命令详解 文章目录 Android 查看按键信息的常用命令详解一、主要命令&#xff1a;二、命令详解1、getevent2、getevent -l3、dumsys input4、cat XXX.kl4、cat /dev/input/eventX5、getevent 其他命令6、input keyevent XX 三、简单示例修改四、总结…...

【Java 基础篇】Properties 结合集合类的使用详解

Java 中的 Properties 类是一个常见的用于管理配置信息的工具&#xff0c;它可以被看作是一种键值对的集合。虽然 Properties 通常用于处理配置文件&#xff0c;但它实际上也可以作为通用的 Map 集合来使用。在本文中&#xff0c;我们将详细探讨如何使用 Properties 作为 Map 集…...

数字孪生体标准编程

数字孪生体标准 括ISO TC184/SC4正在制定数字孪生制造标准ISO 23247、ISO/IEC JTC1/AG11正在推动数字孪生体标准、IEEE P2806正在做有关“数字表达”的标准。赢家通吃的标准战 卡尔夏皮罗和哈尔范里安撰写了《信息规则&#xff1a;网络经济战略指南》&#xff08;Information R…...

力扣 -- 394. 字符串解码

解题方法&#xff1a; 参考代码&#xff1a; class Solution{ public:string decodeString(string s){stack<string> sst;stack<int> dst;//防止字符串栈为空的时候再追加字符串到栈顶元素sst.push("");int n s.size();int i 0;while(i<n)//最好不…...

面试官:什么是虚拟DOM?如何实现一个虚拟DOM?说说你的思路

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、什么是虚拟DOM 二、为什么需要虚拟DOM 三、如何实现虚拟DOM 小结 一、什么是虚拟DOM 虚拟 DOM &#xff08…...

Ubuntu安装中文拼音输入法

ubuntu安装中文拼音输入法 ubuntu版本为23.04 1、安装中文语言包 首先安装中文输入法必须要让系统支持中文语言&#xff0c;可以在 Language Support 中安装中文语言包。 添加或删除语音选项&#xff0c;添加中文简体&#xff0c;然后会有Applying changes的对话框&#x…...

高端知识竞赛中用到的软件和硬件有哪些

现在单位搞知识竞赛&#xff0c;已不满足于用PPT放题&#xff0c;找几个简单的抢答器、计分牌弄一下了&#xff0c;而是对现场效果和科技感要求更高了。大屏要分主屏侧屏&#xff0c;显示内容要求丰富炫酷&#xff1b;选手和评委也要用到平板等设备&#xff1b;计分要大气些&am…...

Vue 3.3 发布

本文为翻译 原文地址&#xff1a;宣布推出 Vue 3.3 |The Vue Point (vuejs.org) 今天我们很高兴地宣布 Vue 3.3 “Rurouni Kenshin” 的发布&#xff01; 此版本侧重于开发人员体验改进 - 特别是 TypeScript 的 SFC <script setup> 使用。结合 Vue Language Tools&…...

算法|图论 3

LeetCode 130- 被围绕的区域 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目描述&#xff1a;给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域…...

【数据结构】二叉树的层序遍历(四)

目录 一&#xff0c;层序遍历概念 二&#xff0c;层序遍历的实现 1&#xff0c;层序遍历的实现思路 2&#xff0c;创建队列 Queue.h Queue.c 3&#xff0c;创建二叉树 BTree.h BTree.c 4&#xff0c;层序遍历的实现 一&#xff0c;层序遍历概念 层序遍历&#xff1a;除了先序…...

macOS文件差异比较最佳工具:Beyond Compare 4

Beyond Compare for mac是一款Scooter Software研发的文件同步对比工具。你可以选择针对多字节的文本、文件夹、源代码&#xff0c;甚至是支持比对adobe文件、pdf文件或是整个驱动器&#xff0c;检查其文件大小、名称、日期等信息。你也可以选择使用Beyond Compare合并两个不同…...

Windows+Pycharm 如何创建虚拟环境

当我们开发一个别人的项目的时候,因为项目里有很多特有的包,比如 Pyqt5.我们不想破坏电脑上原来的包版本,这个时候,新建一个虚拟环境,专门针对这个项目就很有必要了. 简略步骤: 1.新建虚拟环境 1.打开 pycharm 终端(Terminal)安装虚拟环境工具: pip install virtualenv2.创…...

vant 按需导入 vue2

vant 按需导入 vue2 1、通过npm安装 # Vue 3 项目&#xff0c;安装最新版 Vant&#xff1a; npm i vant -S# Vue 2 项目&#xff0c;安装 Vant 2&#xff1a; npm i vantlatest-v2 -S2、自动按需引入组件 babel-plugin-import 是一款 babel 插件&#xff0c;它会在编译过程中…...

Java手写分治算法和分治算法应用拓展案例

Java手写分治算法和分治算法应用拓展案例 1. 算法思维导图 以下是用Mermanid代码表示的分治算法的实现原理&#xff1a; #mermaid-svg-nvJwIm97kPHEXQOR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nvJwIm97kP…...

学习 CodeWhisperer 的一些总结

目前一些常见的的 AI 工具 GitHub Copilot&#xff1a;GitHub 与 OpenAI 合作开发的一个人工智能助手。 Codeium&#xff1a;是一个免费的人工智能驱动的代码生成工具 Tabnine&#xff1a;一个自动代码生成工具&#xff0c;免费版本非常有限&#xff0c;只提供简短的代码完成…...

JavaScript 中的 `this` 指向问题与其在加密中的应用

JS中的 this 关键字是一个非常重要的概念&#xff0c;它在不同情况下会指向不同的对象或值。在本文中&#xff0c;我们将深入探讨 JavaScript 中 this 的各种情况&#xff0c;并思考如何将其应用于 JS加密中的一些有趣用途。 1. 全局上下文中的 this 在全局上下文中&#xff…...

深入理解算法的时间复杂度

文章目录 时间复杂度的定义时间复杂度的分类时间复杂度分析常见数据结构和算法的时间复杂度常见数据结构常见算法 常见排序算法说明冒泡排序(Bubble Sort)快速排序(Quick Sort)归并排序(Merge Sort)堆排序(Heap Sort) 时间复杂度的定义 时间复杂度就是一种用来描述算法在输入规…...

2023年度教育部人文社会科学研究一般项目评审结果,已公布!

【SciencePub学术】 9月15日&#xff0c;教育部社科司公示了2023年度教育部人文社会科学研究一般项目评审结果&#xff0c;共3482项。 其中&#xff0c;规划基金、青年基金、自筹经费项目共3029项通过专家评审&#xff1b;西部和边疆地区项目200项&#xff0c;新疆项目20项&a…...

十一、MySql的事务(上)

文章目录 一、引入&#xff08;一&#xff09;CURD不加控制&#xff0c;会有什么问题&#xff1f;&#xff08;二&#xff09;CURD满足什么属性&#xff0c;能解决上述问题&#xff1f; 二、什么是事务&#xff1f;三、事务的特性&#xff08;一&#xff09;原子性&#xff1a;…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...