ss928_framework/Readme.md
leon 446c6cd638 fix(Readme): 优化了代码结构并更新了执行脚本
详细描述:

1.更新了Readme.md文件的说明信息,增加了上传和设置环境的步骤指导。
2025-02-11 15:53:31 +08:00

404 lines
12 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# wsl环境
## 1. 安装wsl
ubuntu版本必须为18.04。
windows打开powershell 输入以下命令不要使用cmd
```bahs
wsl --install -d Ubuntu-18.04
```
安装参考地址https://learn.microsoft.com/zh-cn/windows/wsl/install
## 2.正常安装928的开发环境参考指南。
## 3.修改目录
### 3.1 交叉编译工具
修改`cmake/ss298.cmake`目录交叉编译工具路径
```bash
SET(CMAKE_C_COMPILER /opt/linux/x86-arm/aarch64-mix210-linux/bin/aarch64-mix210-linux-gcc)
SET(CMAKE_CXX_COMPILER /opt/linux/x86-arm/aarch64-mix210-linux/bin/aarch64-mix210-linux-g++)
SET(CMAKE_STRIP /opt/linux/x86-arm/aarch64-mix210-linux/bin/aarch64-mix210-linux-strip)
```
### 3.2 修改`CMakeLists.txt`
把全部的`/home/setups/ss928_framework/` 替换为自己wsl项目目录比如`/mnt/d/ss928_framework/`
## 4. 把虚拟机中相关目录拷贝wsl中同样的目录下
需要复制的目录为
- /usr/local/lib
- /usr/local/local
```text
注意!!!, 注意!!!, 注意!!!,
_.--""--._
.' `.
/ O O \
| \ ^^ / |
\ `----' /
`. _______ .'
//_____\\
(( ____ ))
`------'
```
复制粘贴- `/usr/local/lib`和`/usr/local/local`先打成压缩包再解压到wsl目录中直接从虚拟机中复制出来的时候会报错不支持符号链接的主机无法复制。
压缩并保持符号链接
```bash
cd /usr/local/lib
zip -ry ~/lib.zip ./*
cd /usr/local/include
zip -ry ~/include.zip ./*
```
- -r 这个选项表示递归地处理目录
- -y 保持符合链接
自行放到wsl任意目录,cd进入该目录解压。如需强制覆盖加上-o参数
```bash
sudo unzip lib.zip -d /usr/local/lib/
sudo unzip include.zip -d /usr/local/include/
```
# 把板子上相关目录拷贝wsl中同样的目录下
需要复制到目录为
- /lib/aarch64-linux-gnu
- /usr/lib/aarch64-linux-gnu
```bash
cd /lib/aarch64-linux-gnu
zip -ry ~/lib_agnu.zip ./*
cd /usr/lib/aarch64-linux-gnu
zip -ry ~/usr_lib_agnu.zip ./*
```
自行放到wsl任意目录,cd进入该目录解压。如需强制覆盖加上-o参数
```bash
sudo unzip lib_agnu.zip -d /lib/aarch64-linux-gnu/
sudo unzip usr_lib_agnu.zip -d /usr/lib/aarch64-linux-gnu/
```
# cmake3.24版本
下载地址https://cmake.org/files/v3.24/cmake-3.24.0-linux-aarch64.tar.gz
解压后的bin目录为可执行文件自行放到目录中。
# 5.编译
```bash
mkdir build
cd build
cmake ..
make -j(nproc)
```
`build/libss928driver.so`为生成的动态库文件
# 执行
**上传**
- ss928sdk/lib 拷贝到 板端目录下
- 将生成的动态库文件`build/libss928driver.so`拷贝到板端目录下
- 将om模型文件拷贝到板端目录下
- 自己要测试的图片以及下面所属的python脚本
你最终的目录结构应该是这样的
```text
_test_928_batch.py #脚本
best_sea_salt.om # 模型文件
lib/ # 库文件
libss928driver.so # 编译的动态库
ymj_sea_salt/ # 测试图片目录
ymj_sea_salt_result/ #结果图片目录
```
**设置环境**
```bash
# 设置环境变量能读取到lib的动态库
export LD_LIBRARY_PATH=${PWD}/lib:${PWD}/lib/npu:${PWD}/lib/svp_npu:$LD_LIBRARY_PATH
# fix ymj runtime oserror /usr/lib/aarch64-linux-gnu/libgomp.so.1: cannot allocate memory in static TLS block
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1:$LD_PRELOAD
```
**创建conda环境**
- 将下面内容复制保存为`environment.yaml`,
- 然后在板端执行`conda env create -f environment.yaml`
- 创建完毕之后,激活环境`conda activate ymj`。
```
name: ymj
channels:
- defaults
- https://repo.anaconda.com/pkgs/main
- https://repo.anaconda.com/pkgs/r
dependencies:
- _libgcc_mutex=0.1=main
- _openmp_mutex=5.1=51_gnu
- anaconda-anon-usage=0.4.4=py312h7d20cce_100
- archspec=0.2.3=pyhd3eb1b0_0
- boltons=23.0.0=py312hd43f75c_0
- brotli-python=1.0.9=py312h419075a_8
- bzip2=1.0.8=h998d150_6
- c-ares=1.19.1=h998d150_0
- ca-certificates=2024.9.24=hd43f75c_0
- certifi=2024.8.30=py312hd43f75c_0
- cffi=1.17.1=py312hcb1262d_0
- charset-normalizer=3.3.2=pyhd3eb1b0_0
- conda=24.9.2=py312hd43f75c_0
- conda-content-trust=0.2.0=py312hd43f75c_1
- conda-libmamba-solver=24.9.0=pyhd3eb1b0_0
- conda-package-handling=2.3.0=py312hd43f75c_0
- conda-package-streaming=0.10.0=py312hd43f75c_0
- cryptography=43.0.0=py312h5077475_0
- distro=1.9.0=py312hd43f75c_0
- expat=2.6.3=h419075a_0
- fmt=9.1.0=hb8fdbf2_1
- frozendict=2.4.2=py312hd43f75c_0
- icu=73.1=h419075a_0
- idna=3.7=py312hd43f75c_0
- jsonpatch=1.33=py312hd43f75c_1
- jsonpointer=2.1=pyhd3eb1b0_0
- krb5=1.20.1=h2e2fba8_1
- ld_impl_linux-aarch64=2.40=h48e3ba3_0
- libarchive=3.7.4=h4086d46_0
- libcurl=8.9.1=hfa2bbb0_0
- libedit=3.1.20230828=h998d150_0
- libev=4.33=hfd63f10_1
- libffi=3.4.4=h419075a_1
- libgcc-ng=11.2.0=h1234567_1
- libgomp=11.2.0=h1234567_1
- libmamba=1.5.8=h0a4e7f9_3
- libmambapy=1.5.8=py312hd82f176_3
- libnghttp2=1.57.0=hb788212_0
- libsolv=0.7.24=h94b7715_1
- libssh2=1.11.0=hfa2bbb0_0
- libstdcxx-ng=11.2.0=h1234567_1
- libuuid=1.41.5=h998d150_0
- libxml2=2.13.1=h6097fa9_2
- lz4-c=1.9.4=h419075a_1
- menuinst=2.1.2=py312hd43f75c_0
- ncurses=6.4=h419075a_0
- openssl=3.0.15=h998d150_0
- packaging=24.1=py312hd43f75c_0
- pcre2=10.42=hcfaa891_1
- pip=24.2=py312hd43f75c_0
- platformdirs=3.10.0=py312hd43f75c_0
- pluggy=1.0.0=py312hd43f75c_1
- pybind11-abi=5=hd3eb1b0_0
- pycosat=0.6.6=py312h998d150_1
- pycparser=2.21=pyhd3eb1b0_0
- pysocks=1.7.1=py312hd43f75c_0
- python=3.12.7=h8edadfe_0
- readline=8.2=h998d150_0
- reproc=14.2.4=h419075a_2
- reproc-cpp=14.2.4=h419075a_2
- requests=2.32.3=py312hd43f75c_0
- ruamel.yaml=0.18.6=py312h998d150_0
- ruamel.yaml.clib=0.2.8=py312h998d150_0
- setuptools=75.1.0=py312hd43f75c_0
- sqlite=3.45.3=h998d150_0
- tk=8.6.14=h987d8db_0
- tqdm=4.66.5=py312h42ac6d5_0
- truststore=0.8.0=py312hd43f75c_0
- tzdata=2024b=h04d1e81_0
- urllib3=2.2.3=py312hd43f75c_0
- wheel=0.44.0=py312hd43f75c_0
- xz=5.4.6=h998d150_1
- yaml-cpp=0.8.0=h419075a_1
- zlib=1.2.13=h998d150_1
- zstandard=0.23.0=py312hc476304_0
- zstd=1.5.6=h6a09583_0
- pip:
- colorlog==6.9.0
- cython==3.0.11
- numpy==2.1.3
- opencv-python==4.10.0.84
- pyzmq==26.2.0
- simplejpeg==1.7.6
- vidgear==0.3.3
prefix: /root/miniconda3/envs/ymj
```
**python执行脚本**
```python
# -- coding: utf-8 --
import os
import sys
import subprocess
import ctypes
from ctypes import *
import platform
import time
import cv2
import numpy as np
from vidgear.gears import VideoGear
from vidgear.gears import NetGear
sys.path.append(r'./')
print(platform.architecture())
libss928 = ctypes.cdll.LoadLibrary("libss928driver.so")
class _TAROBJECT_(Structure):
pass
_TAROBJECT_._fields_ = [
('x', c_int),
('y', c_int),
('width', c_int),
('height', c_int),
('label', c_int),
('prob', c_float),
('text', c_char * 256),
]
TAROBJECT = _TAROBJECT_
class _RETURN_BOJECT_(Structure):
pass
_RETURN_BOJECT_._fields_ = [
('count', c_int),
('objects', TAROBJECT * 128),
]
RETURN_BOJECT = _RETURN_BOJECT_
def LibapiSvpNpuHandleSig():
libss928.LibapiSvpNpuHandleSig.argtype = c_void_p
libss928.LibapiSvpNpuHandleSig.restype = c_uint
return libss928.LibapiSvpNpuHandleSig()
def LibapiSvpNpuAclPrepareInit():
libss928.LibapiSvpNpuAclPrepareInit.argtype = c_void_p
libss928.LibapiSvpNpuAclPrepareInit.restype = c_uint
return libss928.LibapiSvpNpuAclPrepareInit()
def LibApiSvpNpuAclPrepareExit():
libss928.LibApiSvpNpuAclPrepareExit.argtype = c_void_p
libss928.LibApiSvpNpuAclPrepareExit.restype = c_uint
return libss928.LibApiSvpNpuAclPrepareExit()
def LibApiSvpNpuLoadModel(om_model_path, model_index, is_cached):
libss928.LibApiSvpNpuLoadModel.argtype = (c_char_p, c_int, c_bool)
libss928.LibApiSvpNpuLoadModel.restype = c_uint
return libss928.LibApiSvpNpuLoadModel(om_model_path, model_index, is_cached)
def LibApiSvpNpuUnLoadModel(model_index):
libss928.LibApiSvpNpuUnLoadModel.argtype = (c_int)
libss928.LibApiSvpNpuUnLoadModel.restype = c_uint
return libss928.LibApiSvpNpuUnLoadModel(model_index)
def LibApiSvpNpuLoadDataset(model_index, src, data_len, imgin_w, imgin_h, flag):
libss928.LibApiSvpNpuLoadDataset.argtype = (c_int, c_void_p, c_int, c_int, c_int, c_int)
libss928.LibApiSvpNpuLoadDataset.restype = c_uint
return libss928.LibApiSvpNpuLoadDataset(model_index, src, data_len, imgin_w, imgin_h, flag)
def LibApiSvpNpuUnloadDataset():
libss928.LibApiSvpNpuUnloadDataset.argtype = c_void_p
libss928.LibApiSvpNpuUnloadDataset.restype = c_uint
return libss928.LibApiSvpNpuUnloadDataset()
def LibApiSvpNpuModelExecute(model_index):
libss928.LibApiSvpNpuModelExecute.argtype = (c_int)
libss928.LibApiSvpNpuModelExecute.restype = c_uint
return libss928.LibApiSvpNpuModelExecute(model_index)
def LibApiSvpNpuGetModelExecuteResult(model_index, retrunObject):
libss928.LibApiSvpNpuGetModelExecuteResult.argtype = (c_uint , c_void_p)
libss928.LibApiSvpNpuGetModelExecuteResult.restype = c_uint
return libss928.LibApiSvpNpuGetModelExecuteResult(model_index, byref(retrunObject))
def _run_sh():
os.chdir('/root/ss928_framework/build/output/')
script_path = os.path.join('/root/ss928_framework/build/output/', 'rundemo.sh')
print(script_path)
try:
result = subprocess.run(['source ' + script_path, script_path], shell=True)
print("脚本执行成功")
except subprocess.CalledProcessError as e:
print(f"脚本执行失败,返回码: {e.returncode}")
exit()
if __name__ == "__main__":
options = {
"flag": 0, "copy": False, "track": False,
"jpeg_compression": True,
"jpeg_compression_quality": 90,
"jpeg_compression_fastdct": True,
"jpeg_compression_fastupsample": True
}
# 开启Netgear服务
server = NetGear(
address="192.168.101.46",
port="5454",
protocol="tcp",
pattern=1,
logging=True,
**options
)
idxx = 0
base_path = "./ymj_sea_salt/" # 图片输入目录
result_path = "./ymj_sea_salt_result/" # 图片输出目录
om_file_name = "best_sea_salt.om"
# om_file_name = "best_hyp_add_samll_1_fp32_precision_mode_precision_mode.om"
om_file_path = "./"
# 确保输出目录存在
if not os.path.exists(result_path):
os.makedirs(result_path)
# 获取所有图片文件
image_files = [f for f in os.listdir(base_path) if f.lower().endswith(('jpg', 'jpeg', 'png'))]
for image_file in image_files:
try:
if idxx == 0:
LibapiSvpNpuHandleSig()
LibapiSvpNpuAclPrepareInit()
mpath = ctypes.c_char_p((om_file_path + om_file_name).encode('utf-8'))
LibApiSvpNpuLoadModel(mpath, 0, False)
idxx = 1
# 读取当前图片
frame = cv2.imread(os.path.join(base_path, image_file))
# frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
if frame is None:
continue
# 进行处理
ptr = frame.ctypes.data_as(np.ctypeslib.ctypes.c_void_p)
LibApiSvpNpuLoadDataset(0, ptr, frame.shape[0] * frame.shape[1] * frame.shape[2],
frame.shape[1], frame.shape[0], cv2.CV_8UC3)
LibApiSvpNpuModelExecute(0)
# 获取分析结果
return_objs = RETURN_BOJECT()
res = LibApiSvpNpuGetModelExecuteResult(0, return_objs)
print(f"LibApiSvpNpuGetModelExecuteResult.res====================================: {res}")
print(f"objs.count====================================: {return_objs.count}")
if return_objs.count > 0:
for i in range(0, return_objs.count):
if i == 128: break
tarObject = return_objs.objects[i]
if tarObject.label == 0:
frame = cv2.rectangle(frame, (tarObject.x, tarObject.y + 20),
(tarObject.x + tarObject.width, tarObject.y + 20 + tarObject.height),
(0, 0, 255), 2)
# 保存结果图像到新的目录,保持文件名不变
result_file_path = os.path.join(result_path, image_file)
cv2.imwrite(result_file_path, frame)
# 清理
LibApiSvpNpuUnloadDataset()
except KeyboardInterrupt:
break
LibApiSvpNpuUnLoadModel(0)
```
**执行**
```bash
python _test_928_batch.py
```