医学图像处理

news2024/11/23 1:41:18

医学图像处理

    • opencv批量分片高像素图像
    • 病理图像数据增强
      • 提升样本多样性
        • 基于 imgaug、skimage 实现色彩增强
      • 降低样本多样性
        • 基于 DCGAN、TransposeConv 完成染色标准化
      • 精细化提取特征
      • 自动生成数据标注
    • 分类场景下的医学图像分析
    • 分割场景下的医学图像分析
    • 检测场景下的医学图像分析

 


opencv批量分片高像素图像

医学图像通常是大像素(1920x1080)、超大像素(4096x2160)。

深度学习输入数据尺寸通常是 640x640、32x32。

所以我们会切分医学图像, 变成小像素片, 并对每一个方片识别或预测。

因为没有病理图,只能用相似的星辰图代替:

  • 星辰和病灶细胞一样,可能分布在图像各个位置,也可以集中在图像上的某个区域
  • 而且都非常小,可能不到图的1%

    方片尺寸最小是 1x1, 一般我们用 50x50

怎么实现这种分割呢?

  • 选定截取区域
  • 截取保存
# 截取图像[高的起点:高的终点,宽的起点:宽的终点],并保存
cv2.imwrite(os.path.join(path, "1.jpg"), imgcopy[0:1200,0:1200]

每个方片尺寸为 50*50,左上角第一个被切分的方片索引为 imgcopy[:50, :50],紧接着左数第二个方片的索引为 imgcopy[:50,50:100],第三个方片索引为 imgcopy[:50,100:150],第一行所有方片被表示为 ingcopy[:50, x:x+50]。

只要在宽度上循环,每次让宽的起点增加50,宽的终点增加50,就可以做第一行的截取。

imgcopy = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).copy # 每次分割前,获取完整的原始图像

imgheight = imgcopy.shape[0]  # 获取高度
imgwidth = imgcopy.shape[1]  # 获取宽度

patch_height = 50  # 方片尺寸50*50
patch_weight = 50

for y in range(0, imgheight, patch_height):  # y 是高的起点
    for x in range(0, imgwidth, patch_weight):  # x 是宽的起点
        if patch_height > imgheight or patch_weight > imgwidth: # 边界判断,如果图片小于截取尺寸取消
            break  
       
        y_ = y + patch_height
        x_ = x + patch_weight
        
        if imgheight >= y_ and imgwidth >= x_:   # 如果图片已经被截取到连50都到不得了,这部分就舍去,不影响
            patch = imgcopy[y:y_, x:x_]
            cv2.imwrite(os.path.join(path, "x"+str(x)+"_"+str(x_)+"y"+str(y)+"_"+str(y_)+".jpg"), patch)
            # 保存截取图像
            
            cv2.rectangle(imgcopy, (x,y), (x_,y_),(255,255,255),2) # 把刚刚截取区域在原图上用白色矩形圈出来

分割后。读取大批量文件:

def load_images_from_folder(folder): # 批量读取文件夹中的图片
   images = []   # 把所有方片保存在列表
   for filename in os.listdir(folder):
       img = cv2.imread(os.path.join(folder, filename))
       if img is not None:
           images.append(img)
   return images
  
images = load_images_from_folder("分割文件夹路径")

完整代码:

import cv2
import os
import matplotlib.pyplot as plt

path = r"文件夹路径"
img = cv2.imread(os.path.join(path, "图片名字.jpg"))

if img is None:
    	print("opencv读取图像时,没有成功也不会报错")
    else:
        print("读取图像成功")
        
imgcopy = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).copy # 将BGR颜色空间的图像转换为RGB颜色空间,并创建一个副本以供后续使用。每次分割前,获取完整的原始图像

def extract_images_from_folder(folder):
    """对图像进行批量分片(对一个文件夹中所有的图像进行分片)"""
    
    # 图像导入
    for filename in os.listdir(folder):
        img = cv2.imread(os.path.join(folder, filename))
        
        if img is not None:
            # 如果导入成功,则创建该图片专属的文件夹
            subfolder = os.path.join(PATH,filename.split(".")[0])
            if os.path.exists(subfolder):
                print("folder exists")
            else:
                os.mkdir(subfolder)
            
            # 开始分割,所有被分割出的切片都位于该图片的文件夹中
            imgcopy = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).copy()
            imgheight = imgcopy.shape[0]
            imgwidth = imgcopy.shape[1]

            patch_height = 50
            patch_weight = 50

            for y in range(0, imgheight, patch_height):
                for x in range(0, imgwidth, patch_weight):
                    if patch_height > imgheight or patch_weight > imgwidth:
                        break
                    y_ = y + patch_height
                    x_ = x + patch_weight
                    if imgheight >= y_ and imgwidth >= x_:
                        patch = imgcopy[y:y_, x:x_]
                        # 将每一张图像保存到单独的文件夹
                        cv2.imwrite(os.path.join(subfolder,str(filename.split(".")[0])+"x"+str(x)+"_"+str(x_)+"y"+str(y)+"_"+ str(y_) +".jpg")
                                    , patch)
                        # 保存之后,在原始图像上对当前索引出的区域绘制白色边框
                        # 注意这一操作将会在正在被切片的图像上进行
                        cv2.rectangle(imgcopy # 要绘制长方体的对象
                                      , (x, y), (x_, y_) # 绘制长方体的4角的坐标
                                      , (255, 255, 255) # 使用的颜色
                                      , 2 # 线条的粗细,数字越大越粗
                                     )
            #循环完毕后,绘制被我们分割后的图像            
            plt.figure(dpi=300)
            plt.imshow(imgcopy)
            plt.axis("off");
            
extract_images_from_folder(PATH)

使用函数 load_images_from_folderextract_images_from_folder 对任意图像进行批量分割处理了。

病理图像数据增强

不同类型的图像需要使用不同的预处理和增强方式,主要是因为不同图像成像过程存在的干扰因素是大不相同的。

对高像素图像进行分片解释医疗特有的预处理方式。读这个领域数据处理和数据增强的论文,找出有用的方法。

因为恶性病灶原色往往比良性病灶越深。所以色彩差异是神经网络需要学习的一大关键点。

但是模态太多,不同实验室、不同专业人员、不同批次染色剂、不同扫描仪、不同玻片原材料、不同组织对颜色的响应程度等因素而引起的颜色差异,影响学习效果

病理图像的预处理方式、增强:排除染色操作干扰,提升模型泛化能力。

色彩的本质是明度,灰度图也有明度差异,彩色图像的丰富信息要最大程度保留。

病理数据增强:

  • 提升样本多样性:训练集覆盖尽可能多的色彩,提升训练集多样性
  • 降低样本多样性:把所有图像(训练集和测试集)进行色彩标准化,让所有图像尽量在色彩上一致,避免不同染色操作、不同模态的影响
  • 精细化提取特征:病灶极其微小(如肺癌结点大小1mm见方),需要超精细化特征提取,而非多尺度特征,传统去噪方法很容易把关键特征去除
  • 自然光成像,像素范围0-255 -> 反射成像几千,x光就是小数了
  • 样本比例极度不平衡,病灶极小块才是正样本,把正样本抽出来,无限扩充
  • 自动生成数据标注,用一张已标注图,生成其他所有未标注图的数据和标签

提升样本多样性

提升样本多样性:

  • 随机仿射变换:对图像随机移动、随机旋转、随机拉伸、随机透视等
  • 随机噪声:高斯噪声、脉冲噪声、散粒噪声等
  • 随机线性变换:对像素随机亮度、随机对比度、随机色相、随机饱和度、随机色温
  • 改变色彩空间:RGB-HSV、基于反卷积的RGB-H&E、RGB-HED等
  • 针对单通道的随机线性变换(随机加减乘除、随机调整亮度和对比度)
  • 色彩均衡、自动对比度、随机翻转、随机剪裁或填充

针对单通道的随机线性变换,是公认效果很好的手段,具体可以参考以下的论文:

  • 为H&E染色的组织病理学定制自动数据增强
  • HE染色增强改进了用于组织病理学有丝分裂检测的卷积网络的泛化

基于 imgaug、skimage 实现色彩增强

import imgaug   # 19个增强板块:https://imgaug.readthedocs.io/en/latest/source/api.html
import skimage
import imgaug as ia
from imgaug import augmenters as iaa
from skimage import io

imgs = io.imread_collection("图片路径\\*.jpg")                 # 读取所有.jpg图像

aug = iaa.Affine(scale={"x":(0.6, 1.0)}, "y":(0.8, 1.2)},                  # 在 x、y 轴上按比例缩小
				 translate_percent = {"x":(-0.05, 0.2), "y":(-0.2, 0.2)}   # 在 x、y 轴上、下移动
				 rotate = (-25, 25)                                        # 顺时针、逆时针旋转的角度范围
				 shear = -20                                               # 移动图像的一轴,可以将正方形变为菱形,梯形
)
imgs_aug = aug(images = imgs)                                              # 输入图像,仿射变换
io.imshow_collection(imgs[:12])                              # 显示原图效果
io.imshow_collection(imgs_aug[:12])                          # 显示变化效果

aug = iaa.AdditiveGaussianNoise(loc=10,                      # 高斯分布的均值,均值越大噪声越多
								scale = (0.1*255, 0.5*255),  # 方差范围,方差越大噪声越多
								per_channel = True           # 为每个通道单独添加噪声,否则全部通道共享噪声								)
imgs_aug = aug(images = imgs)                                # 输入图像,随机抽取像素点为噪声

aug = iaa.MultiplyAndAddToBrightness(mul = (0.5, 2), add=(-100, 100))      # 随机乘、加亮度 ax+b 
imgs_aug = aug(images = imgs) 

aug = iaa.MultiplyHueAndSaturation(mul_hue(0.5, 2), mul_saturation=(2,3))  # 随机加倍色相(图像颜色)、饱和度(鲜艳程度)
imgs_aug = aug(images = imgs) 

aug = iaa.pillike.EnhanceContrast(factor=(0, 3))             # 增强图像的对比度
imgs_aug = aug(images = imgs) 

img = io.imread(train.iloc[0,1])                             
aug = iaa.ChangeColorTemperature(kelvin=(1000,11000)).augment_image       # 随机色温,按照开尔文温度对颜色进行调整,区间在[1000, 40000]
img_aug = aug(img)
plt.figure(figsize=(1.5, 1.5))
io.imshow(img_aug)

aug = iaa.pillike.Equalize()                                 # 色彩均衡
aug = iaa.pillike.Autocontrast(cutoff=5)                     # 自动对比值     
aug = iaa.Fliplr(p=0.5)                                      # 随机对 50% 的图像进行翻转
aug = iaa.CropAndPad(percent=(0.1, 0.3))                     # 随机裁剪或填充
aug = iaa.ChangeColorspace(to_colorspace="HSV")              # 改变色彩空间,RGB -> HSV

方案一:打包除色彩空间外的全部预处理方法:

seq1 = iaa.Sequential( [
    iaa.Resize(256),
    iaa.Fliplr(0.5), 
    iaa.Flipud(0.5),
    iaa.CropAndPad(percent=(0.01, 0.02)),
    iaa.MultiplyAndAddToBrightness(mul=(0.7, 1.2), add=(-10,10)),
    iaa.MultiplyHueAndStauration(mul_hue=(0.8, 1.2), mul_saturation=(0.8, 1.2),
    iaa.pillike.EnhanceContrast(factor=(0.75, 1.25)),
    iaa.Sometimes(0.5, iaa.AdditiveGaussianNoise(loc=1, scale=(0, 0.05*255), per_channel=0.5)),
    iaa.Add((-20, 5)),
    iaa.Multiply((0.8, 1.2), per_channel=0.2),
    iaa.Affine(scale={"x":(0.9, 1.1), "y":(0.9, 1.1)},
    translate_percent={"x":(-0.05, 0.05), "y":(-0.05, 0.05)},
    rotate=(-10, 10),
    shear=(-3, 3))
    ], random_order=True)
    
    imgs_aug = seq1(images=imgs)

数据变换的操作序列:

'''根据输入的参数生成了用于数据变换的操作序列,并以字典的形式返回相应的变换操作序列。这些操作序列用于将输入的图像数据进行增强、转换和归一化等处理,以便在训练和测试中使用'''
def alltransform( key = "train", plot = "False" )
    train_sequence = [seq1.augment_image, transforms.ToPILImage()]                 
    # 定义了在训练集上进行数据增强的操作序列。其中 seq1.augment_image 是一种数据增强操作,transforms.ToPILImage() 是将增强后的图像转换为 PIL Image 对象。
    test_val_sequence = [iaa.Resize(256).augment_image, transforms.ToPILImage()]
    # 定义了在验证集和测试集上进行数据增强的操作序列。iaa.Resize(256).augment_image 是将图像调整为指定大小的数据增强操作。
    
    if plot == False:
        train_sequence.extend( [transforms.ToTensor(), transforms.Normalize( [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] ) ] )
        # 在训练集操作序列中添加了将图像转换为张量(transforms.ToTensor())和归一化操作(transforms.Normalize())。
        test_val_sequence.extend([transforms.ToTensor(), transforms.Normalize( [0.485, 0.456, 0.406], [0.229, 0.224, 0.225] ) ] )
        # 在验证集和测试集操作序列中添加了将图像转换为张量和归一化的操作。
        
    data_transforms = {'train':transforms.Compose(train_sequence), 'test_val':transforms.Compose(test_val_sequence))
    # 创建了一个字典 data_transforms,其中包含了训练集和验证集/测试集对应的变换操作序列。
    return data_transforms[key]
    # 根据给定的 key 返回相应的数据变换操作序列。

自定义数据集:

''' 定义了一个自定义数据集类 CustomDataset,其中的 __init__ 函数用于初始化数据集,__len__ 函数用于返回数据集长度,__getitem__ 函数用于获取指定索引的样本。同时,通过 CustomDataset 类的实例化,可以加载训练数据集并应用指定的变换操作 '''
class CustomDataset( Dataset ):                  # 定义了一个自定义数据集类 CustomDataset,继承自 torch.utils.data.Dataset 类。
    def __init__( self, df, transform=None):     # 定义了类的初始化函数,接受参数 df 和 transform。df 是一个包含数据路径和标签的数据框,transform 是一个可选的数据变换操作。
        super().__init__()                       # 调用父类的初始化函数。
        self.path_label = df                     # 将传入的数据框赋值给类属性 path_label,用于存储数据路径和标签。
        self.transform = transform               # 将传入的变换操作赋值给类属性 transform,用于数据变换。
        
    def __len__(self):                           # 定义了 __len__ 函数,用于返回数据集的长度。
        return self.path_label.shape[0]          # 返回数据集中样本的数量。
    
    def __getitem__(self):                       # 定义了 __getitem__ 函数,用于获取指定索引 idx 的样本。
        if torch.is_tensor( idx )                # 如果索引 idx 是一个张量,则将其转换为列表。
            idx = idx.tolist()                   # 从数据框中获取指定索引 idx 对应的患者ID。
            
        patient_id = self.path_label["patient_id"].values[idx]    # 从数据框中获取指定索引 idx 对应的患者ID。
        image_path = self.path_label["path"].values[idx]          # 从数据框中获取指定索引 idx 对应的图像路径。
        
        if self.transform:                       # 如果指定了变换操作,则对图像应用变换。
            image = self.transform(image)
            
        sample = {"patch":image,                 # 创建一个样本字典,包含图像数据、标签和患者ID。
                   "label":label,
                   "patient":patient_id}
        return sample                            # 返回样本字典

train_ = CustomDataset( train, transform = alltransform(key="train", plot=True))  # 创建一个自定义数据集实例 train_,传入训练数据框和变换操作。

方案二:将图像转换为 HED 空间后,对单一通道完成线性变换,再转换 RGB

RGB 转 HED 步骤要多一点:

# 改变色彩空间,RGB -> HED
from skimage.color import rgb2hed
from skimage.exposure import rescale_intensity
img = io.imread(train.iloc[0,1])
img_aug = rgb2hed(img)
for channel in [0, 1, 2]:
	img_aug[:, :, channel] = rescale_intensity(img_aug[:, :, channel], out_range=(0, 1))

from matplotlib.colors import LinearSegmentedColormap
# 分解为三通道图
cmap_hema = LinearSegmentedColormap.from_list('mycmap', ['mediumvioletred', 'white'])    # 突出细胞核
cmap_dab = LinearSegmentedColormap.from_list('mycmap', ['white', 'brown'])               # 和原图最接近
cmap_hema = LinearSegmentedColormap.from_list('mycmap', ['crimson', 'white'])            # 突出形状、纹理

# 根据论文《H&E染色增强改进了用于组织病理学有丝分裂检测的卷积网络的泛化》
# 将图像转为 HED 通道后,分别在通道随机加减乘除后,再将色彩空间换回 RGB,可提高模型泛化能力

seq_all = iaa.Sequential(     # 定义了一个包含多个增强操作的序列 seq_all,使用iaa.Sequential()函数创建。该序列中的增强操作按顺序应用于图像。其中包括调整大小、水平翻转、垂直翻转、亮度调整、色调和饱和度调整以及仿射变换等。最后的 .augment_image 表示将这个序列应用于图像。
	[iaa.Resize(256), iaa.Fliplr(0.5), iaa.Filpud(0.5),
	 iaa.MultiplyAndAddToBrightness(mul=(0.8, 1.2), add=(-10, 10)),
	 iaa.MultiplyHueAndSaturation(mul_hue=(0.9, 1.2), mul_saturation=(0.8, 0.9)),
	 iaa.Affine( scale={'x':(0.9, 1.1), 'y':(0.9, 1.1)}, translate_percent={'x':(-0.05, 0.05), 'y':(-0.05, 0.05)}, rotate=(-10, 10), shear=(-3, 3) ) ] ).augment_image

def seq_channel( img, channel=0 ):  # 定义了一个名为 seq_channel 的函数,用于对图像的指定通道进行增强。
	seq = iaa.WithChannels([channel]), [ iaa.pillike.Enhannels([factor=(0.6, 0.8)]),     
		  iaa.Sometimes(0.5, iaa.AdditiveGaussianNoise(loc=1, scale=(0, 0.001 * 255))),
		  iaa.Add(-10, 10),
		  iaa.Nultiply(0.5),
		  iaa.Sharpen(alpha=(0.1, 1.0), lightness=(0.75, 1.5))
	]).augment_image
	return seq(img)

image = io.imread(train.iloc[0, 1])
img = seq_all(image)  # 先对所有通道进行处理
img_hed = skimage.color.rgb2hed(img)
for channel in [0, 1, 2]:
	img_hed[:, :, channel] = rescale_intensity(img_hed[:, :, channel], out_range=(0, 255))
img_hed = img_hed.astype("uint8")
for channel in [0, 1, 2]:  # 对三通道循环处理
	img_aug = seq_channel(img_hed, channel)

img_rgb = skimage.color.hed2rgb(img_hub)   # 转回rgb
for channel in [0, 1, 2]:   # 归一化
	img_rgb[:, :, channel] = rescale_intensity(img_rgb[:, :, channel], out_range=(0, 255))

img_rgb = img_rgb.astype("uint8")
io.imshow(img_rgb)

打包以上的过程,放入 transform 里,Pytorch 就可以调用。

class SingleChannelTrabsform(object):
	def __int__(self):
		seq_all = iaa.Sequential(    
			[iaa.Resize(256), iaa.Fliplr(0.5), iaa.Filpud(0.5),
	 		iaa.MultiplyAndAddToBrightness(mul=(0.8, 1.2), add=(-10, 10)),
	 		iaa.MultiplyHueAndSaturation(mul_hue=(0.9, 1.2), mul_saturation=(0.8, 0.9)),
	 		iaa.Affine( scale={'x':(0.9, 1.1), 'y':(0.9, 1.1)}, translate_percent={'x':(-0.05, 0.05), 'y':(-0.05, 0.05)}, rotate=(-10, 10), shear=(-3, 3) ) ] ).augment_image

	def seq_channel( img, channel=0 ):  # 定义了一个名为 seq_channel 的函数,用于对图像的指定通道进行增强。
		seq = iaa.WithChannels([channel]), [ iaa.pillike.Enhannels([factor=(0.6, 0.8)]),     
		  	  iaa.Sometimes(0.5, iaa.AdditiveGaussianNoise(loc=1, scale=(0, 0.001 * 255))),
		      iaa.Add(-10, 10),
		      iaa.Nultiply(0.5),
		      iaa.Sharpen(alpha=(0.1, 1.0), lightness=(0.75, 1.5))
	       ]).augment_image
		return seq(img)
	self.seq_channel = seq_channel

	def __call__(self, sample):
		image = sample
		img = seq_all(image)
		img_hed = skimage.color.rgb2hed(img)
		for channel in [0, 1, 2]:
			img_hed[:, :, channel] = rescale_intensity(img_hed[:, :, channel], out_range=(0, 255))
		img_hed = img_hed.astype("uint8")
		for channel in [0, 1, 2]:
			img_aug = seq_channel(img_hed, channel)

		img_rgb = skimage.color.hed2rgb(img.aug)
		for channel in [0, 1, 2]:
			img_rgb[:, :, channel] = rescale_intensity(img_rgb[:, :, channel], out_range=(0, 255))
		img_rgb = img_rgb.astype("uint8")
		return img_rgb

经过比对,方案一实现提升样本多样性方法效果更好。

降低样本多样性

传统方法是,先有一个标准(寻找一个标准图像作为目标图像),再将其他所有图像按照目标图像进行标准化。

  • 色彩匹配:将输入图像转换为 LAB 空间(L是亮度,A是从绿色到红色的分量,B是从蓝色到黄色的分量),并以通道为单位,将所有通道的值中心化至 0 均值(在所有像素上减去一个值让均值变为0),再缩放到方差为 1(再把所有像素除以一个数让方差为 1),然后重新标准化以目标图像统计信息。
  • 染色分离:使用反卷积(如 Macenko、Khan染色分离)将数据集上的染色去除,在从目标图像中提取染色特征向量对去除染色的图像进行卷积,最终生成基于目标图像重新染色的图像。

这种方法的缺陷是,必须规定一张标准图像,如果该目标图像与其他数据差异太大,就会导致被标准化的图像被破坏。

现在流行用 GANs 完成色彩标准化,以及比 GAN 更简单的预处理方法。

基于 DCGAN、TransposeConv 完成染色标准化

生成对抗网络:借助真实数据生成一组假数据训练网络,输出一组以假乱真的数据

先把彩图灰度化,把灰度图输入生成器,生成彩色图像,用生成彩色图像和原来彩色图像进行判别,在对抗的过程中,让俩者越来越接近

参考论文:

  • 使用 GAN 处理组织病理学图像的神经染色式迁移学习

GAN 是处理二维数据的线性层组成,无法处理图像数据,需要使用 DCGAN 处理医疗图像,完成染色标准化。

GAN 好处:生成以假乱真的隐私数据,如医疗数据涉及隐私,数量是很少的,我们可以用真实数据生成一组假数据,用这组接近真实数据的假数据去训练。

class Discriminator(nn.Module):
	def __init__(self, in_features):
		super.__init__()
		self.disc = nn.Sequential(nn.Linear(in_features, 128),
			nn.LeakyReLU(0.1),
			nn.Linear(128, 1),
			nn.Sigmoid())
			
	def forward(self, data):
		return self.disc(data)

class Generator(nn.Module):
	def __init__(self, in_features, out_features):
		super().__int__()
		self.gen = nn.Sequential(nn.Linear(in_features, 256),
				   nn.LeakyReLU(0.1),
				   nn.Linear(256, out_features),
				   nn.Tanh())
	def forward(self, z):
		gz = self.gen(z)
		return gz

batch_size = 32
lr = 3e -4
num_epochs = 50
realdata_dim = 28 * 28 * 1
z_dim = 64

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(0.5), (0.5)])

dataset = dest.MNIst(root = r"文件路径", transform = transform, download = True)
dataloader = DataLoader(dataset, batch_size = batch_size, shuffle = True)

fixed_noise = torch.randn((batch_size, z_dim)).to(device)

gen = Genaretor(in_features = z_dim, out_features = realdata_dim).to(device)
disc = Discriminator(in_features = realdata_dim).to(device)
criterion = nn.BCELoss(reduction="mean")

精细化提取特征

自动生成数据标注

分类场景下的医学图像分析

分割场景下的医学图像分析

检测场景下的医学图像分析

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

揭秘Word高级技巧:事半功倍的文字处理策略

Microsoft Word是一款广泛使用的文字处理软件,几乎每个人都有使用过它的经历。但是,你是否知道Word中隐藏着许多高级技巧和功能,可以帮助你事半功倍地处理文字?在本文中,我们将揭秘一些Word的高级技巧,让你…

[] Adobe XD免费版功能一览,设计师们速来免费使用!

Adobe XD 作为一款流行的原型设计工具,免费使用对许多设计师来说是非常重要的。但现在 Adobe XD 的免费版体验已经不是那么舒适了。别担心,本文将为你推荐真正免费好用的 Adobe XD 替代工具。 Adobe XD 是免费的吗? Adobe XD 在早期确实是完…

Licheepi Nano屏幕驱动并输出打印信息

Licheepi Nano买回来好长时间,没咋玩,最近看了一个利用F1C100S自制迷你电脑的博客,里面主要参考的就是Licheepi Nano。我打算先在Licheepi Nano上完成屏幕操作、Debian文件系统和USB键盘等内容,这里介绍怎样利用Licheepi Nano外接…

Java进阶(1)——JVM的内存分配 反射Class类的类对象 创建对象的几种方式 类加载(何时进入内存JVM) 注解 反射+注解的案例

目录 引出java内存分配java内存分布概略图堆方法区常量池 创建对象内存分配 反射class文件的底层类加载顺序1.检查2.开辟静态资源空间3.常量池4.其他...5.创建一个唯一的类的对象获取Class对象的几种方式 创建对象几种方式new 看到new : new Book()反射 Class.forName(“包名.类…

断路器回路电阻试验

试验目的 断路器回路电阻主要取决于断路器动、 静触头的接触电阻, 其大小直接影响正常 运行时的发热情况及切断短路电流的性能, 是反应安装检修质量的重要数据。 试验设备 回路电阻测试仪 厂家: 湖北众拓高试代销 试验接线 对于单断口的断路器, 通过断口两端的接线…

8年测试经验,接口测试总结,测试进阶之路一篇打通...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、什么是接口测试…

开源数据库Mysql_DBA运维实战 (部署服务篇)

前言❀ 1.数据库能做什么 2.数据库的由来 数据库的系统结构❀ 1.数据库系统DBS 2.SQL语言(结构化查询语言) 3.数据访问技术 部署Mysql❀ 1.通过rpm安装部署Mysql 2.通过源码包安装部署Mysql 前言❀ 1.数据库能做什么 a.不论是淘宝,吃鸡,爱奇艺…

k8sday02

第四章 实战入门 本章节将介绍如何在kubernetes集群中部署一个nginx服务,并且能够对其进行访问。 Namespace ​ Namespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 ​ 默认情况下&…

机器学习实战1-kNN最近邻算法

文章目录 机器学习基础机器学习的关键术语 k-近邻算法(KNN)准备:使用python导入数据实施kNN分类算法示例:使用kNN改进约会网站的配对效果准备数据:从文本文件中解析数据分析数据准备数据:归一化数值测试算法…

淘宝API接口为开发者提供了与淘宝平台进行数据交互和操作的便捷途径

淘宝API接口是指淘宝开放平台提供的一套接口,用于与淘宝网进行数据交互和操作。通过使用淘宝API接口,第三方开发者可以实现商品搜索、店铺信息获取、订单管理、商家服务等功能,从而实现与淘宝平台的对接和数据共享。 淘宝API接口的使用可以帮…

C语言赋值号的运算顺序

从右到左。 int & f(int & a) { printf("参数 %d\n", a); return a; } int main(void) {int a 9;int b 3;f(a) f(b);// 运行到此处,a 3,b 3return 0; } 输出

卡尔曼滤波算法demo

代码 learn_kalman.py #codingutf-8 import numpy as np import time from kinematic_model import freedrop from controller import kalman_filterimport matplotlib.pyplot as plt # 支持中文 import matplotlib as mpl mpl.rcParams[font.family]SimHei plt.rcParams[a…

每天一道leetcode:剑指Offer 25.合并两个链表

今日份题目&#xff1a; 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 示例 输入&#xff1a;1->2->4, 1->3->4 输出&#xff1a;1->1->2->3->4->4 提示 0 < 链表长度 < 1000 题目思路 递归…

BL302嵌入式ARM控制器:高性能处理器驱动的储能优化利器

嵌入式ARM控制器钡铼技术BL302系列是工业级坚固型工业控制器&#xff0c;采用NXP的高性能处理器I.MX6ULL&#xff0c;搭配先进的ARM Cortex-A7构架&#xff0c;运行速度高达800MHz&#xff0c;具有高度的稳定性。本产品最高可提供4路RS485/RS232&#xff0c;1路CAN口&#xff0…

嵌入式开发学习(STC51-13-温度传感器)

内容 通过DS18B20温度传感器&#xff0c;在数码管显示检测到的温度值&#xff1b; DS18B20介绍 简介 DS18B20是由DALLAS半导体公司推出的一种的“一线总线&#xff08;单总线&#xff09;”接口的温度传感器&#xff1b; 与传统的热敏电阻等测温元件相比&#xff0c;它是一…

SpringBoot整合达梦数据库

近期接到了一个需要国产化的项目&#xff0c;用到了达梦数据库&#xff0c;没想到一开始配置就出现了问题&#xff0c;下面把配置给大家粘贴出来&#xff0c;大家少踩点坑。 一、先下载达梦数据库 这是达梦数据库下载链接&#xff0c;达梦数据库没有免费的&#xff0c;个人好…

Chapter 12: Regular expressions | Python for Everybody 讲义笔记_En

文章目录 Python for Everybody课程简介Regular ExpressionsRegular ExpressionsCharacter matching in regular expressionsExtracting data using regular expressionsCombining searching and extractingEscape characterSummaryBonus section for Unix / Linux usersDebugg…

[保研/考研机试] 约瑟夫问题No.2 C++实现

题目要求&#xff1a; 输入、输出样例&#xff1a; 源代码&#xff1a; #include<iostream> #include<queue> #include<vector> using namespace std;//例题5.2 约瑟夫问题No.2 int main() {int n, p, m;while (cin >> n >> p >> m) {//如…

【LeetCode】字符串与栈的练习

字符串相乘 class Solution { public:/** 将两个字符串相乘拆分成两步&#xff1a;* 先将一个字符串的每个字符与另一个字符串相乘得到一个计算结果* 再将所有计算结果的字符串进行相加*/string multiply(string num1, string num2) {string result "0";// 一个字…

微服务——es数据聚合+RestClient实现聚合

数据聚合 聚合的种类 DSL实现Bucket聚合 如图所示&#xff0c;设置了10个桶&#xff0c;那么就显示了数量最多的前10个桶&#xff0c;品牌含有7天酒店的有30家&#xff0c; 品牌含有如家的也有30家。 修改排序规则 限定聚合范围 DSL实现Metrics聚合 如下案例要求对不同的品…