Skip to content

Commit 81aead3

Browse files
authored
Add files via upload
0 parents  commit 81aead3

File tree

8 files changed

+221
-0
lines changed

8 files changed

+221
-0
lines changed

images/DSC_0410.JPG

382 KB
Loading

images/DSC_0411.JPG

411 KB
Loading

images/a.jpg

172 KB
Loading

images/b.jpg

209 KB
Loading

images/im_A.jpg

282 KB
Loading

images/im_B.jpg

1.08 MB
Loading

main.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#define _CRT_SECURE_NO_WARNINGS
2+
#include <iostream>
3+
#include <fstream>
4+
#include <string>
5+
6+
#include <opencv2/imgproc.hpp>
7+
#include <opencv2/highgui.hpp>
8+
#include <opencv2/opencv.hpp>
9+
#include <opencv2/features2d.hpp>
10+
11+
//#include <cuda_provider_factory.h>
12+
#include <onnxruntime_cxx_api.h>
13+
14+
using namespace cv;
15+
using namespace std;
16+
using namespace Ort;
17+
18+
19+
class DeDoDeRunner_end2end
20+
{
21+
public:
22+
DeDoDeRunner_end2end(string model_path);
23+
void detect(Mat image_a, Mat image_b, vector<cv::KeyPoint>& points_A, vector<cv::KeyPoint>& points_B);
24+
private:
25+
const int inpWidth = 256;
26+
const int inpHeight = 256;
27+
const float mean_[3] = { 0.485, 0.456, 0.406 };
28+
const float std_[3] = { 0.229, 0.224, 0.225 };
29+
vector<float> input_images;
30+
void preprocess(Mat image_a, Mat image_b);
31+
32+
Env env = Env(ORT_LOGGING_LEVEL_ERROR, "cv::KeyPoints detect and match");
33+
Ort::Session* ort_session = nullptr;
34+
SessionOptions sessionOptions = SessionOptions();
35+
vector<char*> input_names;
36+
vector<char*> output_names;
37+
vector<vector<int64_t>> output_node_dims; // >=1 outputs
38+
};
39+
40+
DeDoDeRunner_end2end::DeDoDeRunner_end2end(string model_path)
41+
{
42+
std::wstring widestr = std::wstring(model_path.begin(), model_path.end());
43+
//OrtStatus* status = OrtSessionOptionsAppendExecutionProvider_CUDA(sessionOptions, 0);
44+
sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
45+
ort_session = new Session(env, widestr.c_str(), sessionOptions);
46+
size_t numInputNodes = ort_session->GetInputCount();
47+
size_t numOutputNodes = ort_session->GetOutputCount();
48+
AllocatorWithDefaultOptions allocator;
49+
for (int i = 0; i < numInputNodes; i++)
50+
{
51+
input_names.push_back(ort_session->GetInputName(i, allocator));
52+
}
53+
for (int i = 0; i < numOutputNodes; i++)
54+
{
55+
output_names.push_back(ort_session->GetOutputName(i, allocator));
56+
Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);
57+
auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
58+
auto output_dims = output_tensor_info.GetShape();
59+
output_node_dims.push_back(output_dims);
60+
}
61+
}
62+
63+
void DeDoDeRunner_end2end::preprocess(Mat image_a, Mat image_b)
64+
{
65+
Mat dstimg;
66+
cvtColor(image_a, dstimg, COLOR_BGR2RGB);
67+
Size target_size = Size(this->inpWidth, this->inpHeight);
68+
resize(dstimg, dstimg, target_size, INTER_LINEAR);
69+
this->input_images.resize(2 * target_size.area() * 3);
70+
for (int c = 0; c < 3; c++)
71+
{
72+
for (int i = 0; i < this->inpHeight; i++)
73+
{
74+
for (int j = 0; j < this->inpWidth; j++)
75+
{
76+
float pix = dstimg.ptr<uchar>(i)[j * 3 + c];
77+
this->input_images[c * target_size.area() + i * this->inpWidth + j] = (pix / 255.0 - this->mean_[c]) / this->std_[c];
78+
}
79+
}
80+
}
81+
82+
cvtColor(image_b, dstimg, COLOR_BGR2RGB);
83+
resize(dstimg, dstimg, target_size, INTER_LINEAR);
84+
for (int c = 0; c < 3; c++)
85+
{
86+
for (int i = 0; i < this->inpHeight; i++)
87+
{
88+
for (int j = 0; j < this->inpWidth; j++)
89+
{
90+
float pix = dstimg.ptr<uchar>(i)[j * 3 + c];
91+
this->input_images[(3 + c) * target_size.area() + i * this->inpWidth + j] = (pix / 255.0 - this->mean_[c]) / this->std_[c];
92+
}
93+
}
94+
}
95+
}
96+
97+
98+
void DeDoDeRunner_end2end::detect(Mat image_a, Mat image_b, vector<cv::KeyPoint>& points_A, vector<cv::KeyPoint>& points_B)
99+
{
100+
this->preprocess(image_a, image_b);
101+
array<int64_t, 4> input_shape_{ 2, 3, this->inpHeight, this->inpWidth };
102+
103+
auto allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
104+
Value input_tensor_ = Value::CreateTensor<float>(allocator_info, input_images.data(), input_images.size(), input_shape_.data(), input_shape_.size());
105+
106+
// 开始推理
107+
vector<Value> ort_outputs = ort_session->Run(RunOptions{ nullptr }, &input_names[0], &input_tensor_, 1, output_names.data(), output_names.size());
108+
109+
///Postprocessing
110+
const float* matches_A = ort_outputs[0].GetTensorMutableData<float>();
111+
const float* matches_B = ort_outputs[1].GetTensorMutableData<float>();
112+
int num_points = ort_outputs[0].GetTensorTypeAndShapeInfo().GetShape()[0];
113+
///cout << "tensor total element = " << ort_outputs[0].GetTensorTypeAndShapeInfo().GetElementCount() << endl;
114+
points_A.resize(num_points);
115+
for (int i = 0; i < num_points; i++)
116+
{
117+
points_A[i].pt.x = (matches_A[i * 2] + 1) * 0.5 * image_a.cols;
118+
points_A[i].pt.y = (matches_A[i * 2 + 1] + 1) * 0.5 * image_a.rows;
119+
points_A[i].size = 1.f;
120+
}
121+
122+
num_points = ort_outputs[1].GetTensorTypeAndShapeInfo().GetShape()[0];
123+
points_B.resize(num_points);
124+
for (int i = 0; i < num_points; i++)
125+
{
126+
points_B[i].pt.x = (matches_B[i * 2] + 1) * 0.5 * image_b.cols;
127+
points_B[i].pt.y = (matches_B[i * 2 + 1] + 1) * 0.5 * image_b.rows;
128+
points_B[i].size = 1.f;
129+
}
130+
}
131+
132+
int main()
133+
{
134+
DeDoDeRunner_end2end mynet("weights/dedode_end2end_1024.onnx");
135+
string imgpath_a = "images/im_A.jpg";
136+
string imgpath_b = "images/im_B.jpg";
137+
Mat image_a = imread(imgpath_a);
138+
Mat image_b = imread(imgpath_b);
139+
140+
vector<cv::KeyPoint> points_A;
141+
vector<cv::KeyPoint> points_B;
142+
mynet.detect(image_a, image_b, points_A, points_B);
143+
144+
//匹配结果放在matches里面
145+
const int num_points = points_A.size();
146+
vector<DMatch> matches(num_points);
147+
for (int i = 0; i < num_points; i++)
148+
{
149+
matches[i] = DMatch(i, i, 0.f);
150+
}
151+
152+
//按照匹配关系将图画出来,背景图为match_img
153+
Mat match_img;
154+
drawMatches(image_a, points_A, image_b, points_B, matches, match_img);
155+
156+
//-- Show detected matches
157+
static const string kWinName = "Image Matches in ONNXRuntime";
158+
namedWindow(kWinName, WINDOW_NORMAL);
159+
imshow(kWinName, match_img);
160+
waitKey(0);
161+
destroyAllWindows();
162+
}

main.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import numpy as np
2+
import onnxruntime as ort
3+
import cv2
4+
5+
class DeDoDeRunner_end2end:
6+
def __init__(self, end2end_path, img_size=[256, 256], fp16=False, providers=["CUDAExecutionProvider", "CPUExecutionProvider"]):
7+
self.end2end = ort.InferenceSession(end2end_path, providers=providers)
8+
self.mean_ = np.array([0.485, 0.456, 0.406], dtype=np.float32).reshape((1,1,3))
9+
self.std_ = np.array([0.229, 0.224, 0.225], dtype=np.float32).reshape((1,1,3))
10+
self.H, self.W = img_size
11+
self.fp16 = fp16
12+
13+
def preprocess(self, image_a, image_b):
14+
images = np.stack([cv2.resize(image_a, (self.W, self.H)), cv2.resize(image_b, (self.W, self.H))])
15+
images = (images / 255.0 - self.mean_) / self.std_
16+
return images.transpose(0, 3, 1, 2).astype(np.float32)
17+
18+
def detect(self, image_a, image_b):
19+
H_A, W_A = image_a.shape[:2]
20+
H_B, W_B = image_b.shape[:2]
21+
images = self.preprocess(cv2.cvtColor(image_a, cv2.COLOR_BGR2RGB), cv2.cvtColor(image_b, cv2.COLOR_BGR2RGB))
22+
if self.fp16:
23+
images = images.astype(np.float16)
24+
matches_A, matches_B, batch_ids = self.end2end.run(None, {"images": images})
25+
26+
# Postprocessing
27+
matches_A = self.postprocess(matches_A, H_A, W_A)
28+
matches_B = self.postprocess(matches_B, H_B, W_B)
29+
return matches_A, matches_B
30+
31+
def postprocess(self, matches, H, W):
32+
return (matches + 1) / 2 * [W, H]
33+
34+
def draw_matches(im_A, kpts_A, im_B, kpts_B):
35+
kpts_A = [cv2.KeyPoint(x, y, 1.0) for x, y in kpts_A]
36+
kpts_B = [cv2.KeyPoint(x, y, 1.0) for x, y in kpts_B]
37+
matches_A_to_B = [cv2.DMatch(idx, idx, 0.0) for idx in range(len(kpts_A))]
38+
im_A, im_B = np.array(im_A), np.array(im_B)
39+
ret = cv2.drawMatches(im_A, kpts_A, im_B, kpts_B, matches_A_to_B, None)
40+
return ret
41+
42+
if __name__ == "__main__":
43+
img_paths = ["images/im_A.jpg", "images/im_B.jpg"]
44+
mynet = DeDoDeRunner_end2end('weights/dedode_end2end_1024_fp16.onnx', fp16=True)
45+
46+
image_a, image_b = cv2.imread(img_paths[0]), cv2.imread(img_paths[1])
47+
matches_a, matches_b = mynet.detect(image_a, image_b)
48+
49+
# match_img = np.hstack((image_a, image_b)) ###直接把两幅输入原图拼在一起,然后在点集里从0开始连线,是不行的。因为两幅输入原图的高宽并不是完全相同的,这就使得在两幅图里检测到的点集个数也可能不相等。因此不能直接连线的,要使用DMatch建立两个点集里的点间对应关系
50+
# w = image_a.shape[1]
51+
# for i in range(matches_a.shape[0]):
52+
# cv2.line(match_img, (int(matches_a[i,0]), int(matches_a[i,1])), (int(w+matches_b[i,0]), int(w+matches_b[i,1])), (0, 255, 0), lineType=16)
53+
54+
match_img = draw_matches(image_a, matches_a, image_b, matches_b)
55+
print('image_a.shape =',image_a.shape, 'image_b.shape =',image_b.shape, 'match_img.shape =',match_img.shape)
56+
cv2.namedWindow('Image matches use onnxrunime', cv2.WINDOW_NORMAL)
57+
cv2.imshow("Image matches use onnxrunime", match_img)
58+
cv2.waitKey(0)
59+
cv2.destroyAllWindows()

0 commit comments

Comments
 (0)