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

一文解读基于PaddleSeg的钢筋长度超限监控方案

d09e9692e404e2f952be21856670ee03.png

8f5eadc330c94299c21d6f5f20bc5dee.png

项目背景

钢铁厂生产钢筋的过程中会存在部分钢筋长度超限的问题,如果不进行处理,容易造成机械臂损伤。因此,需要通过质检流程,筛选出存在长度超限问题的钢筋批次,并进行预警。传统的处理方式是人工核查,该方式一方面增加了人工成本,降低了生产效率;另一方面也要求工人师傅对业务比较熟练,能够准确地判断钢筋长度是否超限,且该方法可能存在一定的误判率。在AI时代,利用深度学习技术,可以实现端到端全自动的钢筋长度超限监控,从而降低人工成本,提高生产效率。整体技术方案可以归纳为如下步骤:

  • 在钢筋一侧安装摄像头,拍摄图像;

  • 利用图像分割技术提取钢筋掩膜;

  • 根据摄像头位置和角度确定长度界限;

  • 最后根据该长度界限和钢筋分割范围的几何关系判断本批次钢筋是否超限。

366b78ed72617c200dbf73aae82e2146.gif钢筋长度超限监控整体流程

钢筋超限监控问题可以转换为图像分割后的几何判断问题。为了实现图像分割,我们使用提供了全流程分割方案的飞桨图像分割套件 PaddleSeg,只需简单地修改配置文件,就可以进行模型训练,获得高精度的分割效果。进一步地,我们挑选使用精度和速度平衡的 PP-LiteSeg 模型,保证在实现高精度的同时,满足工业部署的要求。

cc167e06f09b2b343f824ba58b4f8dfa.png

安装环境

使用 PaddleSeg 套件,我们需要准备如下环境:

  • Python >= 3.6

  • 飞桨框架>= 2.1

  • PaddleSeg

接下来,使用如下命令安装 PaddleSeg 以及相应的依赖:

git clone --branch release/2.6 --depth 1 https://gitee.com/PaddlePaddle/PaddleSeg.git
cd PaddleSeg
pip install -r requirements.txt数据处理

由于钢筋长度超限检测数据集是使用图像标注工具 LabelMe 标注的,其数据格式与 PaddleSeg 支持的格式不同,因此可借助 PaddleSeg 中 tools 目录下的脚本 labelme2seg.py,将 LabelMe 格式标注转换成 PaddleSeg 支持的格式。

python tools/labelme2seg.py ~/data/dataset

接下来,使用 PaddleSeg 提供的脚本(split_dataset_list.py)将数据集划分为训练集、验证集和测试集。

python tools/split_dataset_list.py ~/data/dataset . annotations --split 0.7 0.15 0.15

92b82aca1ff51b88248316a85f1a2819.png

模型训练

此处我们选择轻量级语义分割模型 PP-LiteSeg 模型,对钢筋进行分割。具体介绍可参考 PP-LiteSeg 的 README 说明文件。

  • 说明文件链接

https://github.com/PaddlePaddle/PaddleSeg/tree/release/2.7/configs/pp_liteseg

为了在自定义数据集上使用 PP-LiteSeg 模型,需要对 PaddleSeg 提供的默认配置文件(PaddleSeg/configs/pp_liteseg/pp_liteseg_stdc1_cityscapes_1024x512_scale0.5_160k.yml)进行轻微修改。

如下所示,添加自定义数据集路径、类别数等信息:

batch_size: 4  # total: 4*4
iters: 2000optimizer:type: sgdmomentum: 0.9weight_decay: 5.0e-4lr_scheduler:type: PolynomialDecayend_lr: 0power: 0.9warmup_iters: 100warmup_start_lr: 1.0e-5learning_rate: 0.005loss:types:- type: OhemCrossEntropyLossmin_kept: 130000   # batch_size * 1024 * 512 // 16- type: OhemCrossEntropyLossmin_kept: 130000- type: OhemCrossEntropyLossmin_kept: 130000coef: [1, 1, 1]train_dataset:type: Datasetdataset_root: /home/aistudio/data/datasettrain_path: /home/aistudio/data/dataset/train.txtnum_classes: 2transforms:- type: ResizeStepScalingmin_scale_factor: 0.125max_scale_factor: 1.5scale_step_size: 0.125- type: RandomPaddingCropcrop_size: [1024, 512]- type: RandomHorizontalFlip- type: RandomDistortbrightness_range: 0.5contrast_range: 0.5saturation_range: 0.5- type: Normalizemode: trainval_dataset:type: Datasetdataset_root: /home/aistudio/data/datasetval_path: /home/aistudio/data/dataset/val.txtnum_classes: 2transforms:- type: Normalizemode: valtest_config:aug_eval: Truescales: 0.5model:type: PPLiteSegbackbone:type: STDC1pretrained: https://bj.bcebos.com/paddleseg/dygraph/PP_STDCNet1.tar.gzarm_out_chs: [32, 64, 128]seg_head_inter_chs: [32, 64, 64]

接下来,开始执行训练:

python3 train.py --config /home/aistudio/work/pp_liteseg_stdc1.yml \--use_vdl \--save_dir output/mask_iron \--save_interval 500 \--log_iters 100 \--num_workers 8 \--do_eval \--keep_checkpoint_max 10

使用 PaddleSeg 训练过程中可能会出现报错,例如,one_hot_kernel 相关的报错:

Error: /paddle/paddle/phi/kernels/gpu/one_hot_kernel.cu:38 Assertion `p_in_data[idx] >= 0 && p_in_data[idx] < depth` failed. Illegal index value, Input(input) value should be greater than or equal to 0, and less than depth [1], but received [1].

这里需要注意类别是否正确设置,考虑背景类是否添加。one_hot_kernel 另一种报错:

Error: /paddle/paddle/phi/kernels/gpu/one_hot_kernel.cu:38 Assertion `p_in_data[idx] >= 0 && p_in_data[idx] < depth` failed. Illegal index value, Input(input) value should be greater than or equal to 0, and less than depth [5], but received [-1].

此时需要注意 mask 中标签是否超过 [0, num_classes + 1] 的范围。训练完成后,可使用模型评估脚本对训练好的模型进行评估:

python val.py \--config /home/aistudio/work/pp_liteseg_stdc1.yml \--model_path output/mask_iron/best_model/model.pdparams

输出结果为:

2023-03-06 11:22:09 [INFO]    [EVAL] #Images: 32 mIoU: 0.9858 Acc: 0.9947 Kappa: 0.9857 Dice: 0.9928
2023-03-06 11:22:09 [INFO]    [EVAL] Class IoU: 
[0.993  0.9787]
2023-03-06 11:22:09 [INFO]    [EVAL] Class Precision: 
[0.9969 0.9878]
2023-03-06 11:22:09 [INFO]    [EVAL] Class Recall: 
[0.996  0.9906]

由评估输出可见,模型性能为 mIoU:0.9858,Acc:0.9947,能够满足实际工业场景需求。

7e64b4c2ccfc81d202ad060706e885f4.png

模型预测

使用 predict.py 可用来查看具体样本的切割样本效果。

python predict.py \--config /home/aistudio/work/pp_liteseg_stdc1.yml \--model_path output/mask_iron/best_model/model.pdparams \--image_path /home/aistudio/data/dataset/ec539f77-7061-4106-9914-8d66f450234d.jpg \--save_dir output/result

预测的结果如下所示。

import matplotlib.pyplot as plt
import cv2
im = cv2.imread("/home/aistudio/work/PaddleSeg/output/result/pseudo_color_prediction/ec539f77-7061-4106-9914-8d66f450234d.png")
# cv2.imshow("result", im)
plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
plt.figure()
im = cv2.imread("/home/aistudio/work/PaddleSeg/output/result/added_prediction/ec539f77-7061-4106-9914-8d66f450234d.jpg")
plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))

968567f5bcfc6ef58ebcb46e09b0b0e0.png

1d525ed678bf905cc0154396c6bf1da4.png

接下来,利用预测的结果,并采用最大联通域处理后,判断钢筋是否超限。

import cv2def largestcomponent(img_path, threshold=None):"""Filter the input image_path with threshold, only component that have area larger than threshold will be kept.Arg:img_path: path to a binary imgthreshold: connected componet with area larger than this value will be kept"""binary = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)binary[binary == binary.min()] = 0binary[binary == binary.max()] = 255assert (binary.max() == 255 and binary.min() == 0), "The input need to be a binary image, but the maxval in image is {} and the minval in image is {}".format(binary.max(), binary.min())if threshold is None:threshold = binary.shape[0] * binary.shape[1] * 0.01contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)for k in range(len(contours)):if cv2.contourArea(contours[k]) < threshold:cv2.fillPoly(binary, [contours[k]], 0)cv2.imwrite(img_path.split(".")[0] + "_postprocessed.png", binary)

此处,我们可以对比最大联通域处理前后的差别,可以发现滤除了小的联通区域。

prediction = "/home/aistudio/work/PaddleSeg/output/result/pseudo_color_prediction/ec539f77-7061-4106-9914-8d66f450234d.png"
# prediction = "/home/aistudio/work/PaddleSeg/output/result/pseudo_color_prediction/20220705-153804.png"
largestcomponent(prediction)
before_image = cv2.imread(prediction)
after_image = cv2.imread(prediction.replace(".png", "_postprocessed.png"))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(before_image, cv2.COLOR_BGR2RGB))
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(after_image, cv2.COLOR_BGR2RGB))
plt.show()

c80b1cfa3a82abd26615bd259c282436.png

判断钢筋是否超限:

def excesslimit(image_path, direction="right", position=0.6):"""Automatically tells if the steel bar excess manually set position.Arg:img_path: path to a binary imgdirection: which part of the img is the focused area for detecting bar excession.position: the ratio of the position of the line to the width of the image.Return:excess: whether there is steel wheel excess the limit line.excess_potion: the portion of the excess steel bar to the whole bar."""excess_portion = 0.0binary = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)binary[binary == binary.min()] = 0binary[binary == binary.max()] = 255assert (binary.max() == 255 and binary.min() == 0), "The input need to be a binary image, but the maxval in image is {} and the minval in image is {}".format(binary.max(), binary.min())assert (direction == "left" or direction == "right"), "The direction indicates the side of image that iron excess, it should be 'right' or 'left', but we got {}".format(direction)assert (position > 0 and position < 1), "The position indicates the relative position to set the line, it should bigger than 0 and smaller than 1, but we got {}".format(position)img_pos = int(binary.shape[1] * position)if direction == "right":if binary[:, img_pos:].sum() > 0:excess_portion = binary[:, img_pos:].sum() / binary.sum()binary[:, img_pos : img_pos + 3] = 255else:if binary[:, :img_pos].sum() > 0:excess_portion = binary[:, :img_pos].sum() / binary.sum()binary[:, img_pos - 3 : img_pos] = 255print("The iron is {}excessed in {}, and the excess portion is {}".format(["", "not "][excess_portion == 0], image_path, excess_portion))# cv2.imwrite(image_path.split(".")[0] + "_fullpostprocessed.png", binary)cv2.imwrite(image_path.replace("_postprocessed.png", "_fullpostprocessed.png"), binary)return excess_portion > 0, excess_portion

对预测结果批量判断是否超限。

import os
import globoutput_dir = "/home/aistudio/work/PaddleSeg/output"
pseudo_color_result = os.path.join(output_dir, 'result/pseudo_color_prediction')
os.system(f"rm {pseudo_color_result}/*_*postprocessed.*")
for img_path in glob.glob(os.path.join(pseudo_color_result, "*.png")):largestcomponent(img_path)postproc_img_path = img_path.replace(".png", "_postprocessed.png")
excesslimit(postproc_img_path, "left", 0.3)

可视化后处理结果。

im = cv2.imread("/home/aistudio/work/PaddleSeg/output/result/pseudo_color_prediction/ec539f77-7061-4106-9914-8d66f450234d_fullpostprocessed.png")
# cv2.imshow("result", im)
plt.imshow(im)

5d3cb5f4ca8102eced0b41e6221cc476.png
 

1f9bca4ddff98f7ff0fc5eb1f52ee693.png

模型推理与部署

我们可以选择使用飞桨原生推理库 Paddle Inference 推理。首先将训练好的模型导出为 Paddle Inference 模型。

export CUDA_VISIBLE_DEVICES=0 # Set a usable GPU.
# If on windows, Run the following command
# set CUDA_VISIBLE_DEVICES=0
python export.py \--config /home/aistudio/work/pp_liteseg_stdc1.yml \--model_path output/mask_iron/best_model/model.pdparams \--save_dir output/inference

接下来使用推理模型预测。

python deploy/python/infer.py \--config output/inference/deploy.yaml \--save_dir output/infer_result \--image_path /home/aistudio/data/dataset/bcd33bcd-d48c-4409-940d-51301c8a7697.jpg

最后,根据模型输出,判断钢筋是否超限,可视化判断结果。

img_path = "/home/aistudio/work/PaddleSeg/output/infer_result/bcd33bcd-d48c-4409-940d-51301c8a7697.png"
largestcomponent(img_path)
postproc_img_path = img_path.replace(".png", "_postprocessed.png")
excesslimit(postproc_img_path, "right", 0.5)
img_path = "/home/aistudio/work/PaddleSeg/output/infer_result/bcd33bcd-d48c-4409-940d-51301c8a7697_fullpostprocessed.png"
im = cv2.imread(img_path)
plt.imshow(im)

我们也可以使用 FastDeploy 进行部署。FastDeploy 是一款全场景、易用灵活、极致高效的AI推理部署工具。其提供开箱即用的云边端部署体验,支持超过160个文本、视觉、语音和跨模态模型,并可实现端到端的推理性能优化。此外,其还可实现包括图像分类、物体检测、图像分割、人脸检测、人脸识别、关键点检测、抠图、OCR、NLP和TTS等任务,满足开发者多场景、多硬件、多平台的产业部署需求。

通过如下命令就可以非常方便地安装 FastDeploy。

pip install fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html

使用 FastDeploy 进行预测也十分简单:

import fastdeploy as fd
model_file = "/home/aistudio/work/PaddleSeg/output/inference/model.pdmodel"
params_file = "/home/aistudio/work/PaddleSeg/output/inference/model.pdiparams"
infer_cfg_file = "/home/aistudio/work/PaddleSeg/output/inference/deploy.yaml"# 模型推理的配置信息
option = fd.RuntimeOption()
model = fd.vision.segmentation.PaddleSegModel(model_file, params_file, infer_cfg_file, option)
# 预测结果
import cv2
img_path = "/home/aistudio/data/dataset/8f7fcf0a-a3ea-41f2-9e67-4cbaa61238a4.jpg"
im = cv2.imread(img_path)
result = model.predict(im)
print(result)

我们也可以使用 FastDeploy 提供的可视化函数进行可视化。

import matplotlib.pyplot as plt
vis_im = fd.vision.visualize.vis_segmentation(im, result, 0.5)
plt.imshow(cv2.cvtColor(vis_im, cv2.COLOR_BGR2RGB))

47c073b70549d012ee58766ef61c6db0.png

接下来判断钢筋是否超限,为了便于演示,兼容上面的判断接口。此处将结果导出为mask图片。

import numpy as np
mask = np.reshape(result.label_map, result.shape)
mask = np.uint8(mask)
mask_path = "/home/aistudio/work/PaddleSeg/output/infer_result/mask.png"
cv2.imwrite(mask_path, mask)
# print(mask_path)
largestcomponent(mask_path)
post_img_path = mask_path.replace(".png", "_postprocessed.png")
# print(post_img_path)
excesslimit(post_img_path, "right", 0.7)
# 可视化判断结果
im_path = "/home/aistudio/work/PaddleSeg/output/infer_result/mask_fullpostprocessed.png"
im = cv2.imread(im_path)
plt.imshow(im)

101a423c812da41c453a0203d9a8d26d.png

9892e3f79daf3567042eb769158a991b.png

结论

本项目演示了如何在实际工业场景下,使用 PaddleSeg 开发套件进行语义分割模型训练,并使用 FastDeploy 进行部署应用,解决钢筋长度超限的自动监控问题。结果证明,本技术方案切实可行,可实现端到端全自动的钢筋长度超限监控,为企业生产降本增效。希望本应用范例可以给各行业从业人员和开发者带来有益的启发。

相关文章:

一文解读基于PaddleSeg的钢筋长度超限监控方案

项目背景 钢铁厂生产钢筋的过程中会存在部分钢筋长度超限的问题&#xff0c;如果不进行处理&#xff0c;容易造成机械臂损伤。因此&#xff0c;需要通过质检流程&#xff0c;筛选出存在长度超限问题的钢筋批次&#xff0c;并进行预警。传统的处理方式是人工核查&#xff0c;该方…...

NumPy 数组学习手册:1~5

原文&#xff1a;Learning NumPy Array 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 一、NumPy 入门 让我们开始吧。 我们将在不同的操作系统上安装 NumPy 和相关软件&#xff0c;并查看一些使用 NumPy 的简单代码。 正如“序言”所述&#xff0c;SciPy 与 NumPy 密…...

【C++11】晦涩难懂语法系列:可变参数模板

目录 可变参数模板 1.1 概念 1.2 可变参数模板定义 1.3 参数包的展开方式 1.3.1 递归展开参数包 1.3.2 逗号表达式展开参数包 1.4 STL的emplace系列函数 可变参数模板 1.1 概念 在C语言阶段&#xff0c;我们已经接触过可变参数&#xff0c;比如scand、printf等等 这里…...

计算机组成原理第二章——数据的表示与运算(下)

提示&#xff1a;时光清浅处 一步一安然 文章目录 前言2.3.1 浮点数的表示2.3.2 IEEE7542.2.3 浮点数的运算 前言 本节主要讲三个问题&#xff0c;浮点数的表示&#xff0c;IEEE 754标准&#xff0c;浮点数的加减运算 2.3.1 浮点数的表示 浮点数的作用和基本原理 定点数可表…...

1.mybatis-plus入门及使用

1.什么是MybatisPlus MyBatis-Plus 官网 为什么要学MybatisPlus&#xff1f; MybatisPlus可以节省大量时间&#xff0c;所有的CRUD代码都可以自动化完成MyBatis-Plus是一个MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效…...

JavaWeb开发 —— 前端工程化

目录 一、前后端分离开发 二、YApi 三、前端工程化 1. 环境准备&#xff1a;vue-cli 2. Vue项目创建 四、Vue项目开发流程 一、前后端分离开发 ① 最早的前端开发就是实现页面&#xff0c;顶多再写写JS让页面可以有交互的特效。属于前后端未分离的时代。 早期前后端混合开…...

listener监听器框架

监听器是Web开发中常用的一种组件&#xff0c;用于监听某些事件并根据事件触发相应的处理逻辑。在Spring Boot中使用监听器可以方便地实现对程序中各种事件的监听&#xff0c;比如启动事件、关闭事件等。 首先需要定义一个监听器&#xff0c;通常需要实现ApplicationListener接…...

tp5实现导入excel表到数据库

hello&#xff0c;大家好&#xff0c;好长时间没有更新文章了。最近一直在忙着做项目。所以断更了。 那么好&#xff0c;各位老铁是否想要实现导入导出的功能 请关注我&#xff0c;解密如何实现导入导出&#xff0c; 那么今天先来讲一下用thinkphp5.0 如何实现Excel表格导入数据…...

Python基础-04 字符串

字符串的表示方式 在Python中,可以使用一对单引号/双引号或者一对三个双引号/一对三个单引号表示字符串 a hello b "hello" c hello d """hello""" # 如果字符串里面还有双引号,外面就可以使用单引号 # 反之一样 # 如果字符串里…...

VVC之编码结构

VVC之编码结构&#xff08;新一代通用视频编码的读书笔记&#xff09; 缩写概述EncAppmain函数解读 缩写 缩写含义CVSCoded Video Sequence, 编码视频序列IRAPIntra Random Access Point, 帧内随机接入点GDRGradual Decoding Refresh, 逐渐解码刷新AUAccess Unit, 访问单元PUP…...

FPGA基于SFP光口实现10G万兆网UDP通信 10G Ethernet Subsystem替代网络PHY芯片 提供工程源码和技术支持

目录 1、前言2、我这里已有的UDP方案3、详细设计方案4、vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取 1、前言 目前网上的fpga实现udp基本生态如下&#xff1a; 1&#xff1a;verilog编写的udp收发器&#xff0c;但不带ping功能&#xff0c;这样的代…...

Linux Redis主从复制 | 哨兵监控模式 | 集群搭建 | 超详细

Linux Redis主从复制 | 哨兵监控模式 | 集群搭建 | 超详细 一 Redis的主从复制二 主从复制的作用三 主从复制的流程四 主从复制实验4.1 环境部署4.2 安装Redis&#xff08;主从服务器&#xff09;4.3 修改Master节点Redis配置文件 (192.168.163.100)4.4 修改Slave节点Redis配置…...

整柜海运到美国的规格和收费标准是什么

整柜海运是指将所有货物安装在一个整箱内&#xff0c;由发货人和收货人共同操作&#xff0c;而目的港的收货人一般只有一个&#xff0c;方便操作。整柜海运到美国的主要流程有以下几个步骤&#xff1a;订舱、装柜、报关、海运、清关、提柜和送货。实际上&#xff0c;国际物流出…...

Session和Cookie区别介绍+面试题

Session 会话&#xff1a; 对应的英文单词&#xff1a;session用户打开浏览器&#xff0c;进行一系列操作&#xff0c;然后关闭浏览器。整个过程叫做一次会话一个会话包含多次请求 session机制属于B/S结构的一部分&#xff0c;主要的作用就是为了保存会话状态。(用户登录成功后…...

easyx

普通的画线图什么的 首先我们需要安装一个easyx的图形库&#xff0c;然后把头文件搞出来 #include <stdio.h> #include <easyx.h>//easyx画线啥啥的图形库 #include <graphics.h> #include <math.h> #include <conio.h>//键盘操作的头文件 设…...

记一次科学

华为云与Centos8 华为云99元Hongkong的服务器&#xff1a;1M&#xff0c;1C&#xff0c;2G&#xff0c;40G&#xff0c;自带不可更改的Centos 8.2 64bit 华为yum源不可以&#xff0c;网上找了可用的CentOS8 官方源不支持后配置yum源 # 备份 mv /etc/yum.repos.d/CentOS-Base…...

亚马逊被人差评了怎么办?

第一种&#xff1a; 也是最简单的做法就是通过电话或者邮件联系留差评的买家&#xff0c;大致意思就是按照货值的2-3倍作为赔偿&#xff0c;能不能把差评给删了 赔偿一个普通产品2-3倍的价格比起找服务商删一个差评几百到一千不等可以说是绰绰有余了&#xff0c;碰到那种愿意…...

【目标检测】YOLOv5:修改自己的网络结构

前言 YOLOv5就像一座金矿&#xff0c;里面有无数可以学习的东西。之前的博文一直将YOLOv5当作一个黑盒使用&#xff0c;只考虑模型的输入和输出&#xff0c;以此来对模型进行二次开发。 本篇博文将更近一层&#xff0c;深入到“金矿”内部&#xff0c;来尝试对模型结构进行替换…...

spring boot 工程整合mongodb,遇到的坑

首先说一下背景&#xff0c;因为其他的一个web工程有使用mongo&#xff0c;我想着给另外一个工程把mongo也加过来吧。也是最近做一个发送 丘比特信 的需求&#xff0c;觉得这个信应该是存到 mongodb。结果拿过来遇到了很大的坑&#xff0c;也是对版本对原理不了解吧。 下面介…...

防抖函数(最全 最干净 最好理解)

1.应用场景 1.input输入框 输入远程查询 2.邮箱&#xff0c;手机号验证&#xff0c;用户名验证 3.resize等高评率场景 2.解决问题 高频场景带来的重复渲染 等问题 多次操作 只在操作结束后再执行操作函数 3.具体实现 3.1this问题&#xff08;因为settimeout是window的对…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

SQL进阶之旅 Day 22:批处理与游标优化

【SQL进阶之旅 Day 22】批处理与游标优化 文章简述&#xff08;300字左右&#xff09; 在数据库开发中&#xff0c;面对大量数据的处理任务时&#xff0c;单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”&#xff0c;深入探讨如何通过批量操作和游标技术提…...