add python demos
This commit is contained in:
parent
3bdf2003ec
commit
c91356fc38
97 changed files with 3250 additions and 290 deletions
|
|
@ -0,0 +1,133 @@
|
|||
# yolov8
|
||||
|
||||
## 1.Overview
|
||||
|
||||
YOLOv8 was released by Ultralytics on January 10, 2023, offering cutting-edge performance in terms of accuracy and speed. Building upon the advancements of previous YOLO versions, YOLOv8 introduced new features and optimizations that make it an ideal choice for various [object detection](https://www.ultralytics.com/blog/a-guide-to-deep-dive-into-object-detection-in-2025) tasks in a wide range of applications.
|
||||
|
||||
## 2.Model Download
|
||||
|
||||
- **Open Source model**
|
||||
|
||||
- **Open Source projects:** https://github.com/ultralytics/ultralytics/tree/v8.2.0
|
||||
|
||||
- **Export Model Step:**
|
||||
|
||||
- **Install ultralytics**
|
||||
|
||||
pip install torch==2.4.1
|
||||
|
||||
pip install torchvision==0.19.1
|
||||
|
||||
pip install ultralytics==8.2.0
|
||||
|
||||
- **Download weights**
|
||||
|
||||
wget https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8m.pt
|
||||
|
||||
wget https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8s.pt
|
||||
|
||||
wget https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt
|
||||
|
||||
- **Export Model**
|
||||
|
||||
```
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8m.pt")
|
||||
model.export(format="onnx", opset=12, simplify=True, dynamic=False, imgsz=640)
|
||||
```
|
||||
|
||||
|
||||
- **Exported Model**
|
||||
|
||||
link to amlogic server( **onnx model or quantized tflite**)
|
||||
|
||||
|
||||
|
||||
## 3. Model Conversion
|
||||
|
||||
```
|
||||
cd model
|
||||
Usage: ./adla_covnert.sh model_path adla_tookkit_path target_platform
|
||||
|
||||
example
|
||||
./adla_covnert.sh yolov8m.onnx /xxxx/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
|
||||
./adla_covnert.sh yolov8s.onnx /xxxx/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
|
||||
./adla_covnert.sh yolov8n.onnx /xxxx/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
|
||||
```
|
||||
|
||||
| Parameter | Discription |
|
||||
| ----------------- | ------------------------------------------------------------ |
|
||||
| model_path | onnx model path |
|
||||
| adla_tookkit_path | path to adla_toolkit |
|
||||
| target_platform | Specify target platform. for A311D2 : PRODUCT_PID0XA003。for S905X5: PRODUCT_PID0XA005 |
|
||||
|
||||
|
||||
|
||||
## 4. Demo Run
|
||||
|
||||
### CPP
|
||||
|
||||
#### 1. Compile
|
||||
|
||||
**Prerequisites:**
|
||||
- Android NDK (r25e recommended)
|
||||
- `ANDROID_NDK_PATH` environment variable set
|
||||
|
||||
**Build:**
|
||||
```bash
|
||||
# Build for arm64-v8a
|
||||
cd examples/yolov8/cpp
|
||||
./build-android.sh -a arm64-v8a
|
||||
```
|
||||
|
||||
The executable will be generated at `build/android/yolov8_demo` (Note: executable name may vary, verify in build folder).
|
||||
|
||||
#### 2. Run
|
||||
|
||||
```bash
|
||||
# Push executable to device
|
||||
adb push build/android/yolov8_demo /data/local/tmp/
|
||||
adb push model/yolov8s_int8_A311D2.adla /data/local/tmp/
|
||||
adb push test_image.jpg /data/local/tmp/
|
||||
|
||||
# Run on device
|
||||
adb shell
|
||||
cd /data/local/tmp
|
||||
chmod +x yolov8_demo
|
||||
export LD_LIBRARY_PATH=/vendor/lib64 or (/vendor/lib)
|
||||
|
||||
# Usage: ./yolo_world_demo <model_path> <image_path>
|
||||
./yolov8_demo yolov8s_int8_A311D2.adla test_image.jpg"
|
||||
```
|
||||
|
||||
**Note:** Replace `yolov8s_int8_A311D2.adla` with your actual model file path.
|
||||
|
||||
### Python
|
||||
|
||||
**Prerequisites:**
|
||||
- Python 3.10
|
||||
- Required packages: `numpy`, `opencv-python`, `amlnnlite`
|
||||
|
||||
**Install dependencies:**
|
||||
```bash
|
||||
pip install numpy opencv-python amlnnlite-1.0.0-cp310-cp310-linux_aarch64.whl
|
||||
```
|
||||
|
||||
**Run on device:**
|
||||
```bash
|
||||
python yolov8.py --model-path ./yolov8s_int8_A311D2.adla
|
||||
```
|
||||
|
||||
The script will automatically process all image files (`.jpg`, `.jpeg`, `.png`, `.bmp`) in the current directory and save results to a `{model_name}_result` folder.
|
||||
|
||||
## 5.Results
|
||||
The program will print the detection count and inference time. The result image with bounding boxes will be saved to the specified output path (`result.jpg` by default).
|
||||
|
||||
|
||||
You can pull the result image back to view it:
|
||||
```bash
|
||||
adb pull result.jpg.
|
||||
```
|
||||

|
||||
|
||||
|
|
@ -62,8 +62,6 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
// 3. Preprocess
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto [preprocessed, scale, pad] = preprocess(img, std::make_tuple(MODEL_INPUT_HEIGHT, MODEL_INPUT_WIDTH));
|
||||
|
||||
// Quantize to int8 (model expects quantized input)
|
||||
|
|
@ -88,6 +86,7 @@ int main(int argc, char** argv) {
|
|||
outconfig.typeSize = sizeof(aml_output_config_t);
|
||||
outconfig.format = AML_OUTDATA_FLOAT32;
|
||||
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
nn_output* outdata = (nn_output*)aml_module_output_get(context, outconfig);
|
||||
if (!outdata) {
|
||||
std::cerr << "Failed to run network." << std::endl;
|
||||
|
|
@ -103,8 +102,8 @@ int main(int argc, char** argv) {
|
|||
const int channels = 144; // 64 DFL + 80 classes
|
||||
|
||||
std::vector<Detection> detections = postprocess(
|
||||
std::make_tuple(outbuf0, std::make_tuple(MODEL_INPUT_HEIGHT / 16, MODEL_INPUT_WIDTH / 16, channels), 16),
|
||||
std::make_tuple(outbuf1, std::make_tuple(MODEL_INPUT_HEIGHT / 8, MODEL_INPUT_WIDTH / 8, channels), 8),
|
||||
std::make_tuple(outbuf0, std::make_tuple(MODEL_INPUT_HEIGHT / 8, MODEL_INPUT_WIDTH / 8, channels), 8),
|
||||
std::make_tuple(outbuf1, std::make_tuple(MODEL_INPUT_HEIGHT / 16, MODEL_INPUT_WIDTH / 16, channels), 16),
|
||||
std::make_tuple(outbuf2, std::make_tuple(MODEL_INPUT_HEIGHT / 32, MODEL_INPUT_WIDTH / 32, channels), 32),
|
||||
std::make_tuple(preprocessed, scale, pad),
|
||||
SCORE_THRESHOLD,
|
||||
|
|
|
|||
24
examples/yolov8/model/adla_convert.sh
Executable file
24
examples/yolov8/model/adla_convert.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
# 1. $1: set ADLA_TOOL_PATH
|
||||
# 2. $2: set target-plaftorm
|
||||
# for A311D2 target-platform is PRODUCT_PID0XA003
|
||||
# for S905X5 target-platform is PRODUCT_PID0XA005
|
||||
# Usage: ./adla_covnert.sh yolov8m.onnx /XXX/adla-toolkit-binary-3.2.9.3 PRODUCT_PID0XA005
|
||||
|
||||
model_path=$1
|
||||
ADLA_TOOL_PATH=$2
|
||||
target_platform=$3
|
||||
|
||||
echo "model_path:[$model_path]"
|
||||
echo "ADLA_TOOL_PATH:[$ADLA_TOOL_PATH]"
|
||||
echo "target-plaftorm:[$target_platform]"
|
||||
|
||||
adla_convert=${ADLA_TOOL_PATH}/bin/adla_convert
|
||||
|
||||
$adla_convert --model-type onnx \
|
||||
--model $model_path \
|
||||
--inputs images --input-shapes "1,3,640,640" \
|
||||
--quantize-dtype int8 \
|
||||
--source-file dataset_coco.txt \
|
||||
--channel-mean-value "0,0,0,255" \
|
||||
--outputs "/model.22/Concat_output_0 /model.22/Concat_1_output_0 /model.22/Concat_2_output_0" \
|
||||
--target-platform $target_platform
|
||||
50
examples/yolov8/model/dataset_coco.txt
Executable file
50
examples/yolov8/model/dataset_coco.txt
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
../../../resource/coco_dataset/000000000139.jpg
|
||||
../../../resource/coco_dataset/000000000285.jpg
|
||||
../../../resource/coco_dataset/000000000632.jpg
|
||||
../../../resource/coco_dataset/000000000724.jpg
|
||||
../../../resource/coco_dataset/000000000776.jpg
|
||||
../../../resource/coco_dataset/000000000785.jpg
|
||||
../../../resource/coco_dataset/000000000802.jpg
|
||||
../../../resource/coco_dataset/000000000872.jpg
|
||||
../../../resource/coco_dataset/000000000885.jpg
|
||||
../../../resource/coco_dataset/000000001000.jpg
|
||||
../../../resource/coco_dataset/000000001268.jpg
|
||||
../../../resource/coco_dataset/000000001296.jpg
|
||||
../../../resource/coco_dataset/000000001353.jpg
|
||||
../../../resource/coco_dataset/000000001425.jpg
|
||||
../../../resource/coco_dataset/000000001490.jpg
|
||||
../../../resource/coco_dataset/000000001503.jpg
|
||||
../../../resource/coco_dataset/000000001532.jpg
|
||||
../../../resource/coco_dataset/000000001584.jpg
|
||||
../../../resource/coco_dataset/000000001675.jpg
|
||||
../../../resource/coco_dataset/000000001761.jpg
|
||||
../../../resource/coco_dataset/000000001818.jpg
|
||||
../../../resource/coco_dataset/000000001993.jpg
|
||||
../../../resource/coco_dataset/000000002006.jpg
|
||||
../../../resource/coco_dataset/000000002149.jpg
|
||||
../../../resource/coco_dataset/000000002153.jpg
|
||||
../../../resource/coco_dataset/000000002157.jpg
|
||||
../../../resource/coco_dataset/000000002261.jpg
|
||||
../../../resource/coco_dataset/000000002299.jpg
|
||||
../../../resource/coco_dataset/000000002431.jpg
|
||||
../../../resource/coco_dataset/000000002473.jpg
|
||||
../../../resource/coco_dataset/000000002532.jpg
|
||||
../../../resource/coco_dataset/000000002587.jpg
|
||||
../../../resource/coco_dataset/000000002592.jpg
|
||||
../../../resource/coco_dataset/000000002685.jpg
|
||||
../../../resource/coco_dataset/000000002923.jpg
|
||||
../../../resource/coco_dataset/000000003156.jpg
|
||||
../../../resource/coco_dataset/000000003255.jpg
|
||||
../../../resource/coco_dataset/000000003501.jpg
|
||||
../../../resource/coco_dataset/000000003553.jpg
|
||||
../../../resource/coco_dataset/000000003661.jpg
|
||||
../../../resource/coco_dataset/000000003845.jpg
|
||||
../../../resource/coco_dataset/000000003934.jpg
|
||||
../../../resource/coco_dataset/000000004134.jpg
|
||||
../../../resource/coco_dataset/000000004395.jpg
|
||||
../../../resource/coco_dataset/000000004495.jpg
|
||||
../../../resource/coco_dataset/000000004765.jpg
|
||||
../../../resource/coco_dataset/000000004795.jpg
|
||||
../../../resource/coco_dataset/000000005001.jpg
|
||||
../../../resource/coco_dataset/000000005037.jpg
|
||||
../../../resource/coco_dataset/000000005060.jpg
|
||||
281
examples/yolov8/py/yolov8.py
Executable file
281
examples/yolov8/py/yolov8.py
Executable file
|
|
@ -0,0 +1,281 @@
|
|||
import numpy as np
|
||||
import os
|
||||
import glob
|
||||
import argparse
|
||||
import cv2
|
||||
from pathlib import Path
|
||||
from amlnnlite.api import AMLNNLite
|
||||
|
||||
|
||||
class_names = {
|
||||
0: 'person', 1: 'bicycle', 2: 'car', 3: 'motorcycle', 4: 'airplane',
|
||||
5: 'bus', 6: 'train', 7: 'truck', 8: 'boat', 9: 'traffic light',
|
||||
10: 'fire hydrant', 11: 'stop sign', 12: 'parking meter', 13: 'bench', 14: 'bird',
|
||||
15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow',
|
||||
20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe', 24: 'backpack',
|
||||
25: 'umbrella', 26: 'handbag', 27: 'tie', 28: 'suitcase', 29: 'frisbee',
|
||||
30: 'skis', 31: 'snowboard', 32: 'sports ball', 33: 'kite', 34: 'baseball bat',
|
||||
35: 'baseball glove', 36: 'skateboard', 37: 'surfboard', 38: 'tennis racket', 39: 'bottle',
|
||||
40: 'wine glass', 41: 'cup', 42: 'fork', 43: 'knife', 44: 'spoon',
|
||||
45: 'bowl', 46: 'banana', 47: 'apple', 48: 'sandwich', 49: 'orange',
|
||||
50: 'broccoli', 51: 'carrot', 52: 'hot dog', 53: 'pizza', 54: 'donut',
|
||||
55: 'cake', 56: 'chair', 57: 'couch', 58: 'potted plant', 59: 'bed',
|
||||
60: 'dining table', 61: 'toilet', 62: 'tv', 63: 'laptop', 64: 'mouse',
|
||||
65: 'remote', 66: 'keyboard', 67: 'cell phone', 68: 'microwave', 69: 'oven',
|
||||
70: 'toaster', 71: 'sink', 72: 'refrigerator', 73: 'book', 74: 'clock',
|
||||
75: 'vase', 76: 'scissors', 77: 'teddy bear', 78: 'hair drier', 79: 'toothbrush'
|
||||
}
|
||||
|
||||
def letterbox(img, new_shape=(640, 640), color=(114, 114, 114)):
|
||||
shape = img.shape[:2] # [height, width]
|
||||
scale = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
|
||||
new_unpad = (int(round(shape[1] * scale)), int(round(shape[0] * scale)))
|
||||
pad_w = (new_shape[1] - new_unpad[0]) / 2
|
||||
pad_h = (new_shape[0] - new_unpad[1]) / 2
|
||||
|
||||
if shape[::-1] != new_unpad:
|
||||
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
|
||||
|
||||
top, bottom = int(round(pad_h - 0.1)), int(round(pad_h + 0.1))
|
||||
left, right = int(round(pad_w - 0.1)), int(round(pad_w + 0.1))
|
||||
img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
|
||||
|
||||
return img, scale, (left, top)
|
||||
|
||||
def preprocess(img_path, new_shape=(640, 640), data_format='NCHW', s=0.003921568859368563, zp=-128):
|
||||
original_img = cv2.imread(str(img_path))
|
||||
if original_img is None:
|
||||
raise ValueError(f"can't read image: {img_path}")
|
||||
|
||||
processed_img, scale, pad = letterbox(original_img, new_shape)
|
||||
rgb_img = cv2.cvtColor(processed_img, cv2.COLOR_BGR2RGB)
|
||||
normalized_img = rgb_img.astype(np.float32) / 255.0
|
||||
|
||||
if data_format == 'NCHW':
|
||||
# HWC -> CHW -> BCHW (ONNX default format)
|
||||
input_tensor = np.transpose(normalized_img, (2, 0, 1))
|
||||
input_tensor = np.expand_dims(input_tensor, axis=0)
|
||||
elif data_format == 'NHWC':
|
||||
# HWC -> BHWC (TFLITE default format)
|
||||
input_tensor = np.expand_dims(normalized_img, axis=0)
|
||||
else:
|
||||
raise ValueError(f"Unsupported data format: {data_format}. Only 'NCHW' and 'NHWC' are supported.")
|
||||
|
||||
# Quantize to int8
|
||||
input_tensor = np.round(input_tensor / s + zp).astype(np.int8)
|
||||
|
||||
return input_tensor, original_img, scale, pad
|
||||
|
||||
def postprocess(outputs, scale, pad, data_format='NCHW', strides=[8, 16, 32], conf_threshold=0.25, iou_threshold=0.45):
|
||||
all_boxes = []
|
||||
all_scores = []
|
||||
all_class_ids = []
|
||||
|
||||
for scale_idx, output in enumerate(outputs):
|
||||
stride = strides[scale_idx]
|
||||
|
||||
if data_format == 'NCHW':
|
||||
# (1, 144, H, W) → (H*W, 144)
|
||||
batch_size, channels, height, width = output.shape
|
||||
output_reshaped = output.transpose(0, 2, 3, 1).reshape(-1, channels)
|
||||
elif data_format == 'NHWC':
|
||||
# (1, H, W, 144) → (H*W, 144)
|
||||
batch_size, height, width, channels = output.shape
|
||||
output_reshaped = output.reshape(-1, channels)
|
||||
else:
|
||||
raise ValueError(f"Unsupported data format: {data_format}. Only 'NCHW' and 'NHWC' are supported.")
|
||||
|
||||
# Separate DFL and classification: 144 = 64(DFL) + 80(Classes)
|
||||
dfl_predictions = output_reshaped[:, :64]
|
||||
class_predictions = output_reshaped[:, 64:]
|
||||
|
||||
# Apply sigmoid activation to class scores
|
||||
class_scores = 1.0 / (1.0 + np.exp(-class_predictions))
|
||||
max_class_scores = np.max(class_scores, axis=1)
|
||||
class_ids = np.argmax(class_scores, axis=1)
|
||||
|
||||
# Generate grid coordinates
|
||||
grid_y, grid_x = np.meshgrid(np.arange(height), np.arange(width), indexing='ij')
|
||||
grid_x = grid_x.flatten().astype(np.float32)
|
||||
grid_y = grid_y.flatten().astype(np.float32)
|
||||
|
||||
# DFL decoding
|
||||
dfl_reshaped = dfl_predictions.reshape(-1, 4, 16)
|
||||
dfl_softmax = np.exp(dfl_reshaped) / np.sum(np.exp(dfl_reshaped), axis=-1, keepdims=True)
|
||||
regression_range = np.arange(16, dtype=np.float32)
|
||||
bbox_deltas = np.sum(dfl_softmax * regression_range[None, None, :], axis=-1)
|
||||
|
||||
# Convert to absolute coordinates
|
||||
anchor_x = (grid_x + 0.5) * stride
|
||||
anchor_y = (grid_y + 0.5) * stride
|
||||
|
||||
left, top, right, bottom = bbox_deltas.T
|
||||
x1 = anchor_x - left * stride
|
||||
y1 = anchor_y - top * stride
|
||||
x2 = anchor_x + right * stride
|
||||
y2 = anchor_y + bottom * stride
|
||||
|
||||
boxes = np.stack([x1, y1, x2, y2], axis=1)
|
||||
|
||||
all_boxes.append(boxes)
|
||||
all_scores.append(max_class_scores)
|
||||
all_class_ids.append(class_ids)
|
||||
|
||||
# Merge all scales
|
||||
final_boxes = np.concatenate(all_boxes, axis=0)
|
||||
final_scores = np.concatenate(all_scores, axis=0)
|
||||
final_class_ids = np.concatenate(all_class_ids, axis=0)
|
||||
|
||||
# Filter by confidence threshold
|
||||
valid_mask = final_scores > conf_threshold
|
||||
if not np.any(valid_mask):
|
||||
return []
|
||||
|
||||
valid_boxes = final_boxes[valid_mask]
|
||||
valid_scores = final_scores[valid_mask]
|
||||
valid_class_ids = final_class_ids[valid_mask]
|
||||
|
||||
# Map coordinates back to original image
|
||||
pad_x, pad_y = pad
|
||||
valid_boxes[:, [0, 2]] = (valid_boxes[:, [0, 2]] - pad_x) / scale
|
||||
valid_boxes[:, [1, 3]] = (valid_boxes[:, [1, 3]] - pad_y) / scale
|
||||
valid_boxes = np.maximum(valid_boxes, 0)
|
||||
|
||||
# NMS
|
||||
if len(valid_boxes) > 0:
|
||||
nms_indices = cv2.dnn.NMSBoxes(
|
||||
valid_boxes.tolist(), valid_scores.tolist(), conf_threshold, iou_threshold
|
||||
)
|
||||
|
||||
if len(nms_indices) > 0:
|
||||
nms_indices = nms_indices.flatten()
|
||||
detections = []
|
||||
|
||||
for idx in nms_indices:
|
||||
x1, y1, x2, y2 = valid_boxes[idx]
|
||||
confidence = valid_scores[idx]
|
||||
class_id = valid_class_ids[idx]
|
||||
|
||||
detections.append({
|
||||
'bbox': [float(x1), float(y1), float(x2), float(y2)],
|
||||
'confidence': float(confidence),
|
||||
'class_id': int(class_id),
|
||||
'class_name': class_names.get(int(class_id), f'class_{class_id}')
|
||||
})
|
||||
|
||||
return detections
|
||||
|
||||
return []
|
||||
|
||||
def get_class_color(class_id):
|
||||
import colorsys
|
||||
hue = (class_id * 137.508) % 360
|
||||
rgb = colorsys.hsv_to_rgb(hue/360.0, 0.8, 0.9)
|
||||
bgr = (int(rgb[2]*255), int(rgb[1]*255), int(rgb[0]*255))
|
||||
return bgr
|
||||
|
||||
def draw_detections(img, detections, save_path):
|
||||
result_img = img.copy()
|
||||
|
||||
for det in detections:
|
||||
x1, y1, x2, y2 = [int(coord) for coord in det['bbox']]
|
||||
confidence = det['confidence']
|
||||
class_name = det['class_name']
|
||||
class_id = det['class_id']
|
||||
|
||||
color = get_class_color(class_id)
|
||||
|
||||
cv2.rectangle(result_img, (x1, y1), (x2, y2), color, 2)
|
||||
|
||||
label = f"{class_name}: {confidence:.2f}"
|
||||
(label_w, label_h), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 1)
|
||||
cv2.rectangle(result_img, (x1, y1 - label_h - 10), (x1 + label_w, y1), color, -1)
|
||||
text_color = (255, 255, 255) if sum(color) < 400 else (0, 0, 0)
|
||||
cv2.putText(result_img, label, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, text_color, 1)
|
||||
|
||||
cv2.imwrite(save_path, result_img)
|
||||
return result_img
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--model-path', default='./yolov8s_int8_A311D2.adla')
|
||||
parser.add_argument('--run-cycles', default= 1, type=int)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Initialize AMLNNLite
|
||||
amlnn = AMLNNLite()
|
||||
amlnn.config(
|
||||
model_path=args.model_path, # Model file path, Support ADLD and quantized TFlite models
|
||||
run_cycles=args.run_cycles
|
||||
)
|
||||
amlnn.init()
|
||||
|
||||
# Find all image files in the 01_export_model directory
|
||||
image_dir = "./"
|
||||
image_extensions = ["*.jpg", "*.jpeg", "*.png", "*.bmp"]
|
||||
image_files = []
|
||||
for ext in image_extensions:
|
||||
image_files.extend(glob.glob(os.path.join(image_dir, ext)))
|
||||
image_files.extend(glob.glob(os.path.join(image_dir, ext.upper())))
|
||||
|
||||
if not image_files:
|
||||
print("No image files found in", image_dir)
|
||||
amlnn.uninit()
|
||||
return
|
||||
|
||||
print(f"Found {len(image_files)} image files to process:")
|
||||
for img_file in image_files:
|
||||
print(f" - {os.path.basename(img_file)}")
|
||||
print()
|
||||
|
||||
# Process each image
|
||||
for i, image_path in enumerate(image_files, 1):
|
||||
print(f"=" * 60)
|
||||
print(f"Processing image {i}/{len(image_files)}: {os.path.basename(image_path)}")
|
||||
print(f"=" * 60)
|
||||
|
||||
try:
|
||||
# Preprocess input
|
||||
input_tensor, original_img, scale, pad = preprocess(image_path, new_shape=(640, 640), data_format='NHWC', s=0.003921568859368563, zp=-128)
|
||||
|
||||
# Run inference
|
||||
outputs = amlnn.inference(
|
||||
inputs=[input_tensor]
|
||||
)
|
||||
|
||||
# Postprocess results
|
||||
detections = postprocess(outputs, scale, pad, data_format='NHWC', strides=[8, 16, 32], conf_threshold=0.25, iou_threshold=0.45)
|
||||
|
||||
# Print detection results
|
||||
if detections:
|
||||
print(f" Detected {len(detections)} objects:")
|
||||
for i, det in enumerate(detections, 1):
|
||||
print(f" {i}. {det['class_name']} ({det['confidence']:.2f})")
|
||||
else:
|
||||
print(" No objects detected")
|
||||
|
||||
# Save result image
|
||||
model_name = Path(args.model_path).stem
|
||||
result_dir = f"{model_name}_result"
|
||||
os.makedirs(result_dir, exist_ok=True)
|
||||
img_name = Path(image_path).stem
|
||||
save_path = os.path.join(result_dir, f"{img_name}_result.jpg")
|
||||
draw_detections(original_img, detections, str(save_path))
|
||||
print(f" Result saved to: {save_path}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error processing {os.path.basename(image_path)}: {e}")
|
||||
|
||||
print()
|
||||
|
||||
# Optional visualization
|
||||
amlnn.visualize()
|
||||
|
||||
# Release resources
|
||||
amlnn.uninit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
BIN
examples/yolov8/result.jpg
Executable file
BIN
examples/yolov8/result.jpg
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 528 KiB |
Loading…
Add table
Add a link
Reference in a new issue