介绍

实例分割(instance segmentation)的目的是从图像中分割出每个目标实例的掩模(mask)。与语义分割相比,实例分割不但要区分不同的类别,还要区分出同一种类别下的不同目标实例。如图13-1所示

语义分割的结果中,不同的羊对应的标签是一样的,即都被分配为“羊”的类别,而实例分割的结果中,不同的羊的类别标签一样,但是会有不同的实例号:与目标检测相比,实例分割需要在每个包围盒内再进一步将目标的掩模分割出来。因此,实例分割任务是语义分割任务与目标检测任务的结合。一句话,划分的更加仔细了。

在本章中,我们将介绍经典的基于深度学习的实例分割方法Mask R-CNN,并动手实现相应的实例分割框架。

数据集和度量

由于实例分割与目标检测之间有着紧密的联系,用于这两种任务的数据集和度量也很类似。 MS COCO是最常用的实例分割数据集,mAP是实例分割的评价指标。与目标检测不同的是,这里的mAP是通过Mask IoU进行度量。同目标检测中的Box IoU类似,而不是AP的平均,对于图像中的一个目标,令其真实的掩模内部的像素集合为A,一个预测的掩模内部的像素集合为B,Mask真实掩模预测掩模 IoU通过这两个掩模内像素集合的IoU来度量两个掩模的重合度:

图13-2中黄色部分的面积除以红色的面积。与目标检测中计算mAP的过程一样,对每种类别,通过调节Mask IoU的阈值,可以得到该类掩模交集掩模并集别实例分割结果的PR曲线,PR曲线下方的面积即为该类别实例分割结果的AP,所有类别实例分割结果的AP的平均即为mAP。

Mask R-CNN

既然实例分割结合了目标检测和语义分割,那么实现实例分割的一个很直接的思路就是先进行目标检测,然后在每个预测包围盒里做语义分割。著名的Mask R-CNN模型采用的就是这一思路,从模型的命名可以看出,这是R-CNN系列工作的延续。Mask R-CNN也是由何恺明、Georgia Gkioxari、Piotr Dollar和Ross Girshick提出的,获得了2017年国际计算机视觉大会(International Conference on Computer Vision,ICCV)最佳论文奖一马尔奖(Marr Prize). Mask R-CNN的结构如图I3-3所示。

不难发现,Mask R-CNN是Faster R-CNN的拓展,它们之间的主要区别有3点:

(1)引入特征金字塔网络(feature pyramid network,FPN)与ResNet一起作为主干网络。 FPN作为一种融合多尺度特征信息的手段,在视觉领域有着非常广泛的应用;

(2)提出感兴趣区域对齐(ROI align)取代Faster R-CNN中的ROI池化作为目标区域的特征提取器,用于提取整个候选区域特征并将候选区域特征图尺寸归一化到统一大小,用于后续的预测;

(3)增加了一个用于预测掩模的分支,该分支与分类头和回归头并行。

特征金字塔网络(FPN)

由于图像中的目标大小各不相同,为了能够检测到不同大小的目标,目标检测模型通常需要多尺度检测架构。

图13-4展示了4种不同的用于目标检测的特征提取框架。

图13-4(a)这种架构只在主干网络的最后一层卷积层输出的特征图上做目标检测,故该架构最大的问题是对小目标的检测效果不理想。这是因为小尺度目标的特征会随着主干网络逐层下采样逐渐消失,在最后一层仅有少量的特征支持小目标的精准检测。

图13-4(b)是早期的目标检测算法常用的图像金字塔结构,它通过将输入图像缩放到不同尺度来构建图像金字塔,随后主干网络通过处理这些不同尺度的图像来得到不同尺度的特征图,最后分别在每个尺度的特征图上做目标检测。不难看出,使用图像金字塔最大的问题是主干网络的多次推理会带来计算开销的成倍增长。

图13-4(c)展示的网络架构从主干网络的多个层级都输出特征图,然后在不同空间分辨率的特征图上进行独立的目标检测。显然,这种结构并没有进行不同层之间的特征交互,既没有给深层特征赋予浅层特征擅长定位小目标的能力,也没有给浅层的特征赋予深层蕴含的语义信息,因此对目标检测效果的提升有限。

图13-4(d)展示了FPN的架构。FPN的主要思想是构建一个特征金字塔,将不同层级的特征图融合到一起,从而实现不同大小目标的检测。

具体而言,类似图13-4(C),FPN先使用一个主干网络得到每个层级的特征图,从下到上分别命名为C2、C3、C4,其中的数字2、3 、4(直到 l),代表特征图空间分辨率为原图的1/2,由此得到的深层的特征图空间分辨率小,浅层的特征图空间分辨率大,这一过程称为自底向上。在此之后,FPN构建了一个自顶向下的路径来对不同空间分辨率的特征图进行融合。首先FPN直接输出空间分辨率最小的特征图[图13-4(d)右边第3层,顶层],记为P4,然后对P4进行2倍的上采样,使其空间分辨率大小和C3特征图的空间分辨率保持一致,再通过1×1卷积调整C3的通道数,使其与P4的通道数一致,并将两者进行相加,得到融合的特征图P3[图13-4(d)右边第2层],这一过程称为横向连接这种融合方式迭代地在每层执行,上一层不断与下一层融合,从而实现自顶向下的效果。通过这种方式,FPN可以获取多个尺度的特征,并将这些特征融合在一起,形成了P2、P3、P4,从而提高对多尺度目标检测的准确性和效率。

FPN代码实现(基于PyTorch)

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision.models.resnet import resnet50class FPN(nn.Module):def __init__(self, backbone=resnet50(pretrained=True)):super(FPPN, self).__init__()self.backbone = backbone# Lateral connectionsself.lateral5 = nn.Conv2d(2048, 256, 1)self.lateral4 = nn.Conv2d(1024, 256, 1)self.lateral3 = nn.Conv2d(512, 256, 1)self.lateral2 = nn.Conv2d(256, 256, 1)# Smooth layersself.smooth5 = nn.Conv2d(256, 256, 3, padding=1)self.smooth4 = nn.Conv2d(256, 256, 3, padding=1)self.smooth3 = nn.Conv2d(256, 256, 3, padding=1)self.smooth2 = nn.Conv2d(256, 256, 3, padding=1)# Extra layersself.conv6 = nn.Conv2d(2048, 256, 3, stride=2, padding=1)self.conv7 = nn.Conv2d(256, 256, 3, stride=2, padding=1)def forward(self, x):# Bottom-up pathway (backbone)c1 = self.backbone.conv1(x)c1 = self.backbone.bn1(c1)c1 = self.backbone.relu(c1)c1 = self.backbone.maxpool(c1)c2 = self.backbone.layer1(c1)c3 = self.backbone.layer2(c2)c4 = self.backbone.layer3(c3)c5 = self.backbone.layer4(c4)# Top-down pathwayp5 = self.lateral5(c5)p4 = self.lateral4(c4) + F.interpolate(p5, scale_factor=2, mode='nearest')p3 = self.lateral3(c3) + F.interpolate(p4, scale_factor=2, mode='nearest')p2 = self.lateral2(c2) + F.interpolate(p3, scale_factor=2, mode='nearest')# Smoothp5 = self.smooth5(p5)p4 = self.smooth4(p4)p3 = self.smooth3(p3)p2 = self.smooth2(p2)# Extra pyramid levelsp6 = self.conv6(c5)p7 = self.conv7(F.relu(p6))return p2, p3, p4, p5, p6, p7

感兴趣区域对齐(ROI)

在ROI池化层中,为了得到固定空间分辨率的ROI特征图(如7像素×7像素)并将其送给后续的预测分支,需要将每个ROI的包围盒顶点坐标取整。在将该ROI切分为7×7共49个子窗口的过程中也需要将每个子窗口的坐标取整,如图13-5所示。

在上述过程中,之所以需要取整,是因为将原始图像的候选区域映射到图像特征图中对应的ROI后,ROI顶点坐标可能是非整数,每一个子窗口的坐标也可能是非整数,而提取的特征图上每个位置坐标为整数。因此,通常需要将浮点数坐标取整到最近的整数坐标。但既然是近似,就会引入误差,从而影响检测算法的性能。为了解决这个问题,ROI对齐不再使用取整来处理非整数坐标,而是直接使用这些坐标,如图13-6所示。

那么如何处理非整数坐标并得到特征图上对应位置的值呢?回忆一下之前学过的双线性插值,对于特征图中的任意一个位置,都可以利用双线性插值的方式得到其对应的数值。在这个过程中不会用到取整操作,因此不会引入因坐标取整导致的偏移误差,这有利于实例分割的精度提升。同ROI池化一样,在ROI对齐中,每个ROI将被均分成M×N个子窗口(图中为7×7个)。随后,将每个子窗口再均分成4个小的子窗口,取这4个小子窗口的中心点,根据每个点在特征图中最近的整数坐标对应的特征值,通过插值来计算各自的特征值,再对这4个值进行最大池化(max pooling)或平均池化(average pooling),得到该子窗口的特征值,最终便可以得到空间分辨率为M像素×N像素的ROI特征图。下面我们将介绍如何用代码实现ROI对齐。

ROI对齐的代码实现

import cv2
import numpy as npdef align_roi(image, roi_coords, output_size=(100, 100)):"""对齐ROI区域到指定尺寸"""x, y, w, h = roi_coordsroi = image[y:y+h, x:x+w]aligned = cv2.resize(roi, output_size, interpolation=cv2.INTER_AREA)return aligned

在利用ROI对齐层得到了固定空间分辨率的ROI特征图之后,便可以利用这些特征图进后续的任务。同Faster R-CNN一样,Mask R-CNN在分类和回归分支利用全连接层对ROI进目标类别分类及包围盒回归。与Faster R-CNN不同的是,Mask R-CNN还增加了一条专门用预测掩模的分支

在这一分支中,ROI特征图的大小是14像素×14像素,首先会经过4层卷积层来适应分割任务,随后做2倍上采样得到空间分辨率为28像素×28像的特征图。这是因为空间分辨率大的特征图对于分割精度的提升有正向影响。最后,对该特征图使用1×1卷积层来预测最后的分割结果

Mask R-CNN

Mask R-CNN的损失函数$L$由三部分组成:分类损失$L_{cls}$、包围盒回归损失$L_{box}$和掩模分割损失$L_{mask}$。公式如下:

$L = L_{cls} + L_{box} + L_{mask} $

分类损失
采用交叉熵损失,用于衡量预测类别与真实类别的差异:

包围盒回归损失
采用平滑L1损失,用于优化边界框坐标

掩模分割损失
采用逐像素的二值交叉熵损失,用于优化目标的二值掩模

Mask R-CNN的测试阶段

在测试阶段,Mask R-CNN执行以下操作:

  1. 对候选区域生成包围盒预测和类别预测。
  2. 对每个包围盒内的目标预测其掩模。
  3. 对预测的包围盒进行非极大值抑制(NMS),去除冗余的包围盒。

NMS的公式如下:
对于每个类别,按置信度排序,保留最高置信度的包围盒,并移除与其交并比(IoU)超过阈值$\theta$的其他包围盒:

\text{IoU} = \frac{\text{Area}(B_i \cap B_j)}{\text{Area}(B_i \cup B_j)} > \theta

其中$B_i$$B_j$为两个包围盒,$\theta$为预设阈值(通常为0.5)。

Mask R-CNN代码实现

由于Mask R-CNN代码架构规模比较大,我们将直接调用相关接口进行效果展示。先导入必要的包。

由于Mask R-CNN 和旧版 Keras/TensorFlow 在 Python 3.6 或 3.7 上运行更稳定,所以建议你安装对应的py版本来避免环境问题

下面代码都是在.ipynb文件中运行不同以往

先安装Mask_RCNN

# 导入必要的包
!git clone https://github.com/matterport/Mask_RCNN.git
!cd Mask_RCNN/
!python setup.py install

导入和配置

import ospy
import sys
import random
import math
import numpy as np
import skimage.io
import matplotlib
import matplotlib.pyplot as plt# Root directory of the project
ROOT_DIR = os.path.abspath("../")# Import Mask RCNN
sys.path.append(ROOT_DIR)  # To find local version of the library
from mrcnn import utils
import mrcnn.model as modellib
from mrcnn import visualize
# Import COCO config
sys.path.append(os.path.join(ROOT_DIR, "samples/coco/"))  # To find local version
import coco%matplotlib inline # Directory to save logs and trained model
MODEL_DIR = os.path.join(ROOT_DIR, "logs")# Local path to trained weights file
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")
# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):utils.download_trained_weights(COCO_MODEL_PATH)# Directory of images to run detection on
IMAGE_DIR = os.path.join(ROOT_DIR, "images")

Configurations  配置项


我们将使用基于 MS-COCO 数据集训练的模型。该模型的配置参数存放在 coco.py 文件的 CocoConfig 类中。

为了进行推理任务,需要稍微调整配置以适应需求。具体做法是继承 CocoConfig 类并重写需要修改的属性。


class InferenceConfig(coco.CocoConfig):# Set batch size to 1 since we'll be running inference on# one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPUGPU_COUNT = 1IMAGES_PER_GPU = 1config = InferenceConfig()
config.display()

output:

Configurations:
BACKBONE_SHAPES                [[256 256][128 128][ 64  64][ 32  32][ 16  16]]
BACKBONE_STRIDES               [4, 8, 16, 32, 64]
BATCH_SIZE                     1
BBOX_STD_DEV                   [ 0.1  0.1  0.2  0.2]
DETECTION_MAX_INSTANCES        100
DETECTION_MIN_CONFIDENCE       0.5
DETECTION_NMS_THRESHOLD        0.3
GPU_COUNT                      1
IMAGES_PER_GPU                 1
IMAGE_MAX_DIM                  1024
IMAGE_MIN_DIM                  800
IMAGE_PADDING                  True
IMAGE_SHAPE                    [1024 1024    3]
LEARNING_MOMENTUM              0.9
LEARNING_RATE                  0.002
MASK_POOL_SIZE                 14
MASK_SHAPE                     [28, 28]
MAX_GT_INSTANCES               100
MEAN_PIXEL                     [ 123.7  116.8  103.9]
MINI_MASK_SHAPE                (56, 56)
NAME                           coco
NUM_CLASSES                    81
POOL_SIZE                      7
POST_NMS_ROIS_INFERENCE        1000
POST_NMS_ROIS_TRAINING         2000
ROI_POSITIVE_RATIO             0.33
RPN_ANCHOR_RATIOS              [0.5, 1, 2]
RPN_ANCHOR_SCALES              (32, 64, 128, 256, 512)
RPN_ANCHOR_STRIDE              2
RPN_BBOX_STD_DEV               [ 0.1  0.1  0.2  0.2]
RPN_TRAIN_ANCHORS_PER_IMAGE    256
STEPS_PER_EPOCH                1000
TRAIN_ROIS_PER_IMAGE           128
USE_MINI_MASK                  True
USE_RPN_ROIS                   True
VALIDATION_STEPS               50
WEIGHT_DECAY                   0.0001

创建模型并加载已训练权重

# Create model object in inference mode.
model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=config)# Load weights trained on MS-COCO
model.load_weights(COCO_MODEL_PATH, by_name=True)

Class Names  类名称


模型会对物体进行分类并返回类别 ID,这些整数值用于标识每个类别。某些数据集会为类别分配整数值,有些则不会。例如在 MS-COCO 数据集中,'person'类别对应 1,'teddy bear'对应 88。这些 ID 通常是连续的,但并非始终如此——比如 COCO 数据集中就有对应 70 和 72 的类别,但 71 却不存在。
为了提高一致性,并支持同时从多个数据源进行训练,我们的 Dataset 类会为每个类分配自有的顺序整数 ID。例如,若使用我们的 Dataset 类加载 COCO 数据集,'person'类别将获得 class ID=1(与 COCO 相同),而'teddy bear'类别则为 78(与 COCO 不同)。在将类别 ID 映射到类别名称时需注意这一点。
要获取类名列表,您可以加载数据集后使用 class_names 属性,如下所示。

# Load COCO dataset
dataset = coco.CocoDataset()
dataset.load_coco(COCO_DIR, "train")
dataset.prepare()# Print class names
print(dataset.class_names)
我们不想让你为了运行这个演示就必须下载 COCO 数据集,所以下面提供了类别名称列表。列表中每个类别名称的索引代表其 ID(第一个类别是 0,第二个是 1,第三个是 2,...以此类推)。
# COCO Class names
# Index of the class in the list is its ID. For example, to get ID of
# the teddy bear class, use: class_names.index('teddy bear')
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane','bus', 'train', 'truck', 'boat', 'traffic light','fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird','cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear','zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie','suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball','kite', 'baseball bat', 'baseball glove', 'skateboard','surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup','fork', 'knife', 'spoon', 'bowl', 'banana', 'apple','sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza','donut', 'cake', 'chair', 'couch', 'potted plant', 'bed','dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote','keyboard', 'cell phone', 'microwave', 'oven', 'toaster','sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors','teddy bear', 'hair drier', 'toothbrush']

运行目标检测

# Load a random image from the images folder
file_names = next(os.walk(IMAGE_DIR))[2]
image = skimage.io.imread(os.path.join(IMAGE_DIR, random.choice(file_names)))# Run detection
results = model.detect([image], verbose=1)# Visualize results
r = results[0]
visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], class_names, r['scores'])
Processing 1 images
image                    shape: (476, 640, 3)         min:    0.00000  max:  255.00000
molded_images            shape: (1, 1024, 1024, 3)    min: -123.70000  max:  120.30000
image_metas              shape: (1, 89)               min:    0.00000  max: 1024.00000

Mask-RCNN还要很对应用,具体可见matterport/Mask_RCNN: Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow

本文介绍了实例分割的基本概念及其经典方法Mask R-CNN。实例分割结合了目标检测和语义分割,不仅能区分不同类别,还能识别同一类别下的不同实例。Mask R-CNN在Faster R-CNN基础上引入特征金字塔网络(FPN)和ROI对齐(ROIAlign)技术,并增加掩模预测分支,显著提升了分割精度。文章详细阐述了FPN的多尺度特征融合机制和ROIAlign避免坐标取整误差的优势,并提供了基于PyTorch的FPN实现代码。最后演示了使用预训练Mask R-CNN模型进行实例分割的完整流程,包括环境配置。

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

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

相关文章

水环境遥感分析!R语言编程+多源遥感数据预处理;水体指数计算、水深回归分析、水温SVM预测、水质神经网络建模及科研级可视化制图

系统性地整合R语言编程、遥感数据处理及机器学习建模,涵盖水线提取(水体指数与阈值法)、水深反演(多元回归)、水温预测(支持向量机)、水质评估(神经网络)等核心内容&…

微信公众号/小程序百万级OpenID自动化获取工具

摘要 本报告详细阐述了微信用户列表数据获取与处理工具的设计思路,包括分页处理机制、频率控制策略、断点续传功能和分布式存储方案。针对微信API调用限制和用户数据规模特点,该工具旨在高效、安全地获取和存储微信用户列表数据,同时严格遵守微信API调用频率限制,确保系统…

物联网系统中传感器到网关到物联网平台的传输路径、协议、原理、用途与架构详解

摘要物联网(IoT)系统通过传感器、网关和物联网平台实现数据的采集、传输、处理和应用。本文详细分析了传感器到网关再到物联网平台的传输路径,涵盖直接连接、网关中继、边缘计算、多级网关和混合路径五种方式;介绍了短距离&#x…

SpringBoot自动注入配置类初步实现

一.SpringBoot自动装配SpringBoot 的 自动装配(Auto-Configuration) 是它的核心特性之一,它让开发者可以 "开箱即用",避免手动配置大量的 XML 或 Java Config。它的核心思想是:"约定优于配置"&…

直播预告|鸿蒙生态中的AI新玩法

想知道鸿蒙生态里 AI 能玩出啥新花样? 8 月 14 日(周四)20:00 ,「开发者・面对面 坚果派特辑 —— 鸿蒙生态中的 AI 新玩法」直播来袭! 🔍 直播亮点抢先看 AI赋能鸿蒙产品开发:将分享如何利用AI…

智能合约:区块链时代的“数字契约革命”

一、技术原理与核心特征1. 定义与本质智能合约是运行在区块链上的自动化程序,通过代码定义业务规则,在预设条件满足时自动执行操作(如资金转移、信息更新),无需人工干预。其核心特性包括:自动执行&#xff…

【数据分析】比较SparCC、Pearson和Spearman相关性估计方法在合成组学数据上的表现

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 加载R包 模拟数据 构建网络 RMSE指数计算 画图 总结 系统信息 介绍 在生物信息学和生态学研究中,组学数据的分析越来越依赖于对微生物群落或基因表达数据中物种或基因间相关性的…

Google C++ 风格指南

文章目录背景介绍风格指南的目标C 版本头文件自包含头文件#define 防护包含所需内容前置声明在头文件中定义函数头文件包含顺序与命名规范作用域命名空间内部链接非成员函数、静态成员函数与全局函数局部变量静态与全局变量关于析构的决策关于初始化的决策常见模式thread_local…

安装部署_WVP流媒体

文章目录一、DEV_WVP流媒体开发手册1、搭建流媒体服务clone代码:安装编译器cmake构建和编译项目修改配置文件启动项目2、搭建GB28181协议视频平台安装 jdk, nodejs, maven, git安装redis安装postgresqlclone代码编译前端代码编译后端代码配置文件修改3、设备接入测测…

软件I2C实现(2):I2C协议实现

0 参考资料 I2C 总线规范.pdf 1 I2C协议实现 1.1 SCL、SDA引脚初始化 将SCL、SDA初始化为开漏输出,电平设置为高电平(使用外部上拉电阻拉高)。 /*** @brief 软件I2C初始化** @param sw_i2c_cfg 软件I2C配置指针*/ int sw_i2c_init(sw_i2c_cfg_t *sw_i2c_cfg) {GPIO_InitT…

疯狂星期四文案网第40天运营日记

网站运营第40天,点击观站: 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 今日访问量 今日搜索引擎收录情况 必应秒发秒收 百度收录很慢 网站优化点 优化seo 修复已知bug

【大语言模型 01】注意力机制数学推导:从零实现Self-Attention

注意力机制数学推导:从零实现Self-Attention - 开启大语言模型的核心密码 关键词:注意力机制、Self-Attention、Transformer、数学推导、PyTorch实现、大语言模型、深度学习 摘要:本文从数学原理出发,详细推导Self-Attention的完整…

2025 环法战车科技对决!维乐 Angel Glide定义舒适新标

环法赛场不仅是顶尖车手的竞技舞台,更是自行车科技的时尚秀场。然而经常骑行的朋友都知道,当顶级战车遇上专业坐垫,方能成就完美骑行体验。2025 年环法赛场上的新战车们各展神通,而维乐 Angel Glide 坐垫以其独特的科技与设计&…

VS Code配置MinGW64编译ALGLIB库

VS Code用MinGW64编译C代码安装MSYS2软件并配置ALGLIB库和测试引用库代码的完整具体步骤。 1. 安装 MSYS2 下载 MSYS2: 访问 MSYS2 官网下载最新安装包(如 msys2-x86_64-latest.exe) 安装: 运行安装程序,默认路径为 C…

《WINDOWS 环境下32位汇编语言程序设计》第2章 准备编程环境

2.1 Win32可执行文件的开发过程 在DOS下,生成一个可执行文件的步骤比较简单,用编译器将源程序编译为obj文件,再用链接器将obj文件链接成exe文件,不同语言的开发过程都差不多。 DOS可执行文件中的内容是由源程序中所写的代码和数…

kubernetes(4) 微服务

一、什么是微服务在 Kubernetes 中,控制器负责维持业务副本,但真正把业务“暴露”出去的是 Service。 一句话理解:Service 一组 Pod 的稳定访问入口 4 层负载均衡Ingress 7 层路由 统一入口 灰度 / 认证 / 重写等高级能力默认情况下&…

Pandas 2.0 + Arrow 加速、Dask vs Ray、Plotly 可视化:数据分析的未来

在大数据与人工智能时代,数据分析与可视化的技术栈正在快速演进。过去十年,Pandas 几乎是数据科学家的“瑞士军刀”,Matplotlib 和 Seaborn 是最常用的可视化工具。但如今,随着数据规模与分析需求的增长,新的趋势正在出现: Pandas 2.0 引入 Apache Arrow 后端,性能显著提…

windows扩展(外接)显示器位置调节

概述有的时候我们想把屏幕往左或往右拖动,默认情况下,屏幕都是默认往右拖动的,如果想往左拖动,则需要进行设置。具体步骤如下:当然不止这些还可以往上调,下调等多个位置可调至,这里只显示左右调…

【分数求和2】

题目&#xff1a;分数求和&#xff08;1/22/33/44/55/66/77/88/9&#xff09;代码实现&#xff1a;#include <stdio.h>int main(){double sum 0.0;int i;for(i2;i<10;i){sum((i-1.0)/i);}printf("1/22/33/44/55/66/77/88/9%f\n",sum);return 0;} 注&#x…

软件SPI实现(3):SPI协议测试(使用W25Q64)

0 参考资料 SPI通信协议中文版(SPIV3).pdf 1 SPI协议测试(使用W25Q64) 1.1 测试方法 这里使用W25Q64作为SPI从机,测试实现的软件SPI工作是否正常。测试步骤如下: (0)使用SPI模式0 (1)使用sw_spi_tx_rx_nbyte API向W25Q64起始地址0写入32字节数据 (2)使用sw_spi_tx_…