I have converted pytorch model to onnx model with below codes.
#%%
import torch
import torchvision
import torch.onnx
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
#%%
# stage 1: define pytorch model
# model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
def get_model_instance_segmentation(num_classes):
model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
in_features = model.roi_heads.box_predictor.cls_score.in_features
model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
return model
model = get_model_instance_segmentation(3)
#%%
model.load_state_dict(torch.load(f'/hyeonseop/OD/amr_test/model_amr_10.pt'))
model.eval()
#%%
# generate input data
input_data = torch.randn(1, 3, 600, 800)
#%%
# stage 2 : Export Model to ONNX
torch.onnx.export(model, # 내보낼 모델
input_data, # 모델에 전달할 입력 데이터
"model_amr_10.onnx", # 내보낼 ONNX 파일 경로
export_params=True, # 모델의 가중치를 함께 내보내기
opset_version=11, # ONNX 버전 지정
do_constant_folding=True, # 상수 접기 수행 여부
input_names=['input'], # 입력 노드의 이름 지정
output_names=['output'] # 출력 노드의 이름 지정
)
and I have written this code for object detection.
#include <onnxruntime_cxx_api.h>
#include <iostream>
#include <opencv2/opencv.hpp>
// 함수 선언
void DrawBoundingBox(cv::Mat& image, float x1, float y1, float x2, float y2);
int main() {
// ONNX 런타임 환경 설정
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "app");
// ONNX 모델 로드
Ort::SessionOptions session_options;
Ort::Session session(env, "/hyeonseop/OD_git/onnx_example_1/model_amr_10.onnx", session_options);
// 이미지 파일 로드 및 전처리
cv::Mat image = cv::imread("/hyeonseop/OD/data/amr_img/160.jpg"); // 이미지 파일 로드
cv::resize(image, image, cv::Size(800, 600)); // 이미지 크기 조정
// cv::cvtColor(image, image, cv::COLOR_BGR2RGB); // 채널 변경 (BGR -> RGB)
image.convertTo(image, CV_32FC3); // 부동소수점 형식으로 변환
// 입력 텐서 생성
std::vector<float> input_data;
input_data.assign((float*)image.data, (float*)image.data + image.total() * image.channels());
std::vector<int64_t> input_shape = {1, 3, 600, 800};
Ort::Value input_tensor = Ort::Value::CreateTensor<float>(Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeDefault), input_data.data(), input_data.size(), input_shape.data(), input_shape.size());
// 모델 실행
const char* input_names[] = {"input"};
const char* output_names[] = {"output"};
std::vector<Ort::Value> output_tensors = session.Run(Ort::RunOptions{}, input_names, &input_tensor, 1, output_names, 1);
std::cout << "output tensor size : " << output_tensors.size() << std::endl;
for (auto& tensor : output_tensors) {
Ort::TensorTypeAndShapeInfo info = tensor.GetTensorTypeAndShapeInfo();
std::vector<int64_t> shape = info.GetShape();
std::cout << "shape : ";
for (auto i : shape) {
std::cout << i << " ";
}
std::cout << std::endl;
}
// 텐서가 1차원이고 요소가 있는 경우에만 데이터 출력
const float* data = output_tensors[0].GetTensorMutableData<float>();
Ort::TensorTypeAndShapeInfo info = output_tensors[0].GetTensorTypeAndShapeInfo();
std::vector<int64_t> shape = info.GetShape();
std::cout << "shape size : " << shape.size() << std::endl;
std::cout << "shape 0 : " << shape.at(0) << std::endl;
std::cout << "shape 1 : " << shape.at(1) << std::endl;
std::cout << "data 0 : " << data << std::endl;
return 0;
}
but when I check output_tensors' data, there's nothing. Actually, I even don't know I am doing correctly. How should I load an image to model? How should I set tensor shape? Or If you know simple example of ONNX object detection, please let me know. It will be very helpful for me. please help me.