胸部CT图肺实质分割与3D模型重建

从CT图像中分割肺部,展示了多种分割方法,最终获取mask。通过多方查找相关的教程,将我们组的课程任务完成情况总结记录如下:

任务说明
肺癌手术治疗的关键是尽可能少的切除感染部位并保留大部分健康的肺组织。传统的计算机手术辅助系统在PC屏幕上显示病人的CT图像。但这种辅助系统不是真正的三维系统,不能很好地向外科医生展示患者肺血管和气管的位置。
为了更好的显示患者的肺部三维结构,我们通过对患者的肺部CT数据进行分析和处理,实现对肺部的分割提取并对提取的肺部数据进行模型创建,尽可能准确的还原肺部的结构。

技术方案
原始数据为某人的肺部CT图,我们需要对CT图数据进行处理,然后根据处理过的数据分割获取肺部组织的结构进行模型重建。

肺部实质分割
处理CT数据的时候,我们需要获取肺部的mask来实现肺部结构的提取。我们主要采用了阈值分割、图像形态学、图像连通域等方法来进行肺部的分割。

肺部模型重建
通过对每一张CT切片进行肺部实质分割,我们得到每一张CT切片中的肺部结构图(以数组的方式存储),多张切片组合成一个三维数组。然后,我们可以通过marching_cubes方法计算三维数据中的曲面并使用matpoltlib和matlab分别显示肺部的的三维模型。

环境介绍
编程语言:Python
主要使用的第三方库:skimage、matplotlib、mayavi
(1)Python
Python 是一种面向对象、解释型、弱类型的脚本语言,它也是一种功能强大而完善的通用型语言。
相比其他编程语言,Python代码非常简单,上手非常容易。比如我们要完成某个功能,如果用Java需要100行代码,但用Python可能只需要20行代码,这是Python具有巨大吸引力的一大特点。
同时,Python具有完备的语言生态,有很多可用的第三方库,且第三方库的安装和使用非常方便,极大的简化了Python程序的编写。
(2)skimage
skimage的全称是scikit-image SciKit (toolkit for SciPy) ,它对scipy.ndimage进行了扩展,提供了更多的图片处理功能。它是由python语言编写的,由scipy 社区开发和维护。skimage库由许多子模块组成,各个子模块提供不同的功能。主要子模块有:
■ filters——图像增强、边缘检测、排序滤波器、自动阈值等
■ draw——操作于numpy数组上的基本图形绘制,如线条、矩形、圆等
■ transform——几何变换或其它变换,如旋转、拉伸和拉式变换等
■ morphology——形态学操作,如开闭运算、骨架提取等
■ exposure——图片强度调整,如亮度调整、直方图均衡等
■ feature——特征检测与提取等
■ measure——图像属性的测量,如相似性或等高线等
(3)matplotlib
matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型的2D图表和一些基本的3D图表,可根据数据集自行定义x、y轴,绘制图形(线形图,柱状图,直方图,密度图,散布图等),能够满足大部分的需要。matplotlib中最基础的模块是pyplot。
(4)mayavi
Mayavi2完全用Python编写,因此它不但是一个方便实用的可视化软件,而且可以方便地用Python编写扩展,嵌入到用户编写的Python程序中,或者直接使用其面向脚本的API:mlab快速绘制三维图。

技术实现
肺部实质分割
CT图中包含扫描区域的所有物体,包括床板、衣物、人体组织等等,首先需要做的便是将肺部实质提取出来,去除所有其他我们不关注的数据信息。以一张CT切片为例,整个流程如下所示:

(1)二值化
由于CT值的范围是-1000~+1000,所以可以根据不同组织或者结构的CT值对CT图进行二值化操作。对与肺部CT而言,一般以空气的CT值(-300)为界,将大于-300的位置置为1,小于-300的位置置为0。这样就可以将数据分为外部空气、内部空气、躯干组织。如下图所示:

binary

(2)处理边界
边界处理是为了将轮廓外的1值清除,达到删除其他杂物的目的,获得的图像结果如下所示:

AfterClear

(3)标记连通区域
在二值图像中,如果两个像素点相邻且值相同(同为0或同为1),那么就认为这两个像素点在一个相互连通的区域内。而同一个连通区域的所有像素点,都用同一个数值来进行标记,这个过程就叫连通区域标记。我们使用label方法对边界处理过后的图像结果做连通区域划分。
(4)保留最大的两个连通区域
对于一张CT图而言,去除了其他杂物和组织之后,剩余的部分中肺部组织占据了最大的面积。因此,对于标记了连通区域后的图像,我们仅保留最大的两个连通区域,即左肺和右肺。遍历所有的连通区域,将除了最大两个连通区域以外的所有其他位置全部置为0,获得的结果如下所示:
keeplungs
(5)腐蚀和闭包操作
通过腐蚀和闭包操作,处理肺部组织中的细节,结果如下所示:
erosion_closing
(6)填充形成mask
将腐蚀和闭包操作之后的结果做填充完整作为最终的mask结果,最终得到的肺部mask结果如下所示:
mask
(7)肺部分割结果
对每一张切片而言,对切片处理获得对应的肺部mask结果,然后将原始切片的非mask区域置为0,仅保留肺部组织即可。最终的到的分割结果如下所示:

mask

这里只以单张CT图的处理过程为例讲解肺部分割提取的结果,我们对于每一张的CT图都做相同的操作获取到每一个切片的肺部组织数据,用于最终的建模。这里给出单张CT图的肺部分割代码:

# 绘制图片结果
def printImage(image,imgName):
    plt.title(imgName)
    plt.imshow(image,cmap="gray")
    plt.show()
 
# 该函数用于从给定的2D切片中分割肺
def get_segmented_lungs(im, spacing, threshold=-300):
    # 步骤1: 二值化
    binary = im < threshold # 显示二值化 # printImage(binary,"binary") # 步骤2: 清除边界上的斑点 cleared = clear_border(binary) # printImage(cleared,"AfterClear") # 步骤3: 标记联通区域 label_image = label(cleared) # 保留两个最大的联通区域,即左右肺部区域,其他区域全部置为0 areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0
    # printImage(binary,"keep lungs")
 
    # 腐蚀操作
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    # 闭包操作
    selem = disk(10)
    binary = binary_closing(binary, selem)
    # printImage(binary,"erosion and closing")
 
    # 填充操作
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    # printImage(binary,"mask")
    # 返回最终的结果
    return binary
 
#读取图片,一张CT切片的路径
path = "F:/data/631165.dcm"
data = sitk.ReadImage(path)
spacing = data.GetSpacing()
scan = sitk.GetArrayFromImage(data)
# 获取当前CT切片的mask
mask = np.array([get_segmented_lungs(scan.copy().squeeze(0), spacing)])
# 将mask以外的值置为0,仅保留肺部结构
scan[~mask] = 0
# 显示分割结果
plt.imshow(scan[0],cmap="gray")
plt.show()

肺部模型重建
肺部模型的重建工作基于对每一张CT切片的处理结果之上,将所有的切片数据做肺部组织的分割和提取,然后构成三维坐标数据,最后根据提取的三维坐标进行模型重绘。
首先,我们使用skimage库中measure子模块中的marching_cubes方法根据提取的三维坐标计算曲面;然后,我们采用了matplotlib的3D绘图和mayavi中的mlab分别进行三维图形的绘制;最后,我们使用3D Slicer软件对肺部进行精细化建模,将三者进行对比。
(1)使用matplotlib绘制三维模型
设置好3D绘图的属性后,对分割结果进行绘制,绘制函数编写如下:

# 使用matplotlib绘图
def plot_3d_with_plt(image, threshold=-150):
    p = image.transpose(2,1,0)
    print(image.shape)
    verts,faces,_,_ = measure.marching_cubes(p, threshold)
    # plt绘制
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')
    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces], alpha=0.1)
    face_color = [0.5, 0.5, 1]
    mesh.set_facecolor(face_color)
    ax.add_collection3d(mesh)
 
    ax.set_xlim(0, p.shape[0])
    ax.set_ylim(0, p.shape[1])
    ax.set_zlim(0, p.shape[2])
 
    plt.show()

绘制结果如下所示:
matplotlib
(2)使用mlab绘制三维面模型
使用mlab进行绘制的函数比较简单,但是绘制结果图的显示效果优于matplotlib绘制的结果,代码如下所示:

# 使用mlab绘图
def plot_3d_with_mlab(image, threshold=-150):
    p = image.transpose(2,1,0)
    print(image.shape)
    verts,faces,_,_ = measure.marching_cubes(p, threshold)
    verts = verts.T
    mlab.triangular_mesh([verts[0]], [verts[1]], [verts[2]], faces)
    mlab.show()

绘制结果如下所示:
mlab

(3)与3D Slicer的建模结果对比
我们使用了3D Slicer进行了更加精细化的建模,该软件的建模需要手动标注用于区分不同的组织。尤其是对于气道这样的组织,可以通过对多张CT图和不同视图的标记帮助软件更好的对肺部进行建模。我们使用该软件对给定的CT数据进行建模的结果如下所示:
3d
完整的代码如下所示:

from optparse import Values
from skimage.segmentation import clear_border
from skimage.measure import label,regionprops, perimeter
from skimage.morphology import ball, disk, dilation, binary_erosion, remove_small_objects, erosion, closing, reconstruction, binary_closing
from skimage.filters import roberts, sobel
from scipy import ndimage as ndi
import scipy.ndimage
import numpy as np
from skimage import measure, feature
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from skimage import measure
import os
import SimpleITK as sitk
import matplotlib.pyplot as plt
from mayavi import mlab
 
# 该函数用于从给定的2D切片中分割肺
def get_segmented_lungs(im, spacing, threshold=-300):
    # 步骤1: 二值化
    binary = im < threshold # 步骤2: 清除边界上的斑点 cleared = clear_border(binary) # 步骤3: 标记联通区域 label_image = label(cleared) # 保留两个最大的联通区域,即左右肺部区域,其他区域全部置为0 areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2:
        for region in regionprops(label_image):
            if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0
    # 腐蚀操作,分割肺部的细节
    selem = disk(2)
    binary = binary_erosion(binary, selem)
    # 闭包操作
    selem = disk(10)
    binary = binary_closing(binary, selem)
 
    edges = roberts(binary)
    binary = ndi.binary_fill_holes(edges)
    # 返回最终的结果
    return binary
 
# 提取主要部分,选取不符合肺部实质特征的部分进行过滤
def extract_main(mask, spacing, vol_limit=[0.68, 8.2]):
    voxel_vol = spacing[0]*spacing[1]*spacing[2]
    label = measure.label(mask, connectivity=1)
    properties = measure.regionprops(label)
    for prop in properties:
            if prop.area * voxel_vol < vol_limit[0] * 1e6 or prop.area * voxel_vol > vol_limit[1] * 1e6:
                mask[label == prop.label] = 0           
    return mask
 
# 显示ct切片的分割结果
def plot_ct_scan(scan, num_column=4, jump=1):
    num_slices = len(scan)
    num_row = (num_slices//jump + num_column - 1) // num_column
    f, plots = plt.subplots(num_row, num_column, figsize=(num_column*5, num_row*5))
    for i in range(0, num_row*num_column):
        plot = plots[i % num_column] if num_row == 1 else plots[i // num_column, i % num_column]        
        plot.axis('off')
        if i < num_slices//jump:
            plot.imshow(scan[i*jump], cmap=plt.cm.bone) 
 
# 使用matplotlib绘图
def plot_3d_with_plt(image, threshold=-150):
    p = image.transpose(2,1,0)
    print(image.shape)
    verts,faces,_,_ = measure.marching_cubes(p, threshold)
    # plt绘制
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')
    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces], alpha=0.1)
    face_color = [0.5, 0.5, 1]
    mesh.set_facecolor(face_color)
    ax.add_collection3d(mesh)
 
    ax.set_xlim(0, p.shape[0])
    ax.set_ylim(0, p.shape[1])
    ax.set_zlim(0, p.shape[2])
 
    plt.show()
 
# 使用mlab绘图
def plot_3d_with_mlab(image, threshold=-150):
    p = image.transpose(2,1,0)
    print(image.shape)
    verts,faces,_,_ = measure.marching_cubes(p, threshold)
    verts = verts.T
    mlab.triangular_mesh([verts[0]], [verts[1]], [verts[2]], faces)
    mlab.show()
# 存放数据的文件夹
root = 'F:/data'
paths = os.listdir(root)
tem = np.empty(shape=(0,512,512))
for path in paths:
    # 读取CT图,对每一张进行分割提取
    data =sitk.ReadImage(os.path.join(root,path))
    spacing = data.GetSpacing()
    scan = sitk.GetArrayFromImage(data)
    mask = np.array([get_segmented_lungs(scan.copy().squeeze(0), spacing)])
    scan[~mask] = 0
    tem = np.append(tem, scan, axis=0)
 
print(tem.shape)
scan = tem[::-1]                #读取文件的顺序和实际模型颠倒,所以这里做一个逆序
plot_3d_with_plt(scan)          #绘制建模结果
plot_3d_with_mlab(scan)         #绘制建模结果

结果分析
通过对结果的分析和比较,我们发现自己使用的分割和重建方法难以对肺部组织和气道进行明显的区分。虽然,我们可以通过调节相应的参数获取不带有气道的完整肺部结构,但是比较难以将气道和肺部组织进行分离,尤其是在肺部和气道的交界处。如何使用CT图中的数据特征更加准确的区分肺部组织和气道组织是一个可以进一步深入研究的课题。

python运行YOLOv8推理详解及部署实现

参考文档:github.com/ultralytics/

代码仓库的名字不再沿用 yolovx 而是使用 ultralytics, 而这个名字正是创建该项目的公司的名字,之所以如此,一方面是该公司想要创建一个 CV 的通用仓库,使其能够支持大部分的 CV 任务,如 物体检测与跟踪、实例分割、图像分类和姿态估计等,以区分于之前只是检测任务使用的 yolovx。第二方面,估计有想提升公司知名度的意味,故命名为自己公司的名字。

 一,基本核心代码

from ultralytics import YOLO

model = YOLO("xxxx.pt")# 或者(用于训练): model = YOLO("yolov8x.yaml")

image = "xxx.jpg"# 或者图片文件夹

model.predict(image, save=True)# 返回image的预测结果

# 训练:model.train(data="数据集路径.yaml", epochs=200, batch=16)
# 训练数据集类型看yolov8训练流程

二,代码扩展案例

1,训练

from ultralytics import YOLO

model = YOLO("./weights/yolov8n.pt")

data = "./dataset/car/mydata.yaml"

model.train(data=data, epochs=100, batch=1)

2,预测
2.1单图

from ultralytics import YOLO

save_path = './'
image_path = './dataset/fire_smoke/000010.jpg'
model = YOLO('./weights/best.pt')

# 单图预测
results = model.predict(image_path)
for r in result[0]:
if r.boxes.cls.item()==0.0:
print('有火')
elif r.boxes.cls.item()==1.0:
print('有烟')

2.2多图文件夹

from ultralytics import YOLO
from pathlib import Path

save_path = './'
images_path = './dataset/fire_smoke/images'
model = YOLO('./weights/best.pt')

for path in Path(images_path).glob('*.*'):
results = model.predict(str(path))
for result results: 
for r in result:
if r.boxes.cls.item()==0.0:
print('有火')
elif r.boxes.cls.item()==1.0:
print('有烟')

2.3 图片路径文件

from ultralytics import YOLO
from pathlib import Path

save_path = './'
txt_path = './xxx.txt'# txt内容是图片路径
model = YOLO('./weights/best.pt')

# 图集推理
with open(txt_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
for path in lines:
results = model.predict(path[:-1])
for r in result[0]:
if r.boxes.cls.item()==0.0:
print('有火')
elif r.boxes.cls.item()==1.0:
print('有烟')

2.4网络摄像头

from ultralytics import YOLO
import cv2

save_path = './'
video_url = 0# 网络摄像头路径,0表示本机摄像头
model = YOLO('./weights/best.pt')

cap = cv2.VideoCapture(video_url)
while True:
ret, frame = cap.read()
results = model.predict(frame, save=True)
img = cv2.imread('./predict/image0.jpg')
cv2.imshow('img', img)
if cv2.waitKey(1) == ord('q'):
break
for r in results[0]:
# if r.boxes.conf.item()>5.0:# 置信度阈值
if r.boxes.cls.item()==0.0:
print('有火')
elif r.boxes.cls.item()==1.0:
print('有烟')

Python yolov8 介绍

介绍 Ultralytics YOLOv8 YOLOv8 基于深度学习和计算机视觉领域的尖端技术,在速度和准确性方面具有无与伦比的性能。其流线型设计使其适用于各种应用,并可轻松适应从边缘设备到云 API 等不同硬件平台。

探索YOLOv8 文档,这是一个旨在帮助您了解和利用其特性和功能的综合资源。无论您是经验丰富的机器学习实践者还是该领域的新手,hub ,旨在最大限度地发挥YOLOv8 在您的项目中的潜力。

根据官方描述,Yolov8是一个SOTA模型,它建立在Yolo系列历史版本的基础上,并引入了新的功能和改进点,以进一步提升性能和灵活性,使其成为实现目标检测、图像分割、姿态估计等任务的最佳选择。其具体创新点包括一个新的骨干网络、一个新的Ancher-Free检测头和一个新的损失函数,可在CPU到GPU的多种硬件平台上运行。

此外,Yolov8还有一个特点就是可扩展性,ultralytics没有直接将开源库命名为Yolov8,而是直接使用”ultralytics”,将其定位为算法框架,而非某一个特定算法。这也使得Yolov8开源库不仅仅能够用于Yolo系列模型,而且能够支持非Yolo模型以及分类分割姿态估计等各类任务。

总而言之,Yolov8是Yolo系列模型的最新王者,各种指标全面超越现有对象检测与实例分割模型,借鉴了Yolov5、Yolov6、YoloX等模型的设计优点,在全面提升改进Yolov5模型结构的基础上实现,同时保持了Yolov5工程化简洁易用的优势。

 

YOLO:简史
YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的约瑟夫-雷德蒙(Joseph Redmon)和阿里-法哈迪(Ali Farhadi)开发。YOLO 于 2015 年推出,因其高速度和高精确度而迅速受到欢迎。

2016 年发布的YOLOv2 通过纳入批量归一化、锚框和维度集群改进了原始模型。
2018 年推出的YOLOv3 使用更高效的骨干网络、多锚和空间金字塔池进一步增强了模型的性能。
YOLOv4于 2020 年发布,引入了 Mosaic 数据增强、新的无锚检测头和新的损失函数等创新技术。
YOLOv5进一步提高了模型的性能,并增加了超参数优化、集成实验跟踪和自动导出为常用导出格式等新功能。
YOLOv6于 2022 年由美团开源,目前已用于该公司的许多自主配送机器人。
YOLOv7增加了额外的任务,如 COCO 关键点数据集的姿势估计。
YOLOv8是YOLO 的最新版本,由Ultralytics 提供。YOLOv8 YOLOv8 支持全方位的视觉 AI 任务,包括检测、分割、姿态估计、跟踪和分类。这种多功能性使用户能够在各种应用和领域中利用YOLOv8 的功能。

 

Yolov8的改进之处有以下几个地方:

  • Backbone:使用的依旧是CSP的思想,将YOLOv5中的C3模块被替换成了C2f模块,实现了进一步的轻量化,同时YOLOv8依旧使用了YOLOv5等架构中使用的SPPF模块;
  • PAN-FPN:YOLOv8依旧使用了PAN的思想,不同的是YOLOv8将YOLOv5中PAN-FPN上采样阶段中的卷积结构删除了,同时也将C3模块替换为了C2f模块;
  • Decoupled-Head:这一点源自YOLOX;分类和回归两个任务的head不再共享参数,YoloV8也借鉴了这样的head设计。
  • Anchor-Free:YOLOv8抛弃了以往的Anchor-Base,使用了Anchor-Free的思想;
  • 损失函数:YOLOv8使用VFL Loss作为分类损失,使用DFL Loss+CIOU Loss作为分类损失;
  • 样本匹配:YOLOv8抛弃了以往的IOU匹配或者单边比例的分配方式,而是使用了Task-Aligned Assigner匹配方式。

yolov8是个模型簇,从小到大包括:yolov8n、yolov8s、yolov8m、yolov8l、yolov8x等。模型参数、运行速度、参数量等详见下表:

模型 尺寸
(像素)
mAPval
50-95
速度
CPU ONNX
(ms)
速度
A100 TensorRT
(ms)
参数
(M)
FLOPs
(B)
YOLOv8n 640 37.3 80.4 0.99 3.2 8.7
YOLOv8s 640 44.9 128.4 1.20 11.2 28.6
YOLOv8m 640 50.2 234.7 1.83 25.9 78.9
YOLOv8l 640 52.9 375.2 2.39 43.7 165.2
YOLOv8x 640 53.9 479.1 3.53 68.2 257.8
  • mAP 值是基于单模型单尺度在 COCO val2017 数据集上的结果。
    通过 yolo val detect data=coco.yaml device=0 复现
  • 速度 是使用 Amazon EC2 P4d 实例对 COCO val 图像进行平均计算的。
    通过 yolo val detect data=coco128.yaml batch=1 device=0|cpu 复现

显然,A100上使用 TensorRT 加速确实快,但我更需要的是在比较弱的 GPU 上的 速度指标。

从上面的指标可以看出,yolov8 相比 yolov5-7.0, mAP 全部都更高, 但是 n/s/m 模型的参数更多,对应 speed 也更慢,l/x 的参数量更少,推理速度却更慢。但是,更高的性能,牺牲点参数量和 speed,我觉得也是可以接受的。可能该仓库的目的也不在此,更多的是让 ultralytics 变成一个算法框架,这是许多人都需要的东西。

最详细的Ubuntu安装与配置Docker教程

Docker是一种流行的容器化平台,它能够简化应用程序的部署和管理。本文将介绍在Ubuntu操作系统上安装Docker的步骤,以便我们可以开始使用Docker来构建和运行容器化应用程序。

系统版本

本文以Ubuntu20.05系统为例安装docker,Ubuntu官方下载地址

检查卸载老版本docker

ubuntu下自带了docker的库,不需要添加新的源。
但是ubuntu自带的docker版本太低,需要先卸载旧的再安装新的。

一、安装Docker

注:docker的旧版本不一定被称为docker,http://docker.io 或 docker-engine也有可能,所以我们卸载的命令为:

  1. 查看是否已经安装docker
docker version

(移除旧版本)

sudo apt-get remove docker docker-engine docker.io containerd runc
  1. 更新软件列表
sudo apt-get update
  1. 允许apt命令可以使用HTTP访问Docker repository
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  1. 添加docker官方GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

返回 OK
验证key
清华源

add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

或者阿里源

add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
  1. 更新源
sudo apt-get update
  1. 安装docker-ce软件
sudo apt-get install docker-ce docker-ce-cli containerd.io
  1. 重启docker
service docker restart
  1. 测试
sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete 
Digest: sha256:ac69084025c660510933cca701f615283cdbb3aa0963188770b54c31c8962493
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

9. 查看docker版本

sudo docker version
Client: Docker Engine - Community
 Version:           24.0.7
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        afdd53b
 Built:             Thu Oct 26 09:08:01 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.7
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       311b9ff
  Built:            Thu Oct 26 09:08:01 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.26
  GitCommit:        3dd1e886e55dd695541fdcd67420c2888645a495
 runc:
  Version:          1.1.10
  GitCommit:        v1.1.10-0-g18a0cb0
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
  1. 查看镜像,可以看到刚才创建的镜像
sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d2c94e258dcb 7 months ago 13.3kB

二、 卸载Docker

  1. 卸载Docker CE安装包
sudo apt-get purge docker-ce
  1. 删除相关目录和配置文件
rm -rf /var/lib/docker $ rm -rf /etc/docker

三、 命令补全

通过bash_complete,docker提供自动补全功能,在执行该命令时,按tab即可自动补全参数,提高命令输入效率

  1. 安装bash_completion
apt install bash-completion
  1. 加载bash_completion
source /etc/bash_completion

四、更改默认存储位置

  1. 查看docker数据存储路径
sudo docker info
  1. 查看docker数据占用的存储空间(-v参数是详细列出)
sudo docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          1         1         13.26kB   0B (0%)
Containers      1         0         0B        0B
Local Volumes   0         0         0B        0B
Build Cache     0         0         0B        0B
sudo docker system df -v
Images space usage:

REPOSITORY    TAG       IMAGE ID       CREATED        SIZE      SHARED SIZE   UNIQUE SIZE   CONTAINERS
hello-world   latest    d2c94e258dcb   7 months ago   13.3kB    0B            13.26kB       1

Containers space usage:

CONTAINER ID   IMAGE         COMMAND    LOCAL VOLUMES   SIZE      CREATED          STATUS                      NAMES
deeef9008e1b   hello-world   "/hello"   0               0B        28 minutes ago   Exited (0) 28 minutes ago   quirky_sanderson

Local Volumes space usage:

VOLUME NAME   LINKS     SIZE

Build cache usage: 0B

CACHE ID   CACHE TYPE   SIZE      CREATED   LAST USED   USAGE     SHARED

3. 新建配置文件并输入以下内容

sudo vim /etc/docker/daemon.json
{
"data-root": "/home/xxx/docker", # 新的路径
"registry-mirrors": [
	"http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://registry.docker-cn.com"]
}
  1. 将原来docker中的数据复制到新的存储目录下
sudo cp -r /var/lib/docker /home/xxx/docker
  1. 重启Docker
sudo systemctl restart docker
  1. 查看image信息
docker images
  1. 删除之前的数据
rm -rf /var/lib/docker

五、拉取镜像

!官方镜像地址!:https://hub.docker.com/search?q=

docker pull openvino/ubuntu18_dev
using default tag:latest
latest: Pulling from openvino/ubuntu18_dev
726b8a513d66:Pulling fs layer
0f56be5e847f: pull complete
f957f773fc62: Pull complete
f722a4ecdd54: Pull complete
6b060e8bd29c:Pull complete
40b9e5ee4b53:Pull complete
a365951389a1: Pull complete
bd7c374e5019: Pull complete
c2ab551aadf8: Pull complete
05d8d25ca7b2: Pull complete
ffaeef3258cb: Pull complete
ed8677b27775:Pull complete
ef839f01f9e6: Pull complete
39540179535f:Pull complete
621ba107416a: Pull complete
b4e66e18204d:Pull complete
cc51904aeed8: Pull complete
790ce7f99b38:Pull complete
ec28e21ce553:Pull complete
87050f54d747:Pull complete
17a9417b599e:Pull complete
955c554af1bf: Pull complete
5dd2794e2c8e: pull complete
C66277640e81:Pull complete
Digest: sha256:6a13b6ef271e949a1853ff633e33c8d60fed2d2e42b81b966ad6c4ea1dab7a66
Status: Downloaded newer image for openvino/ubuntu18_dev:latest

六、国内镜像

1.Docker中国区官方镜像
https://registry.docker-cn.com

2.网易
http://hub-mirror.c.163.com

3.中科大
https://docker.mirrors.ustc.edu.cn

Ubuntu操作系统安装Anaconda

概述

Anaconda是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。其包含的科学包有:conda, numpy, scipy, ipython notebook等。

Anaconda具有如下特点:

    • 开源
    • 安装过程简单
    • 高性能使用Python和R语言
    • 免费的社区支持

其特点的实现主要基于Anaconda拥有的:

    • 资源管理conda和pip

扩展:conda和pip的区别

    1. 依赖项检查:pip不一定会展示所需其他依赖包,conda会列出所需其他依赖包。
    1. 环境管理:pip维护多个环境难度较大,conda可以比较方便地在不同环境之间切换,环境管理较为简单
    2. 对系统自带Python的影响:pip:在系统自带Python中包的更新/回退版本/卸载将影响其他程序。 conda:不会影响系统自带Python
    3. 适用语言:pip仅适用于Python,conda适用于Python, R, Ruby, Lua, Scala, Java, JavaScript, C等
      • 180多个科学包
      • 1,000+开源库

Anaconda + Jupyter 基本上已经是大部分机器学习以及数据分析等开发者必备的开发环境。

安装

下载安装程序: 在下载页面上,复制链接并使用 wget 命令下载 Miniconda 安装程序。请将链接替换为您选择的版本链接。例如:

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh

运行安装程序: 运行下载的安装程序。首先,给安装程序添加执行权限:

chmod +x Miniconda3-latest-Linux-x86_64.sh

然后,运行安装程序:

./Miniconda3-latest-Linux-x86_64.sh

安装程序将引导您通过安装过程。按照提示选择安装位置,通常接受默认选项即可。安装完成后,您需要关闭并重新打开终端,以使 Conda 生效。

测试 Conda 安装: 在终端中,运行以下命令来验证 Conda 是否安装成功:

conda --version

这应该显示安装的 Conda 版本号,确认安装成功。

设置path激活:

source ~/.bashrc

anaconda常用命令

1、查看已安装的包

conda list

2、更新所有包

conda upgrade --all

3、安装包

conda install package_name

4、删除包

conda remove package_name

5、更新包

conda update package_name

6、不知道包名要找包

conda search name

7、用conda建立虚拟环境

conda create -n env_name list_of_packages

其中 -n 代表 name,env_name 是需要创建的环境名称,list of packages 则是列出在新环境中需要安装的工具包。
例如,当我安装了 Python3 版本的 Anaconda 后,默认的 root 环境自然是 Python3,但是我还需要创建一个 Python 2 的环境来运行旧版本的 Python 代码,最好还安装了 pandas 包,于是我们运行以下命令来创建:

conda create -n py2 python=2.7 pandas

细心的你一定会发现,py2 环境中不仅安装了 pandas,还安装了 numpy 等一系列 packages,这就是使用 conda 的方便之处,它会自动为你安装相应的依赖包,而不需要你一个个手动安装。
8、进入虚拟环境

source activate env_name

9、退出虚拟环境

source deactivate

10、删除名为 env_name 的环境

conda env remove -n env_name

11、显示所有的环境:

conda env list

12、当分享代码的时候,同时也需要将运行环境分享给大家,执行如下命令可以将当前环境下的 package 信息存入名为 environment 的 YAML 文件中

conda env export > environment.yaml

13、使用别人生成的yaml文件创建环境

conda env create -f environment.yaml

natapp国内高速内网穿透服务

1、什么是内网穿透

内网穿透用通俗的语言讲,就是如何让外部的人员或服务访问我们我们局域网的服务的过程,称之为内网穿透。

2、natapp就是一款提供内网穿透的服务

服务器更新:全面支持HTTPS协议以及本地SSL证书,支持WSS协议.同时支持HTTP/2 WEB协议,支持微信小程序本地开发.
全面自动支持泛子域名与访客真实IP地址.
网址 :https://natapp.cn

3、内网穿透可以做什么?

1. 上文举例的办公软件

2. 放在家里的树莓派,服务器等,需要远程ssh管理,这样打通服务器的22端口即可远程通过ssh操作服务器了.

3. 微信/支付宝等本地开发.现在微信/支付宝等应用,需要服务器接收微信/支付宝发送的回调信息,然而在本地开发程序的话,还得实时上传到服务器,以便支持微信/支付宝的回调信息,如果使用了natapp内网穿透软件,将回调地址设置成natapp提供的地址,回调数据立即传递回本地,,这样很方便的在本地就可以实时调试程序,无须再不断上传服务器等繁琐且无意义的步骤.

4. 一些企业内部数据库,由于安全等原因,不愿意放到云服务器上,可以将数据库放到办公室本地,然后通过natapp的tcp隧道映射,这样既保证安全,又保证公网可以正常访问.

5. 一些开发板做的监控等信息,每台设备运行一条隧道,可以方便的管理监控各个设备的运行情况.

6. 一些本地运行的游戏,想和好基友一起联网玩,一条命令运行natapp即可实现联网游戏.

7. 群辉上运行natapp之后,随时随地在任何地方可以访问到群辉上应用

4、内网穿透安全吗?

现在服务器被黑的情况,多半是服务器上一些软件/漏洞/端口导致的.你的应用如果放在公网服务器,由于缺少系统安全维护知识,会变得很危险.而用了natapp内网穿透软件之后,将服务器放在本地,暴露给公网的也仅仅是应用层面的一个端口,其他系统上的漏洞/端口都被隐藏起来.从这个层面来说,提高了很多安全性.

当然,你的应用本身带来的安全性,比如代码本身有漏洞,如果是映射数据库应用,数据库弱密码等,这需要引起重视,排查映射的应用本身安全性即可.

Natapp本身的隧道传输采用ssl256位加密,这种加密安全性现阶段完全无法破解,natapp隧道的安全性无需考虑

yansongda/pay 优雅的php Alipay/WeChat/Unipay 的支付 SDK 扩展

开发了多次支付宝与微信支付后,很自然产生一种反感,惰性又来了,想在网上找相关的轮子,可是一直没有找到一款自己觉得逞心如意的,要么使用起来太难理解,要么文件结构太杂乱,只有自己撸起袖子干了。

特点

  • 多租户支持
  • Swoole 支持
  • 灵活的插件机制
  • 丰富的事件系统
  • 命名不那么乱七八糟
  • 隐藏开发者不需要关注的细节
  • 根据支付宝、微信最新 API 开发而成
  • 高度抽象的类,免去各种拼json与xml的痛苦
  • 文件结构清晰易理解,可以随心所欲添加本项目中没有的支付网关
  • 方法使用更优雅,不必再去研究那些奇怪的的方法名或者类名是做啥用的
  • 内置自动获取微信公共证书方法,再也不用再费劲去考虑第一次获取证书的的问题了
  • 符合 PSR2、PSR3、PSR4、PSR7、PSR11、PSR14、PSR18 等各项标准,你可以各种方便的与你的框架集成

安装
# yansongda/pay 2.x

composer require "larva/laravel-transaction:^2.0"

# yansongda/pay 3.x

composer require "larva/laravel-transaction:^3.0"

laravel 用户

配置文件

php artisan vendor:publish --provider="Yansongda\LaravelPay\PayServiceProvider" --tag=laravel-pay

lumen 用户

配置文件

请手动复制配置文件

service provider

$app->register(Yansongda\LaravelPay\PayServiceProvider::class);

支持的支付方法

1、支付宝

  • 电脑支付
  • 手机网站支付
  • APP 支付
  • 刷卡支付
  • 扫码支付
  • 账户转账
method 描述
web 电脑支付
wap 手机网站支付
app APP 支付
pos 刷卡支付
scan 扫码支付
transfer 帐户转账

2、微信

  • 公众号支付
  • 小程序支付
  • H5 支付
  • 扫码支付
  • 刷卡支付
  • APP 支付
  • 企业付款
  • 普通红包
  • 分裂红包

method描述mp公众号支付miniapp小程序支付wapH5 支付scan扫码支付pos刷卡支付appAPP 支付transfer企业付款redpack普通红包groupRedpack分裂红包

版本支持

版本 PHP 分支 状态
v3.5 >= 8.0 master 积极开发中
v3.4 >= 8.0 master EOL,停止维护
v3.0-3.3 >= 7.3 master EOL,停止维护
v2.x >= 7.0 v2 安全支持,不做新功能开发
v1.x >= 5.6 v1 EOL,停止维护

官网:https://pay.yansongda.cn/

 

ThinkPHP8.0搭建的后台管理系统EasyAdmin8

项目介绍

EasyAdmin8在EasyAdmin的基础上,使用ThinkPHP v8.0重构,并且开发了Laravel v10.20和webman等框架的版本,是市面上常用框架的快速开发后台管理系统。

官网链接:https://easyadmin8.top/

项目特性

快速CURD命令行
一键生成控制器、模型、视图、JS文件
支持关联查询、字段预设置等等
基于auth的权限管理系统
通过注解方式来实现auth权限节点管理
具备一键更新auth权限节点,无需手动输入管理
完善的后端权限验证以及前面页面按钮显示、隐藏控制
完善的菜单管理
分模块管理
无限极菜单
菜单编辑会提示权限节点
完善的前端组件功能
对layui的form表单重新封装,无需手动拼接数据请求
简单好用的图片、文件上传组件
简单好用的富文本编辑器ckeditor
对弹出层进行再次封装,以极简的方式使用
对table表格再次封装,在使用上更加舒服
根据table的cols参数再次进行封装,提供接口实现image、switch、list等功能,再次基础上可以自己再次扩展
根据table参数一键生成搜索表单,无需自己编写
完善的后台操作日志
记录用户的详细操作信息
按月份进行分表记录
上传文件记录管理
后台路径自定义,防止别人找到对应的后台地址

项目简介

EasyAdmin8 在 EasyAdmin 的基础上更新 ThinkPHP 框架到 8.0 ,PHP 最低版本要求不低于 8.0
ThinkPHP v8.0 和 layui v2.8.x 的快速开发的后台管理系统。

项目地址:
https://github.com/wolf-leo/EasyAdmin8

https://gitee.com/wolf18/easyAdmin8
EasyAdmin8-Laravel 在 EasyAdmin 的基础上使用 Laravel 10.x 重构,PHP 最低版本要求不低于 8.1
Laravel v10.x 和 layui v2.8.x 的快速开发的后台管理系统。

项目地址:

https://github.com/wolf-leo/EasyAdmin8-Laravel

https://gitee.com/wolf18/EasyAdmin8-Laravel
EasyAdmin8-webman 在 EasyAdmin 的基础上使用 webman 最新版重构,PHP 最低版本要求不低于 8.0
webman 和 layui v2.8.x 的快速开发的后台管理系统。

项目地址:

https://github.com/wolf-leo/EasyAdmin8-webman

https://gitee.com/wolf18/EasyAdmin8-webman

特别感谢
以下项目排名不分先后

EasyAdmin: https://github.com/zhongshaofa/easyadmin

ThinkPHP:https://github.com/top-think/framework

Laravel:https://laravel.com/docs/10.x

webman:https://github.com/walkor/webman

Layuimini:https://github.com/zhongshaofa/layuimini

Annotations:https://github.com/doctrine/annotations

Layui:https://github.com/sentsin/layui

Jquery:https://github.com/jquery/jquery

RequireJs:https://github.com/requirejs/requirejs

WangEditor:https://github.com/wangfupeng1988/wangEditor

Echarts:https://github.com/apache/incubator-echarts

BUG反馈
项目使用过程成,如遇到BUG,请到各版本的Gitee中的issue进行提问!

版权信息
EasyAdmin8遵循EasyAdmin的MIT开源协议发布,并提供免费使用。

换脸roop部署cpu和gpu模式

roop 介绍

上面介绍的一键换脸项目叫做Roop,项目官方介绍如下:你只需要一张所需脸部的图像,没有数据集,无需训练,你就可以将拍摄视频其中的面孔替换为你选择的面孔。该工具旨在为快速发展的人工智能生成媒体行业做出富有成效的贡献,它将帮助艺术家完成诸如动画自定义角色或使用角色作为服装模型等任务。本地安装Roop,官方给出了2种选择,基于CPU安装或者基于GPU安装。

1.roop是新开源了一个单图就可以进行视频换脸的项目,只需要一张所需面部的图像。不需要数据集,不需要训练。

2.大概的测试了一下,正脸换脸效果还不错,融合也比较自然。但如果人脸比较大,最终换出的效果可能会有些模糊。侧脸部分的幅度不宜过大,否则会出现人脸乱飘的情况。在多人场景下,也容易出现混乱。

3.使用简单,在处理单人视频和单人图像还是的换脸效果还是可以的,融合得也不错,适合制作一些小视频或单人图像。

roop 安装

获取代码,

sudo apt install git -y
git clone --depth 1 https://github.com/s0md3v/roop.git

安装依赖,

cd roop
pip install -r requirements.txt

# 如遇错误,可依提示。例如:
#  pip install -r requirements.txt --use-pep517
# 如遇 dependency conflict,可修改依赖版本。例如:
#  numpy>=1.23.5

# 若配置镜像
pip config set global.index-url http://mirrors.aliyun.com/pypi/simple
pip config set install.trusted-host mirrors.aliyun.com
cat ~/.config/pip/pip.conf

其实到这里就可以直接运行如下代码进行视频换脸了,首次启动会下载529M的模型文件,目前使用的是CPU,如果你显卡不高不想折腾了的话可以开始体验了。但是我们继续折腾,去开启GPU显卡处理功能。

python run.py

安装CUDA

(1)这是NVIDIA显卡的操作步骤,其它显卡用不了,打开链接:https://developer.nvidia.com/cuda-11-8-0-download-archive,安装程序下载下来之后,直接双击运行安装即可,安装选项选择精简版,安装完成关闭窗口即可。

(2)安装依赖

还在打开Python虚拟环境的cmd窗口中依次输入如下命令并回车,安装依赖,一条命令执行完再运行下一条命令。

pip uninstall onnxruntime onnxruntime-gpu
pip install onnxruntime-gpu

然后再输入如下命令即可启动roop操作窗口进行视频换脸了,

python run.py –execution-provider cuda
左侧点击select a face按钮选择一张待使用的人脸,右侧按钮select a target选择待转换的视频,点击start按钮会提示选择输出视频路径,选择完毕后即可开始转换。

roop运行常用指令
只用CPU处理视频:python run.py
使用GPU处理视频:python run.py –execution-provider cuda
图片保存jpg格式 python run.py –execution-provider cuda –temp-frame-format jpg
视频高清化处理: python run.py –execution-provider cuda –temp-frame-format jpg –frame-processor face_swapper face_enhancer
处理脸部跳闪: python run.py –execution-provider cuda –temp-frame-format jpg –frame-processor face_swapper face_enhancer –similar-face-distance 1.5
指定帧识别人脸并替换:python run.py –execution-provider cuda –reference-face-position 3 –reference-frame-number 166 –similar-face-distance 1.5
其他参数
–temp-frame-format {jpg,png} 用于帧提取的图像格式
–temp-frame-quality [0-100] 用于帧提取的图像质量
–output-video-encoder {libx264,libx265,libvpx-vp9,h264_nvenc,hevc_nvenc} 用于输出视频的编码器
–output-video-quality [0-100] 用于输出视频的质量
–max-memory MAX_MEMORY 最大RAM量(单位:GB)
–execution-threads EXECUTION_THREADS 执行线程数量

python中requirements.txt的生成与使用

在导入一个新项目的时候往往需要下载安装很多依赖,这时如果只是一个个下载非常繁琐,好在很多代码中都附带有requirements.txt文件,可以很方便的安装相应依赖,下面记录一下如何使用与生成该文件。

使用

激活项目具体使用的环境,切换到requirements.txt目录下执行该命令即可。

pip install -r requirements.txt

生成

方式一

生成的是该环境中所有的依赖包,对于想要获得该环境中的某个项目的依赖不友好。

pip freeze > requirements.txt 
# 在当前路径下生成,或者可以指定生成路径如 E:\requirements.txt

方式二

直接获得某个项目的依赖包,但需要另外安装包pipreqs。

# 当前环境下直接安装 
pip install pipreqs

利用该包可以完成对项目依赖包的获取。

# 切换到项目根目录下执行命令 
pipreqs ./ --encoding=utf8 
# 如果当前路径下已经存在requirements.txt文件,会提示附加上--force 
pipreqs ./ --encoding=utf8 --force