ubuntu下使用docker、socket、yolov5进行图像处理数据交互记录

ubuntu下使用docker、socket、yolov5进行图像处理数据交互记录

概述:主要实现了在宿主机上通过8000端口传递一张图像给docker镜像,然后镜像中处理后,通过8001端口回传处理后的图像给宿主机。

第一章、构建镜像

一、dockerfile文件

1.拉取ubuntu20.04镜像
基于ubuntu20.04进行构建,拉取ubuntu20.04的指令如下:

sudo docker pull ubuntu:20.04

2.编写dockerfile文件
dockerfile写入如下:

# Dockerfile# Base images 基础镜像FROM ubuntu:20.04# MAINTAINER 维护者信息
maintainer chenjun_1241370589@qq.com
# 设置超时
ENV PIP_DEFAULT_TIMEOUT=100 
# 设置环境变量以避免手动选择时区
ENV DEBIAN_FRONTEND=noninteractive#RUN 执行以下命令
RUN apt update
RUN apt install python3 python3-pip -y
RUN apt-get install nano
# 安装必要的系统依赖项
RUN apt-get update && apt-get install -y \libglib2.0-0 \libsm6 \libxext6 \libxrender-dev
RUN pip3 install --upgrade pip setuptools
RUN pip3 cache purge
RUN pip3 install opencv-python==4.5.5.62 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 安装 OpenCV  
RUN apt-get update && apt-get install -y \   libgl1-mesa-glx  # 安装 OpenGL 库  
# 其他依赖和设置RUN pip3 install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple 
RUN apt install libgl1-mesa-glx
RUN mkdir -p /data/code/#拷贝文件至工作文件夹
COPY test.py /data/code/test.py#工作目录
WORKDIR /data/code/#容器启动时执行的命令
CMD ["python3","test.py"]
二、编写docker内运行文件

1.新建test.py文件
test.py文件将被拷贝进镜像中,作为镜像内部运行文件。写入如下:

import cv2  # 导入OpenCV库
import numpy as np  # 导入NumPy库
import socket  # 导入socket库
import struct  # 导入struct库
import timedef receive_image():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP/IP套接字server_socket.bind(('0.0.0.0', 8000))  # 绑定到本地地址和端口8000server_socket.listen(1)  # 监听连接print("Waiting for connection...")  # 打印等待连接信息client_socket, addr = server_socket.accept()  # 接受连接print(f"Connected to {addr}")  # 打印连接地址data = b""  # 初始化数据变量payload_size = struct.calcsize("L")  # 获取消息大小的字节数while len(data) < payload_size:  # 接收消息大小data += client_socket.recv(4096)packed_msg_size = data[:payload_size]  # 获取打包的消息大小data = data[payload_size:]  # 剩余数据msg_size = struct.unpack("L", packed_msg_size)[0]  # 解包消息大小while len(data) < msg_size:  # 接收完整消息data += client_socket.recv(4096)frame_data = data[:msg_size]  # 获取图像数据frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)  # 解码图像client_socket.close()  # 关闭客户端套接字server_socket.close()  # 关闭服务器套接字return frame  # 返回图像def process_image(image):height, width = image.shape[:2]  # 获取图像高度和宽度new_height, new_width = height // 2, width // 2  # 计算新高度和宽度print("Process_image ok !")return cv2.resize(image, (new_width, new_height))  # 调整图像大小def send_image(image):client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP/IP套接字for _ in range(5):  # 尝试5次连接try:client_socket.connect(('172.17.0.1', 8001))  # 连接到指定地址和端口breakexcept ConnectionRefusedError:print("Connection refused, retrying...")time.sleep(2)  # 等待2秒后重试else:print("Failed to connect after 5 attempts")return_, img_encoded = cv2.imencode('.jpg', image)  # 编码图像为JPEG格式data = img_encoded.tobytes()  # 转换为字节数据client_socket.sendall(struct.pack("L", len(data)) + data)  # 发送数据client_socket.close()  # 关闭客户端套接字if __name__ == "__main__":while True:# 接收图像received_image = receive_image()# 处理图像processed_image = process_image(received_image)# 发送处理后的图像send_image(processed_image)

其中client_socket.connect((‘172.17.0.1’, 8001)) # 连接到指定地址和端口这一行中的ip需要在宿主机运行指令:

ip addr show docker0

在这里插入图片描述
将inet后的ip填入代码中。

三、构建镜像

宿主机终端输入:

sudo docker build -t python_socket2 . -f Dockerfile

其中“python_socket2”是我自己创建的名字,自行修改。
在这里插入图片描述

第二章、宿主机代码

一、交互代码

在宿主机中写入test1.py代码,这里图像处理部分只对图像进行尺寸减半的操作,代码如下:

import cv2
import numpy as np
import socket
import structdef send_image(image_path):# 读取图像image = cv2.imread(image_path)if image is None:print(f"无法读取图像: {image_path}")return# 创建TCP/IP套接字client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.connect(('localhost', 8000))  # 连接到Docker容器的8000端口# 编码图像为JPEG格式_, img_encoded = cv2.imencode('.jpg', image)data = img_encoded.tobytes()# 发送数据client_socket.sendall(struct.pack("L", len(data)) + data)client_socket.close()print("图像已发送")def receive_processed_image():# 创建TCP/IP套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('0.0.0.0', 8001))  # 绑定到本地地址和端口8001server_socket.listen(1)print("等待接收处理后的图像...")client_socket, addr = server_socket.accept()print(f"已连接到 {addr}")data = b""payload_size = struct.calcsize("L")while len(data) < payload_size:data += client_socket.recv(4096)packed_msg_size = data[:payload_size]data = data[payload_size:]msg_size = struct.unpack("L", packed_msg_size)[0]while len(data) < msg_size:data += client_socket.recv(4096)frame_data = data[:msg_size]# 解码图像frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)client_socket.close()server_socket.close()return frameif __name__ == "__main__":image_path = "/home/cj/work/Docker/Yolov5DnnImage/bus.jpg"  # 替换为实际的图像路径send_image(image_path)processed_image = receive_processed_image()# 显示处理后的图像#cv2.imshow("Processed Image", processed_image)#cv2.waitKey(0)#cv2.destroyAllWindows()# 保存处理后的图像cv2.imwrite("processed_image.jpg", processed_image)print("处理后的图像已保存为 processed_image.jpg")

图像输入地址自行修改。

第三章、交互使用

一、docker端

在宿主机终端输入:

sudo docker run -p 8000:8000 -i -t python_socket2:latest

这里的“python_socket2:latest”修改成自己的镜像。
查看镜像宿主机终端输入:

sudo docker images

在这里插入图片描述

二、宿主机端

运行test1.py文件
在这里插入图片描述
同时在docker端也会有输出:
在这里插入图片描述
在宿主机当前工作目录下也会生成对应的图像。
在这里插入图片描述

第四章、增加yolov5目标检测

一、宿主机文件摆放

因为需要更新dockerfile文件,因此需要留意文件摆放。本文中将需要用的文件都摆放在项目目录下。
在这里插入图片描述

目录中,bus.jpg是等待传输和处理的图像,classes.txt是目标检测类别文件,Dockerfile是进行构建文件,processed_image.jpg是宿主机传递给镜像处理后传输回来的图像,test.py是镜像中的主函数代码,test1.py是宿主机端的主函数代码,yolo.py是yolov5调用opencv的dnn模块进行推理的代码,yolov5s.onnx是模型全重文件。

二、各文件内容

1.classes.txt文件

person
bicycle
car
motorbike
aeroplane
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
sofa
pottedplant
bed
diningtable
toilet
tvmonitor
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

2.Dockerfile文件
主要是通过COPY命令,将一些必要的文件拷贝到镜像中

# Dockerfile# Base images 基础镜像FROM ubuntu:20.04# MAINTAINER 维护者信息
maintainer chenjun_1241370589@qq.com
# 设置超时
ENV PIP_DEFAULT_TIMEOUT=100 
# 设置环境变量以避免手动选择时区
ENV DEBIAN_FRONTEND=noninteractive#RUN 执行以下命令
RUN apt update
RUN apt install python3 python3-pip -y
RUN apt-get install nano
# 安装必要的系统依赖项
RUN apt-get update && apt-get install -y \libglib2.0-0 \libsm6 \libxext6 \libxrender-dev
RUN pip3 install --upgrade pip setuptools
RUN pip3 cache purge
RUN pip3 install opencv-python==4.5.5.62 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 安装 OpenCV  
RUN apt-get update && apt-get install -y \   libgl1-mesa-glx  # 安装 OpenGL 库  
# 其他依赖和设置RUN pip3 install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple 
RUN apt install libgl1-mesa-glx
RUN mkdir -p /data/code/#拷贝文件至工作文件夹
COPY test.py /data/code/test.py
COPY yolo.py /data/code/yolo.py
COPY classes.txt /data/code/classes.txt
COPY yolov5s.onnx /data/code/yolov5s.onnx#工作目录
WORKDIR /data/code/#容器启动时执行的命令
CMD ["python3","test.py"]

3.test.py文件
主要增加Yolov5Dnn函数

import cv2  # 导入OpenCV库
import numpy as np  # 导入NumPy库
import socket  # 导入socket库
import struct  # 导入struct库
import time
from yolo import build_model,detect,load_classes,wrap_detection,format_yolov5
def receive_image():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP/IP套接字server_socket.bind(('0.0.0.0', 8000))  # 绑定到本地地址和端口8000server_socket.listen(1)  # 监听连接print("Waiting for connection...")  # 打印等待连接信息client_socket, addr = server_socket.accept()  # 接受连接print(f"Connected to {addr}")  # 打印连接地址data = b""  # 初始化数据变量payload_size = struct.calcsize("L")  # 获取消息大小的字节数while len(data) < payload_size:  # 接收消息大小data += client_socket.recv(4096)packed_msg_size = data[:payload_size]  # 获取打包的消息大小data = data[payload_size:]  # 剩余数据msg_size = struct.unpack("L", packed_msg_size)[0]  # 解包消息大小while len(data) < msg_size:  # 接收完整消息data += client_socket.recv(4096)frame_data = data[:msg_size]  # 获取图像数据frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)  # 解码图像client_socket.close()  # 关闭客户端套接字server_socket.close()  # 关闭服务器套接字return frame  # 返回图像def process_image(image):height, width = image.shape[:2]  # 获取图像高度和宽度new_height, new_width = height // 2, width // 2  # 计算新高度和宽度print("Process_image ok !")return cv2.resize(image, (new_width, new_height))  # 调整图像大小def send_image(image):client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建TCP/IP套接字for _ in range(5):  # 尝试5次连接try:client_socket.connect(('172.17.0.1', 8001))  # 连接到指定地址和端口breakexcept ConnectionRefusedError:print("Connection refused, retrying...")time.sleep(2)  # 等待2秒后重试else:print("Failed to connect after 5 attempts")return_, img_encoded = cv2.imencode('.jpg', image)  # 编码图像为JPEG格式data = img_encoded.tobytes()  # 转换为字节数据client_socket.sendall(struct.pack("L", len(data)) + data)  # 发送数据client_socket.close()  # 关闭客户端套接字def Yolov5Dnn(image):print("Yolo detect ")class_list = load_classes()colors = [(255, 255, 0), (0, 255, 0), (0, 255, 255), (255, 0, 0)]is_cuda = 0net = build_model(is_cuda)inputImage = format_yolov5(image)outs = detect(inputImage, net)class_ids, confidences, boxes = wrap_detection(inputImage, outs[0])for (classid, confidence, box) in zip(class_ids, confidences, boxes):color = colors[int(classid) % len(colors)]cv2.rectangle(image, box, color, 2)cv2.rectangle(image, (box[0], box[1] - 20), (box[0] + box[2], box[1]), color, -1)cv2.putText(image, class_list[classid], (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 0, 0))return imageif __name__ == "__main__":while True:# 接收图像received_image = receive_image()# 处理图像#processed_image = process_image(received_image)processed_image = Yolov5Dnn(received_image)# 发送处理后的图像send_image(processed_image)

4.test1.py文件
这里和前面的代码是一样的

import cv2
import numpy as np
import socket
import structdef send_image(image_path):# 读取图像image = cv2.imread(image_path)if image is None:print(f"无法读取图像: {image_path}")return# 创建TCP/IP套接字client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.connect(('localhost', 8000))  # 连接到Docker容器的8000端口# 编码图像为JPEG格式_, img_encoded = cv2.imencode('.jpg', image)data = img_encoded.tobytes()# 发送数据client_socket.sendall(struct.pack("L", len(data)) + data)client_socket.close()print("图像已发送")def receive_processed_image():# 创建TCP/IP套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('0.0.0.0', 8001))  # 绑定到本地地址和端口8001server_socket.listen(1)print("等待接收处理后的图像...")client_socket, addr = server_socket.accept()print(f"已连接到 {addr}")data = b""payload_size = struct.calcsize("L")while len(data) < payload_size:data += client_socket.recv(4096)packed_msg_size = data[:payload_size]data = data[payload_size:]msg_size = struct.unpack("L", packed_msg_size)[0]while len(data) < msg_size:data += client_socket.recv(4096)frame_data = data[:msg_size]# 解码图像frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)client_socket.close()server_socket.close()return frameif __name__ == "__main__":image_path = "/home/cj/work/Docker/Yolov5DnnImage/bus.jpg"  # 替换为实际的图像路径send_image(image_path)processed_image = receive_processed_image()# 显示处理后的图像#cv2.imshow("Processed Image", processed_image)#cv2.waitKey(0)#cv2.destroyAllWindows()# 保存处理后的图像cv2.imwrite("processed_image.jpg", processed_image)print("处理后的图像已保存为 processed_image.jpg")

5.yolo.py文件
这个文件包含的是yolov5调用opencv的dnn模块进行目标检测的一些函数,内容如下:

import cv2
import time
import sys
import numpy as npdef build_model(is_cuda):net = cv2.dnn.readNet("./yolov5s.onnx")if is_cuda:print("Attempty to use CUDA")net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)else:print("Running on CPU")net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)return netINPUT_WIDTH = 640
INPUT_HEIGHT = 640
SCORE_THRESHOLD = 0.2
NMS_THRESHOLD = 0.4
CONFIDENCE_THRESHOLD = 0.4def detect(image, net):blob = cv2.dnn.blobFromImage(image, 1/255.0, (INPUT_WIDTH, INPUT_HEIGHT), swapRB=True, crop=False)net.setInput(blob)preds = net.forward()return predsdef load_classes():class_list = []with open("./classes.txt", "r") as f:class_list = [cname.strip() for cname in f.readlines()]return class_listdef wrap_detection(input_image, output_data):class_ids = []confidences = []boxes = []rows = output_data.shape[0]image_width, image_height, _ = input_image.shapex_factor = image_width / INPUT_WIDTHy_factor =  image_height / INPUT_HEIGHTfor r in range(rows):row = output_data[r]confidence = row[4]if confidence >= 0.4:classes_scores = row[5:]_, _, _, max_indx = cv2.minMaxLoc(classes_scores)class_id = max_indx[1]if (classes_scores[class_id] > .25):confidences.append(confidence)class_ids.append(class_id)x, y, w, h = row[0].item(), row[1].item(), row[2].item(), row[3].item() left = int((x - 0.5 * w) * x_factor)top = int((y - 0.5 * h) * y_factor)width = int(w * x_factor)height = int(h * y_factor)box = np.array([left, top, width, height])boxes.append(box)indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.25, 0.45) result_class_ids = []result_confidences = []result_boxes = []for i in indexes:result_confidences.append(confidences[i])result_class_ids.append(class_ids[i])result_boxes.append(boxes[i])return result_class_ids, result_confidences, result_boxesdef format_yolov5(frame):row, col, _ = frame.shape_max = max(col, row)result = np.zeros((_max, _max, 3), np.uint8)result[0:row, 0:col] = framereturn result
三、更新并运行docker镜像

1.更新镜像
在文件目录下打开终端,输入:

sudo docker build -t python_socket2 . -f Dockerfile

等待构建完成。
2.运行镜像
终端输入:

sudo docker run -p 8000:8000 -i -t python_socket2:latest

在这里插入图片描述
宿主机端,运行test1.py文件。
在这里插入图片描述
3.查看结果
文件夹下出现processed_image.jpg,可以看到检测结果。
在这里插入图片描述

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

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

相关文章

尚品汇-前端面包屑平台属性、排序处理(三十三)

目录&#xff1a; &#xff08;1&#xff09;面包屑处理平台属性 &#xff08;2&#xff09;排序处理 &#xff08;2&#xff09;单点登录业务介绍 &#xff08;1&#xff09;面包屑处理平台属性 前端显示&#xff1a;面包屑显示效果 搜list搜索方法继续添加返回的平台属性…

Lora 全文翻译

作者&#xff1a; 地点&#xff1a;hby 来源&#xff1a;https://arxiv.org/pdf/2106.09685 工具&#xff1a;文心 LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS 摘要 自然语言处理的一个重要范式包括在通用领域数据上进行大规模预训练&#xff0c;并适应特定任务或…

php 在app中唤起微信app进行支付,并处理回调通知

<?phpnamespace app\api\controller;use think\facade\Db; use think\facade\Log;class Wxzf {

什么是视频比特率?与视频时长是什么关系

​ ‌比特率是指单位时间内传输或处理的比特的数量&#xff0c;单位为‌bps(‌bit per second)。‌ 比特率经常用于描述在电信和计算领域中数据传输的速度&#xff0c;也可以作为衡量音频和视频文件数据率的指标。比特率越高&#xff0c;传送的数据越大&#xff0c;音频或视频…

Notion快速使用

探索Notion&#xff1a;全能笔记软件的新世界 1. 什么是Notion&#xff1f; 在数字化时代&#xff0c;一款集颜值与功能于一身的笔记软件无疑是学习与工作的得力助手。今天&#xff0c;我要向大家介绍的就是这样一款全能型选手——Notion。Notion不仅以其高颜值在众多笔记软件…

拟南芥中基因家族序列的提取

1.拟南芥基因组数据的下载 phytozome 是一个收录植物基因组数据的网站&#xff0c;数据整理比较规范&#xff0c;已 经提供了去除可变剪切的 cds 和 protein 序列文件。只有 gff3 文件需要 过滤处理 2. 对拟南芥的注释文件gff3文件进行ID处理&#xff0c;最终得到以下4个文件 …

【uni-app】使用天气API做一个天气APP(全过程)- 实况、逐小时、40日

头一次使用uni-app写代码, 现学现卖, 写的不好的地方见谅, 申请个appid就可以运行 切换城市界面比较简单, 城市名称需要符合天气api参数规则, 录入的城市不要带市区县; 格式如: 青岛、铁西、海淀、沛县 APP效果 功能说明 实况天气逐小时预报未来7日天气未来40日天气空气质量详…

C语言 | Leetcode C语言题解之第336题回文对

题目&#xff1a; 题解&#xff1a; #define SIZE 9470 #define N 168000 #define P 13331typedef unsigned long long ULL; ULL p[301];//p[i]存储P^ivoid init()//初始化p进制次幂数组 {int i;p[0]1;for(i1;i<300;i){p[i]p[i-1]*P;} }int** palindromePairs(char**words,…

探索 Resolume Arena 7 - 引领 VJ 音视频创作的卓越软件

Resolume Arena 7 是一款专为 Mac 和 Windows 系统设计的强大 VJ 音视频软件&#xff0c;为创意专业人士和爱好者提供了丰富而出色的功能。 这款软件拥有直观且用户友好的界面&#xff0c;即使对于初学者来说&#xff0c;也能快速上手并开始创作。其强大的媒体管理功能&#x…

SpringBoot事务-调度-缓存

一.Spring Boot中的事务管理 设置事务 Transactional(isolation Isolation.DEFAULT) Transactional(propagation Propagation.REQUIRED) 开启事务 EnableTransactionManagement 1. 开启事务管理 要开启 Spring 的事务管理&#xff0c;你需要在你的 Spring Boot 应用中添加 …

大数据技术现场工程师特色实训室解决方案

一、引言 在大数据时代背景下&#xff0c;数据已成为新的生产要素&#xff0c;驱动着各行各业的创新发展。面对这一趋势&#xff0c;市场对于既掌握大数据理论知识又具备实战能力的大数据技术人才的需求急剧增加。为了应对这一挑战&#xff0c;唯众精心设计了一套全面的大数据…

详解golang内存管理

介绍 要搞明白 Go 语言的内存管理,就必须先理解操作系统以及机器硬件是如何管理内存的。因为 Go 语言的内部机制是建立在这个基础之上的,它的设计,本质上就是尽可能的会发挥操作系统层面的优势,而避开导致低效情况。 操作系统内存管理 其实现在计算机内存管理的方式都是…

FPGA资源评估

FPGA资源评估 文章目录 FPGA资源评估前言一、资源评估1.1 资源有哪些1.2 资源统计 二、 FPGA 的基本结构三、 更为复杂的 FPGA 架构 前言 一、资源评估 大家在项目中一般会要遇到需要资源评估的情况&#xff0c;例如立了新项目&#xff0c;前期需要确定使用什么FPGA片子&…

RabbitMQ消息队列总结

RabbitMQ那些事 参考一. `RabbitMQ`介绍1.1 Java工程师1.1.1 RabbitMQ学习目标1.1.2 消息队列介绍1.1.3 RabbitMQ介绍各自属性介绍(❤❤❤)二. `RabbitMQ`安装1. 基于Linux1.1 安装1.2 常用命令1.3 后台管理开启与面板介绍三. 客户端`SDK`操作(❤❤了解)1. 客户端依赖1. 生产者…

Springboot实现doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频在线预览功能,你学“废”了吗?

最近工作中&#xff0c;客户需要生成包含动态内容的word/pdf报告&#xff0c;并且需要在线预览。 刚开始使用后台直接生成word文档&#xff0c;返回文件流给前端&#xff0c;浏览器预览会发生格式错乱问题&#xff0c;特别是文档中的图片有些还不显示。 想到最简单的办法就是…

alibabacloud学习笔记13

微服务Docker镜像打包讲解 父项目怎么springboot版本依赖 每个子模块项目添加依赖 添加构建文件&#xff1a; 微服务Docker镜像打包整合JDK11 服务根目录创建dockerFile文件. dockerFile的内容。 构建镜像( 去到子模块pom文件下)&#xff1a; 要下载这个才能使用本地docker.…

Nginx--简介、安装、常用命令和配置文件

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、Nginx简介 1、nginx介绍 Nginx (engine x) 是一个高性能的 HTTP 和 反向代理 服务&#xff0c;也是一个IMAP/POP3/SMTP服务。因它的稳定性、丰…

RPC 和 HTTP 理解

网上充斥着各类类似于这样的文章&#xff1a;rpc 比 http 快了多少倍&#xff1f;既然有了 http&#xff0c;为什么还要用 rpc 调用等等。遇到这类文章&#xff0c;说明对 http 和 rpc 是由理解误区的。 这里再次重复强调一遍&#xff0c;通信协议不是 rpc 最重要的部分&#x…

【OpenCV 】插值的方法原理,图片缩放,矫正,边界填充

图像旋转 缩放 计算机中的图像是以数组的方式储存&#xff0c;每个位置储存了像素点的像素值。对图像进行旋转缩放&#xff0c;就是对数组进行操作&#xff0c;乘以对应的矩阵&#xff0c;进行空间变换&#xff0c;而矩阵的行列式的值&#xff0c;就是缩放的倍数。 进行缩放旋…

Erupt 项目搭建

创建Spring Boot项目 Maven依赖 Spring Boot版本为 2.7.10&#xff0c;erupt版本为 1.12.14 erupt版本要与Spring Boot版本适配&#xff0c;3.x.x版本Spring Boot暂不适用说是 <properties><erupt.version>1.12.14</erupt.version></properties> <…