源码网站怎么做,网络平台贷款,网站开发要跑道吗,wordpress 媒体库 群晖需求#xff1a;使用C调用Pytorch模型#xff0c;对处理后的图像进行预测。 第一种#xff0c;使用C调用Python代码处理#xff0c;使用pybind11源代码再末尾 缺点#xff0c;导入Python包非常麻烦#xff0c;执行的C程序找不到cv2 torch包等等 本人解决了cv2 numpy等包使用C调用Pytorch模型对处理后的图像进行预测。 第一种使用C调用Python代码处理使用pybind11源代码再末尾 缺点导入Python包非常麻烦执行的C程序找不到cv2 torch包等等 本人解决了cv2 numpy等包但是torch一致搞不定大概率包不兼容导致的pip下载的PyTorch官网搞不懂 明明Python’直接执行可以但是C调用Python执行就不行非常奇怪 第二种C使用LibTorch将加载模型进行处理源代码再末尾 这个会不用例会网络架构以及包的问题只需将PyTorch模型保存为pt然后使用C加载即可非常简单 需要重写图像处理的一些代码保持和Python一致输入模型进行预测。
第一种方法的经验之谈 在使用conda的环境中conda和pip都可以下载包两种方式最好不要混用避免出现奇奇怪怪的错误 例如C:\ProgramData\anaconda3\DLLs_ctypes.pyd PIL_imaging.cp311-win_amd64.pyd”。模块已生成不包含符号。等等无法加载的错误 本人使用conda下载的使用pip卸载后重新使用pip装就解决了问题 cv 2numpypillow等包都是如此统一conda或者统一使用pip推荐使用pip 这样使用visual studio C调用python import的包就不会出现加载不了的问题 务必注意 pip install 包名版本号
不要轻易使用conda 一键升级包会导致部分版本太高不兼容 本人将python升级到3.11.9后cv2版本对不上也找不到对应版本的 冒险使用官网上最新的版本竟然可以使用
expected np.ndarray (got numpy.ndarray) 这个问题也是numpy版本过高导致 pip install numpy1.26.4就解决了 总之版本太高就会出现各种奇奇怪怪的bug修来修去非常浪费时间。
手动清除包缓存可以使用以下命令 pip cache purge 这个命令会清除所有缓存包括已下载但未安装的软件包和已安装但未被使用的缓存。
只想清除特定软件包的缓存可以使用以下命令 pip cache remove package-name
第二种 在C部署PytorchLibtorch模型的方法总结Win10VS2017 读取torchlib文件夹所有的lib文件的python代码
import osdef list_lib_files(directory):try:# 获取目录中的所有文件和文件夹files_and_dirs os.listdir(directory)# 筛选出以“lib”结尾的文件lib_files [f for f in files_and_dirs if f.endswith(.lib)]# 打印每个文件的全名for file_name in lib_files:print(file_name)except Exception as e:print(f发生错误: {e})
directory_path rC:\Users\TomSawyer\Downloads\Compressed\libtorch\lib
list_lib_files(directory_path)asmjit.lib
c10.lib
cpuinfo.lib
dnnl.lib
fbgemm.lib
fbjni.lib
fmt.lib
kineto.lib
libprotobuf-lite.lib
libprotobuf.lib
libprotoc.lib
pthreadpool.lib
pytorch_jni.lib
sleef.lib
torch.lib
torch_cpu.lib
XNNPACK.libVS 配置外部DLL的引用路径【可执行文件的环境路径】 右键项目属性-配置属性-调试-环境在这里写入可执行文件运行时的环境路径
本人莎莎的以为要重写PyTorch模型网络架构于是使用C的LibTorch和gpt重写了一下结果一致卡在load不上非常奇怪于是检查两个网络的架构其实非常类似忘记截图载下来了就下面一张图 检查python的Pytorch模型 与 使用C创建的LibTorch模型是否一致先看看VGG模型长啥样
其实可以直接加载模型pt文件里面保存了网络的架构的无需重写具体代码找一找就有 我之前都注释了代码没问题的自行理解一下 将pth保存为pt再加载pt模型 .pt文件保存的是模型的全部在加载时可以直接赋值给新变量model torch.load(“filename.pt”)。 .pth保存的是模型参数通过字符字典进行保存在加载该类文件时应该先实例化一个具体的模型然后对新建立的空模型进行参数赋予。
import os
import cv2
from PIL import Image
from torchvision import transforms as T
import torchload_model_path ./checkpoints/Cnn.pth
model getattr(models, Cnn)()
device torch.device(cuda:0 if torch.cuda.is_available() else cpu)
model.to(device)
model.load(load_model_path)
model.eval()vartorch.ones((1,3,224,224))
traced_script_module torch.jit.trace(model, var)
traced_script_module.save(./checkpoints/Cnn.pt)# 测试pt模型
model_pt torch.load(./checkpoints/Cnn.pt)
model_pt.to(device)
model_pt.eval()将Python保存的pth模型与pt模型进行对比看看保存的两个模型是否有差异没有任何差异 使用C实现Python的图像处理部分看看实现是否有差异发现数值类似略有差异 猜测可能是摄像头保存一帧 与 C读取图像的不同所引起的于是使用Python读取图像试试 发现结果一致了原来是保存为jpg格式带来的有损压缩导致的 统一保存为png格式即可无损格式
全部代码 Python使用Pytorch加载模型处理图像模型预测结果模型是错的只是走个流程
import os
import cv2
from PIL import Image
from torchvision import transforms as T
import models
import datetime
import torch# 创建保存图像的文件夹
if not os.path.exists(testModel):os.makedirs(testModel)# 1 先使用摄像头读取一帧图像保存
# 0读取摄像头保存的图片
flag 0
if flag1:cap cv2.VideoCapture(0)if not cap.isOpened():print(无法打开摄像头)else:# 读取一帧图像ret, frame cap.read()if ret:# 保存原始图像original_image_path testModel/test1_original_image.pngcv2.imwrite(original_image_path, frame)print(f原始图像已保存到 {original_image_path})# 释放摄像头资源cap.release()
else:##读取摄像头保存的一帧画面frame cv2.imread(testModel/test1_original_image.png);此类主要提供模型调用方法接受一个图片同时返回一个力的结果model_list os.listdir(./checkpoints/)
# load_model_path ./checkpoints/ model_list[0]
load_model_path ./checkpoints/Cnn.pth
model getattr(models, Cnn)()
device torch.device(cuda:0 if torch.cuda.is_available() else cpu)
model.to(device)
model.load(load_model_path)
model.eval()# 测试pt模型
model_pt torch.load(./checkpoints/Cnn.pt)
model_pt.to(device)
model_pt.eval()# veision1 预定义图像处理模式,图像预处理设置,正态化数据来自于图片空间因此需要Normalize.py获取此处已指定
normalize T.Normalize(mean[0.684, 0.831, 0.83],std[0.684, 0.831, 0.83])
transform T.Compose([T.ToTensor(),# normalize]
)img frame
cv2.imshow( , img)
cv2.waitKey(0)
imgcv2.resize(img,[640,360])
# 裁剪图像保留从第170列到第530列的区域
imgimg[::,170:530,::] #样品1
cv2.imshow( , img)
cv2.waitKey(0)
# 保存处理后的图像
processed_image_path testModel/test1_processed_image.png
cv2.imwrite(processed_image_path, img)
print(f处理后的图像已保存到 {processed_image_path})img Image.fromarray(img)
img transform(img)
img img.view(1, img.shape[0], img.shape[1], img.shape[2])#改变张量的形状但不会改变其数据 第一、第二、第三和第四维度大小。
train img.to(device)
force model(train)
force force.squeeze().detach().cpu()
force_act force.tolist()
# 时间格式为分钟秒.微秒
force_act.append(datetime.datetime.now().strftime(%M:%S.%f))
# force_act为输出力的列表格式【f(x),f(y),f(z),时间】
print(pth模型结果,force_act)force_pt model_pt(train)
force_pt force_pt.squeeze().detach().cpu()
force_act_pt force_pt.tolist()
# 时间格式为分钟秒.微秒
force_act_pt.append(datetime.datetime.now().strftime(%M:%S.%f))
# force_act为输出力的列表格式【f(x),f(y),f(z),时间】
print(pt模型结果,force_act_pt)C加载torch script保存的pt模型重新实现图像处理给出结果
#include torch/torch.h
#include torch/script.h
#include string
#include iostream
#include opencv2/opencv.hpp// 假设你已经定义了transform函数
torch::Tensor transform(const cv::Mat img) {// 这里需要根据你的transform逻辑来实现// 例如假设你只是将图像转换为Tensortorch::Tensor tensor_image torch::from_blob(img.data, { img.rows, img.cols, img.channels() }, torch::kFloat32);将OpenCV图像数据存储在img.data中转换为一个PyTorch张量张量的形状为[img.rows, img.cols, img.channels()]数据类型为kFloat32tensor_image tensor_image.permute({ 2, 0, 1 }).to(torch::kFloat); // 转换为CHW格式并转换为Float类型return tensor_image;
}int test_pt() {// 假设模型路径和加载方式torch::jit::script::Module module;try {module torch::jit::load(R(C:\Users\TomSawyer\source\repos\testPython\force_indentify\checkpoints\Cnn.pt));} catch (const c10::Error e) {std::cerr Error loading the model\n;return {};}// 检查CUDA是否可用bool is_cuda torch::cuda::is_available();torch::Device device(is_cuda ? torch::kCUDA : torch::kCPU);std::cout (is_cuda ? CUDA is available. Using GPU. : Using CPU.) std::endl;module.to(device);module.eval();// 指定图像路径std::string imagePath R(C:\Users\TomSawyer\source\repos\testPython\force_indentify\testModel\test1_original_image.png);while (1) {cv::Mat frame cv::imread(imagePath, cv::IMREAD_COLOR);// 检查图像是否加载成功if (frame.empty()) {std::cerr 无法加载图片请检查路径: imagePath std::endl;return -1;}// 显示图片cv::imshow(Loaded Image, frame);cv::waitKey(0);cv::resize(frame, frame, cv::Size(640, 360));cv::imshow(frame, frame);cv::waitKey(0);frame frame(cv::Rect(170, 0, 360, 360)); // 裁剪图像170到360列cv::imshow(frame, frame);cv::waitKey(0);frame.convertTo(frame, CV_32FC3, 1.0 / 255.0);// 应用transformtorch::Tensor tensor_image transform(frame);// 调整形状tensor_image tensor_image.unsqueeze(0); // 增加batch维度tensor_image tensor_image.to(device);// 模型预测std::vectortorch::jit::IValue inputs;inputs.push_back(tensor_image);at::Tensor output module.forward(inputs).toTensor();//bugoutput output.squeeze().detach().cpu();std::vectorfloat force_act { output[0].itemfloat(), output[1].itemfloat(), output[2].itemfloat() };std::cout pt_Force: force_act[0] , force_act[1] , force_act[2] std::endl;}return {};
}int main() {test_pt(); //测试pt模型和python的pthreturn 0;
}pybind11运行一直没解决cv2numpy包解决了Torch包一直搞不定
#include pybind11/pybind11.h
#include pybind11/embed.h
#include iostream
#include cstdlib // for _putenvnamespace py pybind11;int main() {// 设置 Python 解释器的路径为 Conda 环境std::string pythonHome R(C:\ProgramData\anaconda3);std::string pythonHomeEnv PYTHONHOME pythonHome;_putenv(pythonHomeEnv.c_str());// 设置 Python 路径std::string pythonPath R(C:\ProgramData\anaconda3\Lib\site-packages;C:\Users\TomSawyer\source\repos\testPython\force_indentify;);std::string pythonPathEnv PYTHONPATH pythonPath;_putenv(pythonPathEnv.c_str());// 添加 PATH 环境变量std::string path R(C:\ProgramData\anaconda3\Library\bin;);std::string pathEnv PATH path ; getenv(PATH);_putenv(pathEnv.c_str());//std::cout PythonHome: pythonHomeEnv std::endl;//std::cout PythonPath: pythonPathEnv std::endl;std::cout PATH: getenv(PATH) std::endl;// 初始化 Python 解释器py::scoped_interpreter guard{};//在使用 pybind11 导入 Python 模块时路径的指定方式需要注意。通常情况下Python 模块的导入路径应该是模块的名称而不是文件的绝对路径// 添加模块路径到 sys.pathpy::module::import(sys).attr(path).attr(append)(R(C:\Users\TomSawyer\source\repos\testPython\force_indentify;C:\Users\TomSawyer\source\repos\testPython\force_indentify\models));//std::cout std::endl PATH: getenv(PATH) std::endl;// 导入 Python 模块py::module script py::module::import(interface_single);// 调用 Python 函数并获取返回的列表py::object result script.attr(inter)();py::list py_list result.castpy::list();// 将 Python 列表转换为 C 向量std::vectorint cpp_list;for (auto item : py_list) {cpp_list.push_back(item.castint());}// 处理 C 向量for (int value : cpp_list) {std::cout value ;}std::cout std::endl;return 0;
}