51、目标的相似度检测模型Siamese部署rk3399pro、ncnn、mnn进行推理加速

article/2025/9/30 21:27:16

基本思想:需要一个判断目标相似度的模型,来比对被检测目标和既定目标的相似度,测试图片仅有的几张图片,感觉一般,量化图片尽量多点对于rknn

链接: https://pan.baidu.com/s/1NFjnCBh5RqJXDxEjl9TzHg?pwd=xev4 提取码: xev4

https://github.com/bubbliiiing/Siamese-pytorch.git

一、测试图片

/usr/bin/python3.8 /home/ubuntu/Siamese-pytorch/predict.py
Loading weights into state dict...
model_data/Omniglot_vgg.pth model loaded.
Configurations:
----------------------------------------------------------------------
|                     keys |                                   values|
----------------------------------------------------------------------
|               model_path |              model_data/Omniglot_vgg.pth|
|              input_shape |                               [105, 105]|
|          letterbox_image |                                    False|
|                     cuda |                                     True|
----------------------------------------------------------------------
Input image_1 filename:/home/ubuntu/Siamese-pytorch/img/0.jpeg
Input image_2 filename:/home/ubuntu/Siamese-pytorch/img/1.jpeg

 测试结果

转onnx模型

import matplotlib.pyplot as plt
import numpy as np
import onnxruntime
import torch
import cv2
from PIL import Image
from nets.siamese import Siamese as siamese
from torch.autograd import Variable
from onnxruntime.datasets import get_example
from PIL import Imagefrom utils.utils_aug import center_crop, resizedevice  = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
def letterbox_image(image, size, letterbox_image):w, h = sizeiw, ih = image.sizeif letterbox_image:'''resize image with unchanged aspect ratio using padding'''scale = min(w/iw, h/ih)nw = int(iw*scale)nh = int(ih*scale)image = image.resize((nw,nh), Image.BICUBIC)new_image = Image.new('RGB', size, (128,128,128))new_image.paste(image, ((w-nw)//2, (h-nh)//2))else:if h == w:new_image = resize(image, h)else:new_image = resize(image, [h ,w])new_image = center_crop(new_image, [h ,w])return new_imagedef cvtColor(image):if len(np.shape(image)) == 3 and np.shape(image)[2] == 3:return imageelse:image = image.convert('RGB')return image
def preprocess_input(x):x /= 255.0return xif __name__ == "__main__":image_1=Image.open("/home/ubuntu/Siamese-pytorch/img/0.jpeg")image_2 = Image.open("/home/ubuntu/Siamese-pytorch/img/1.jpeg")image_1_ = cvtColor(image_1)image_2_ = cvtColor(image_2)# ---------------------------------------------------##   对输入图像进行不失真的resize# ---------------------------------------------------#image_1 = letterbox_image(image_1_, [105, 105],False)image_2 = letterbox_image(image_2_, [105, 105],False)# ---------------------------------------------------------##   归一化+添加上batch_size维度# ---------------------------------------------------------#photo_1 = preprocess_input(np.array(image_1, np.float32))photo_2 = preprocess_input(np.array(image_2, np.float32))photo_1 = torch.from_numpy(np.expand_dims(np.transpose(photo_1, (2, 0, 1)), 0)).type(torch.FloatTensor).to(device)photo_2 = torch.from_numpy(np.expand_dims(np.transpose(photo_2, (2, 0, 1)), 0)).type(torch.FloatTensor).to(device)print('Loading weights into state dict...')model = siamese([105, 105])model.load_state_dict(torch.load("/home/ubuntu/Siamese-pytorch/model_data/Omniglot_vgg.pth", map_location=device))net = model.eval()net = net.cuda()dummy_input = [photo_1, photo_2]input_names = ["in1", "in2"]output_names = ["output"]torch.onnx.export(net,dummy_input,"/home/ubuntu/Siamese-pytorch/Siamese.onnx",verbose=True,input_names=input_names,output_names=output_names,keep_initializers_as_inputs=False,opset_version=12,)example_model = get_example("/home/ubuntu/Siamese-pytorch/Siamese.onnx")session = onnxruntime.InferenceSession(example_model)# get the name of the first input of the modelinput_name0 = session.get_inputs()[0].nameinput_name1 = session.get_inputs()[1].name# print('onnx Input Name:', input_name)output = session.run([], {input_name0: dummy_input[0].data.cpu().numpy(),input_name1: dummy_input[1].data.cpu().numpy()})output = torch.nn.Sigmoid()(torch.Tensor(output))#output = torch.nn.Sigmoid()(output)score=output[0].tolist()[0][0]plt.subplot(1, 2, 1)plt.imshow(np.array(image_1_))plt.subplot(1, 2, 2)plt.imshow(np.array(image_2_))plt.text(-12, -12, 'Similarity:%.3f' %score, ha='center', va='bottom', fontsize=11)plt.show()

测试结果

二、转ncnn模型

ubuntu@ubuntu:~/ncnn/build/install/bin$ ./onnx2ncnn /home/ubuntu/Siamese-pytorch/Siamese.onnx /home/ubuntu/Siamese-pytorch/Siamese.param /home/ubuntu/Siamese-pytorch/Siamese.bin

camkelists.txt

cmake_minimum_required(VERSION 3.16)
project(siamsese)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
set(CMAKE_CXX_STANDARD 11)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/include/ncnn)
include_directories(${CMAKE_SOURCE_DIR})
find_package(OpenCV  REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
#导入ncnn
add_library(libncnn STATIC IMPORTED)
set_target_properties(libncnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib/libncnn.a)add_executable(siamsese main.cpp)target_link_libraries(siamsese ${OpenCV_LIBS} libncnn)

main.cpp

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include "net.h"
void crop_img(cv::Mat img, cv::Mat &crop_img, int x,int y,int w,int h) {int crop_x1 = std::max(0, x);int crop_y1 = std::max(0, y);int crop_x2 = crop_x1+std::min(img.cols , x + w );int crop_y2 = crop_y1+std::min(img.rows , y+ h );crop_img = img.clone()(cv::Range(crop_x1, crop_x2),cv::Range(crop_y1, crop_y2));
}void letterbox_image(cv::Mat image, cv::Mat &image_dst_1, int size) {float w = image.cols;float h = image.rows;int oh=0;int ow=0;if(w<=h&&w==size || h<=w&& h==size){image_dst_1=image;return;}else if(w<h){ow=size;oh=int(size*h/w);} else {oh=size;ow=int(size*w/h);}cv::Mat temp;cv::resize(image, temp, cv::Size(ow, oh), 0, 0, cv::INTER_LINEAR);w=temp.rows;h=temp.cols;int th=size;int tw=size;int i = int(round((h - th) / 2.));int j = int(round((w - tw) / 2.));//crop_img(temp,image_dst_1,i,j,th,tw);crop_img(temp,image_dst_1,j,i,tw,th);}void pretty_print(const ncnn::Mat& m)
{for (int q=0; q<m.c; q++){const float* ptr = m.channel(q);for (int z=0; z<m.d; z++){for (int y=0; y<m.h; y++){for (int x=0; x<m.w; x++){printf("%f ", ptr[x]);}ptr += m.w;printf("\n");}printf("\n");}printf("------------------------\n");}
}
static inline float sigmoid(float x)
{return static_cast<float>(1.f / (1.f + exp(-x)));
}int main() {cv::Mat image_1 = cv::imread("/home/ubuntu/Siamese-pytorch/img/Angelic_01.png");cv::Mat image_2 = cv::imread("/home/ubuntu/Siamese-pytorch/img/Angelic_02.png");int image_1_w = image_1.cols;int image_1_h = image_1.rows;int image_2_w = image_2.cols;int image_2_h = image_2.rows;int target_size = 105;cv::Mat image_dst_1, image_dst_2;letterbox_image(image_1, image_dst_1, target_size);letterbox_image(image_2, image_dst_2, target_size);cv::imwrite("a.jpg",image_dst_1);cv::imwrite("b.jpg",image_dst_2);// subtract 128, norm to -1 ~ 1ncnn::Mat in_1 = ncnn::Mat::from_pixels(image_dst_1.data, ncnn::Mat::PIXEL_BGR2RGB, image_dst_1.cols,image_dst_1.rows);ncnn::Mat in_2 = ncnn::Mat::from_pixels(image_dst_2.data, ncnn::Mat::PIXEL_BGR2RGB, image_dst_2.cols,image_dst_2.rows);float mean[3] = {0, 0, 0};float norm[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f};in_1.substract_mean_normalize(mean, norm);in_2.substract_mean_normalize(mean, norm);//pretty_print(in_1);ncnn::Net net;net.load_param("/home/ubuntu/Siamese-pytorch/Siamese.param");net.load_model("/home/ubuntu/Siamese-pytorch/Siamese.bin");ncnn::Extractor ex = net.create_extractor();ex.set_light_mode(true);ex.set_num_threads(4);ex.input("in1", in_1);ex.input("in2", in_2);ncnn::Mat out;ex.extract("output", out);out = out.reshape(out.h * out.w * out.c);fprintf(stderr, "output shape: %d %d %d %d\n", out.dims, out.h, out.w, out.c);printf("cls_scores=%f\n",out[0]);float score=sigmoid(out[0]);printf("cls_scores=%f\n",score);return 0;
}

测试结果

/home/ubuntu/demo/cmake-build-debug/siamsese
cls_scores=4.522670
cls_scores=0.989257
output shape: 1 1 1 1Process finished with exit code 0

三、转mnn模型

ubuntu@ubuntu:~/MNN/build$ ./MNNConvert -f ONNX --modelFile /home/ubuntu/Siamese-pytorch/Siamese.onnx --MNNModel /home/ubuntu/Siamese-pytorch/Siamese.mnn --bizCode MNN
Start to Convert Other Model Format To MNN Model...
[14:37:19] /home/ubuntu/MNN/tools/converter/source/onnx/onnxConverter.cpp:40: ONNX Model ir version: 6
Start to Optimize the MNN Net...
The Convolution use shared weight, may increase the model size
inputTensors : [ in1, in2, ]
outputTensors: [ output, ]
Converted Success!

cmakelist.txt

cmake_minimum_required(VERSION 3.10)
project(untiled2)set(CMAKE_CXX_STANDARD 11)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/include/MNN)
find_package(OpenCV REQUIRED)
add_library(libmnn SHARED IMPORTED)
set_target_properties(libmnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib/libMNN.so)add_executable(untiled2 main.cpp )target_link_libraries(untiled2 ${OpenCV_LIBS} libmnn)

测试代码


#include <iostream>
#include <algorithm>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include<MNN/Interpreter.hpp>
#include<MNN/ImageProcess.hpp>
using namespace std;
using namespace cv;void crop_img(cv::Mat img, cv::Mat &crop_img, int x,int y,int w,int h) {int crop_x1 = std::max(0, x);int crop_y1 = std::max(0, y);int crop_x2 = crop_x1+std::min(img.cols , x + w );int crop_y2 = crop_y1+std::min(img.rows , y+ h );crop_img = img.clone()(cv::Range(crop_x1, crop_x2),cv::Range(crop_y1, crop_y2));
}void letterbox_image(cv::Mat image, cv::Mat &image_dst_1, int size) {float w = image.cols;float h = image.rows;int oh=0;int ow=0;if(w<=h&&w==size || h<=w&& h==size){image_dst_1=image;return;}else if(w<h){ow=size;oh=int(size*h/w);} else {oh=size;ow=int(size*w/h);}cv::Mat temp;cv::resize(image, temp, cv::Size(ow, oh), 0, 0, cv::INTER_LINEAR);w=temp.rows;h=temp.cols;int th=size;int tw=size;int i = int(round((h - th) / 2.));int j = int(round((w - tw) / 2.));//crop_img(temp,image_dst_1,i,j,th,tw);crop_img(temp,image_dst_1,j,i,tw,th);}inline float sigmoid(float x)
{return static_cast<float>(1.f / (1.f + exp(-x)));
}int main(int argc, char **argv) {cv::Mat image_1 = cv::imread("/home/ubuntu/Siamese-pytorch/img/Angelic_01.png");cv::Mat image_2 = cv::imread("/home/ubuntu/Siamese-pytorch/img/Angelic_02.png");int target_size = 105;cv::Mat image_dst_1, image_dst_2;letterbox_image(image_1, image_dst_1, target_size);letterbox_image(image_2, image_dst_2, target_size);// MNN inferenceauto mnnNet = std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile("/home/ubuntu/Siamese-pytorch/Siamese.mnn"));auto t1 = std::chrono::steady_clock::now();MNN::ScheduleConfig netConfig;netConfig.type = MNN_FORWARD_CPU;netConfig.numThread = 4;auto session = mnnNet->createSession(netConfig);auto input_1 = mnnNet->getSessionInput(session, "in1");auto input_2 = mnnNet->getSessionInput(session, "in2");mnnNet->resizeTensor(input_1, {1, 3, (int) target_size, (int) target_size});mnnNet->resizeTensor(input_2, {1, 3, (int) target_size, (int) target_size});mnnNet->resizeSession(session);MNN::CV::ImageProcess::Config config;const float mean_vals[3] = {0.f,0.f,0.f};const float norm_255[3] = {1.f / 255, 1.f / 255, 1.f / 255};std::shared_ptr<MNN::CV::ImageProcess> pretreat(MNN::CV::ImageProcess::create(MNN::CV::BGR, MNN::CV::RGB, mean_vals, 3,norm_255, 3));pretreat->convert(image_1.data, (int) target_size, (int) target_size, image_1.step[0], input_1);pretreat->convert(image_2.data, (int) target_size, (int) target_size, image_2.step[0], input_2);mnnNet->runSession(session);auto SparseInst_scores = mnnNet->getSessionOutput(session, "output");MNN::Tensor scoresHost(SparseInst_scores, SparseInst_scores->getDimensionType());SparseInst_scores->copyToHostTensor(&scoresHost);float value = scoresHost.host<float>()[0];std::cout<<value<<std::endl;float score=sigmoid(value);std::cout<<score<<std::endl;mnnNet->releaseModel();mnnNet->releaseSession(session);return 0;
}

四、转rknn模型

from rknn.api import RKNNONNX_MODEL = '/home/ubuntu/Siamese-pytorch/Siamese.onnx'
RKNN_MODEL = '/home/ubuntu/Siamese-pytorch/Siamese.rknn'if __name__ == '__main__':# Create RKNN objectrknn = RKNN(verbose=True)# pre-process configprint('--> config model')rknn.config(mean_values=[[0, 0, 0],[0, 0, 0]], std_values=[[255, 255, 255],[255, 255, 255]],reorder_channel='0 1 2#0 1 2',target_platform=['rk1808', 'rk3399pro'],quantized_dtype='asymmetric_affine-u8',batch_size=1, optimization_level=3, output_optimize=1)print('done')print('--> Loading model')ret = rknn.load_onnx(model=ONNX_MODEL)if ret != 0:print('Load model  failed!')exit(ret)print('done')# Build modelprint('--> Building model')ret = rknn.build(do_quantization=True, dataset='dataset.txt')  # ,pre_compile=Trueif ret != 0:print('Build Siamese failed!')exit(ret)print('done')# Export rknn modelprint('--> Export RKNN model')ret = rknn.export_rknn(RKNN_MODEL)if ret != 0:print('Export Siamese.rknn failed!')exit(ret)print('done')rknn.release()

dataset.txt这样写,多多益善

Angelic_01.png Angelic_02.png
img.png img.png
0.jpeg 1.jpeg
Atem_01.png Atl_01.png
00.jpeg 11.png

cmakelists.txt

cmake_minimum_required(VERSION 3.16)
project(untitled10)
set(CMAKE_CXX_FLAGS "-std=c++11")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/include)
find_package(OpenCV REQUIRED)
#message(STATUS ${OpenCV_INCLUDE_DIRS})
#添加头文件
include_directories(${OpenCV_INCLUDE_DIRS})
#链接Opencv库
add_library(librknn_api SHARED IMPORTED)
set_target_properties(librknn_api PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib64/librknn_api.so)add_executable(untitled10 main.cpp)
target_link_libraries(untitled10 ${OpenCV_LIBS} librknn_api )

源码

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <queue>
#include "rknn_api.h"
void crop_img(cv::Mat img, cv::Mat &crop_img, int x,int y,int w,int h) {int crop_x1 = std::max(0, x);int crop_y1 = std::max(0, y);int crop_x2 = crop_x1+std::min(img.cols , x + w );int crop_y2 = crop_y1+std::min(img.rows , y+ h );crop_img = img.clone()(cv::Range(crop_x1, crop_x2),cv::Range(crop_y1, crop_y2));
}void letterbox_image(cv::Mat image, cv::Mat &image_dst_1, int size) {float w = image.cols;float h = image.rows;int oh=0;int ow=0;if(w<=h&&w==size || h<=w&& h==size){image_dst_1=image;return;}else if(w<h){ow=size;oh=int(size*h/w);} else {oh=size;ow=int(size*w/h);}cv::Mat temp;cv::resize(image, temp, cv::Size(ow, oh), 0, 0, cv::INTER_LINEAR);w=temp.rows;h=temp.cols;int th=size;int tw=size;int i = int(round((h - th) / 2.));int j = int(round((w - tw) / 2.));//crop_img(temp,image_dst_1,i,j,th,tw);crop_img(temp,image_dst_1,j,i,tw,th);}
void printRKNNTensor(rknn_tensor_attr *attr) {printf("index=%d name=%s n_dims=%d dims=[%d %d %d %d] n_elems=%d size=%d ""fmt=%d type=%d qnt_type=%d fl=%d zp=%d scale=%f\n",attr->index, attr->name, attr->n_dims, attr->dims[3], attr->dims[2],attr->dims[1], attr->dims[0], attr->n_elems, attr->size, 0, attr->type,attr->qnt_type, attr->fl, attr->zp, attr->scale);
}static inline float sigmoid(float x)
{return static_cast<float>(1.f / (1.f + exp(-x)));
}int main() {cv::Mat image_1 = cv::imread("../Angelic_01.jpeg");cv::Mat image_2 = cv::imread("../Angelic_02.jpeg");int target_size = 105;cv::Mat image_dst_1, image_dst_2;letterbox_image(image_1, image_dst_1, target_size);letterbox_image(image_2, image_dst_2, target_size);const char *model_path = "../Siamese.rknn";// Load modelFILE *fp = fopen(model_path, "rb");if (fp == NULL) {printf("fopen %s fail!\n", model_path);return -1;}fseek(fp, 0, SEEK_END);int model_len = ftell(fp);void *model = malloc(model_len);fseek(fp, 0, SEEK_SET);if (model_len != fread(model, 1, model_len, fp)) {printf("fread %s fail!\n", model_path);free(model);return -1;}rknn_context ctx = 0;int ret = rknn_init(&ctx, model, model_len, 0);if (ret < 0) {printf("rknn_init fail! ret=%d\n", ret);return -1;}/* Query sdk version */rknn_sdk_version version;ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version,sizeof(rknn_sdk_version));if (ret < 0) {printf("rknn_init error ret=%d\n", ret);return -1;}printf("sdk version: %s driver version: %s\n", version.api_version,version.drv_version);/* Get input,output attr */rknn_input_output_num io_num;ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));if (ret < 0) {printf("rknn_init error ret=%d\n", ret);return -1;}printf("model input num: %d, output num: %d\n", io_num.n_input,io_num.n_output);rknn_tensor_attr input_attrs[io_num.n_input];memset(input_attrs, 0, sizeof(input_attrs));for (int i = 0; i < io_num.n_input; i++) {input_attrs[i].index = i;ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]),sizeof(rknn_tensor_attr));if (ret < 0) {printf("rknn_init error ret=%d\n", ret);return -1;}printRKNNTensor(&(input_attrs[i]));}rknn_tensor_attr output_attrs[io_num.n_output];memset(output_attrs, 0, sizeof(output_attrs));for (int i = 0; i < io_num.n_output; i++) {output_attrs[i].index = i;ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]),sizeof(rknn_tensor_attr));printRKNNTensor(&(output_attrs[i]));}int input_channel = 3;int input_width = 0;int input_height = 0;if (input_attrs[0].fmt == RKNN_TENSOR_NCHW) {printf("model is NCHW input fmt\n");input_width = input_attrs[0].dims[0];input_height = input_attrs[0].dims[1];printf("input_width=%d input_height=%d\n", input_width, input_height);} else {printf("model is NHWC input fmt\n");input_width = input_attrs[0].dims[1];input_height = input_attrs[0].dims[2];printf("input_width=%d input_height=%d\n", input_width, input_height);}printf("model input height=%d, width=%d, channel=%d\n", input_height, input_width,input_channel);/* Init input tensor */rknn_input inputs[2]={0};inputs[0].index = 0;inputs[0].buf = image_dst_1.data;inputs[0].type = RKNN_TENSOR_UINT8;inputs[0].size = input_width * input_height * input_channel;inputs[0].fmt = RKNN_TENSOR_NCHW;inputs[0].pass_through = 0;inputs[1].index = 1;inputs[1].buf = image_dst_2.data;inputs[1].type = RKNN_TENSOR_UINT8;inputs[1].size = input_width * input_height * input_channel;inputs[1].fmt = RKNN_TENSOR_NCHW;inputs[1].pass_through = 0;/* Init output tensor */rknn_output outputs[io_num.n_output];memset(outputs, 0, sizeof(outputs));for (int i = 0; i < io_num.n_output; i++) {outputs[i].want_float = 1;}printf("img.cols: %d, img.rows: %d\n", image_dst_1.cols, image_dst_1.rows);auto t1 = std::chrono::steady_clock::now();rknn_inputs_set(ctx, io_num.n_input, inputs);ret = rknn_run(ctx, NULL);if (ret < 0) {printf("ctx error ret=%d\n", ret);return -1;}ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);if (ret < 0) {printf("outputs error ret=%d\n", ret);return -1;}int shape_b = 0;int shape_c = 0;int shape_w = 0;;int shape_h = 0;;for (int i = 0; i < io_num.n_output; ++i) {shape_b = output_attrs[i].dims[3];shape_c = output_attrs[i].dims[2];shape_h = output_attrs[i].dims[1];;shape_w = output_attrs[i].dims[0];;}printf("batch=%d channel=%d width=%d height= %d\n", shape_b, shape_c, shape_w, shape_h);float *output = (float *) outputs[0].buf;printf("cls_scores=%f\n",output[0]);float score=sigmoid(output[0]);printf("cls_scores=%f\n",score);return 0;
}

测试结果

/tmp/tmp.E4ciUSTTsf/cmake-build-debug/untitled10
D RKNNAPI: ==============================================
D RKNNAPI: RKNN VERSION:
D RKNNAPI:   API: 1.6.1 (00c4d8b build: 2021-03-15 16:31:37)
D RKNNAPI:   DRV: 1.7.1 (0cfd4a1 build: 2021-12-10 09:43:11)
D RKNNAPI: ==============================================
sdk version: 1.6.1 (00c4d8b build: 2021-03-15 16:31:37) driver version: 1.7.1 (0cfd4a1 build: 2021-12-10 09:43:11)
model input num: 2, output num: 1
index=0 name=in1_69 n_dims=4 dims=[1 3 105 105] n_elems=33075 size=33075 fmt=0 type=3 qnt_type=2 fl=0 zp=0 scale=0.003922
index=1 name=in2_70 n_dims=4 dims=[1 3 105 105] n_elems=33075 size=33075 fmt=0 type=3 qnt_type=2 fl=0 zp=0 scale=0.003922
index=0 name=Gemm_Gemm_67/out0_0 n_dims=2 dims=[0 0 1 1] n_elems=1 size=1 fmt=0 type=3 qnt_type=2 fl=0 zp=0 scale=0.043770
model is NCHW input fmt
input_width=105 input_height=105
model input height=105, width=105, channel=3
img.cols: 105, img.rows: 105
batch=0 channel=0 width=1 height= 1
cls_scores=11.161281
cls_scores=0.999986Process finished with exit code 0

  剩下的根据自己的场景简单训练了


http://chatgpt.dhexx.cn/article/hcXIDkVW.shtml

相关文章

SPCL:Siamese Prototypical Contrastive Learning

论文链接&#xff1a;https://arxiv.org/abs/2208.08819 BMVC 2021 abstract CSL(Contrastive Self-supervised Learning)的一个缺点是&#xff0c;对比损失函数需要大量的负样本&#xff0c;以提供更好的理想互信息边界。 通过变大batch size来增加负样本数理&#xff0c;同…

Exploring Simple Siamese Representation Learning论文笔记

写在前面 大三狗随手记录&#xff0c;不喜勿喷。 主要思想 Siamese network常常被用来计算图像的两个增强之间的相似性&#xff0c;但可能会造成模型坍塌&#xff08;即输出恒定&#xff09;。作者在本文提出了一个非常简单的Simple Siamese network&#xff0c;简称Simsiam…

SiamCAR:Siamese Fully Convolutional Classification and Regression for Visual Tracking

文章目录 AbstractIntroductionProposed MethodFeature ExtractionBounding Box PredictionThe Tracking Phase 值得关注的几个问题Q1:输入的图片大小不一&#xff1f;Q2:在两者做相关性之前&#xff0c;如何得到特征图&#xff1f;Q3:两者的相关性计算是如何实现的&#xff1f…

TensorFlow搭建VGG-Siamese网络

TensorFlow搭建VGG-Siamese网络 Siamese原理 Siamese网络&#xff0c;中文称为孪生网络。大致结构如下图所示&#xff1a; Siamese网络有两个输入&#xff0c;一个输出。其中&#xff0c;两个输入经过相同的网络层知道成为一个n维向量&#xff0c;再对这个n维向量进行求距离&…

mesa 概述

技术关键词&#xff1a;mesa、OpenGL、dri、gpu、kmd、xsever 目录 一、mesa概述 二、mesa架构 1. 架构设计 2. 模块划分 三、mesa与linux图形系统中的其他模块的关系 四、mesa的编译 五、链接资源 总结 一、mesa概述 mesa是OpenGL、OpenGL ES、Vulkan、OpenCL的一个开…

Siamese 网络(Siamese network)

来源&#xff1a;Coursera吴恩达深度学习课程 上个文章One-Shot学习/一次学习&#xff08;One-shot learning&#xff09;中函数d的作用就是输入两张人脸图片&#xff0c;然后输出相似度。实现这个功能的一个方式就是用Siamese网络。 上图是常见的卷积网络&#xff0c;输入图片…

MISF:Multi-level Interactive Siamese Filtering for High-Fidelity Image Inpainting 论文解读与感想

深度学习模型被广泛应用于各种视觉任务的同时&#xff0c;似乎传统的图像处理方式已经被人们渐渐遗忘&#xff0c;然而很多时候传统图像处理方式的稳定性和可解释性依然是深度学习模型所不能达到的。本文是CVPR2022的一篇将传统与深度相结合进行inpainting的文章。 在图像inpa…

Siamese系列文章

说明 在学习目标追踪方面&#xff0c;慢慢读懂论文&#xff0c;记录论文的笔记&#xff0c;同时贴上一些别人写的非常优秀的帖子。 文章目录 说明综述类型笔记SiamFC笔记 SiamRPN笔记 DaSiamRPN笔记 SiamRPN笔记复现 SiamDW笔记 SiamFC笔记 UpdateNet笔记 SiamBAN笔记 SiamMa…

SiamRPN阅读笔记:High Performance Visual Tracking with Siamese Region Proposal Network

这是来自商汤的一篇文章 发表在CVPR2018上 论文地址 目录&#xff1a; 文章目录 摘要1.引言2.相关工作2.2 RPN2.3 One-shot learning 3.Siamese-RPN framework3.1 孪生特征提取子网络3.2 候选区域提取子网络3.3 训练阶段&#xff1a;端到端训练孪生RPN 4. Tracking as one-sho…

【度量学习】Siamese Network

基于2-channel network的图片相似度判别 一、相关理论 本篇博文主要讲解2015年CVPR的一篇关于图像相似度计算的文章&#xff1a;《Learning to Compare Image Patches via Convolutional Neural Networks》&#xff0c;本篇文章对经典的算法Siamese Networks 做了改进。学习这…

【论文阅读】Learning to Rank Proposals for Siamese Visual Tracking

Learning to Rank Proposals for Siamese Visual Tracking&#xff1a;2021 TIP 引入 There are two main challenges for visual tracking&#xff1a; 首先&#xff0c;待跟踪目标具有类不可知性和任意性&#xff0c;关于目标的先验信息很少。 其次&#xff0c;仅仅向跟踪器…

深度学习笔记-----多输入网络 (Siamese网络,Triplet网络)

目录 1&#xff0c;什么时候需要多个输入 2&#xff0c;常见的多输入网络 2.1 Siamese网络(孪生网络) 2.1 Triplet网络 1&#xff0c;什么时候需要多个输入 深度学习网络一般是输入都是一个&#xff0c;或者是一段视频切片&#xff0c;因为大部分的内容是对一张图像或者一段…

Siamese networks

Siamese Network 是一种神经网络的架构&#xff0c;而不是具体的某种网络&#xff0c;就像Seq2Seq一样&#xff0c;具体实现上可以使用RNN也可以使用CNN。Siamese Network 就像“连体的神经网络”&#xff0c;神经网络的“连体”是通过共享权值来实现的&#xff08;共享权值即左…

Siamese Network理解(附代码)

author:DivinerShi 文章地址&#xff1a;http://blog.csdn.net/sxf1061926959/article/details/54836696 提起siamese network一般都会引用这两篇文章&#xff1a; 《Learning a similarity metric discriminatively, with application to face verification》和《 Hamming D…

详解Siamese网络

摘要 Siamese网络用途&#xff0c;原理&#xff0c;如何训练&#xff1f; 背景 在人脸识别中&#xff0c;存在所谓的one-shot问题。举例来说&#xff0c;就是对公司员工进行人脸识别&#xff0c;每个员工只给你一张照片&#xff08;训练集样本少&#xff09;&#xff0c;并且…

Siamese网络(孪生网络)

1. Why Siamese 在人脸识别中&#xff0c;存在所谓的one-shot问题。举例来说&#xff0c;就是对公司员工进行人脸识别&#xff0c;每个员工只有一张照片&#xff08;因为每个类别训练样本少&#xff09;&#xff0c;并且员工会离职、入职&#xff08;每次变动都要重新训练模型…

Siamese网络(孪生神经网络)详解

SiameseFC Siamese网络&#xff08;孪生神经网络&#xff09;本文参考文章&#xff1a;Siamese背景 Siamese网络解决的问题要解决什么问题&#xff1f;用了什么方法解决&#xff1f;应用的场景&#xff1a; Siamese的创新Siamese的理论Siamese的损失函数——Contrastive Loss损…

8.HttpEntity,ResponseEntity

RequestBody请求体&#xff0c;获取一个请求的请求体内容就不用RequestParam RequestMapping("/testRequestBody")public String testRequestBody(RequestBody String body){System.out.println("请求体: "body);return "success";}只有表单才有…

使用restTemplate进行feign调用new HttpEntity<>报错解决方案

使用restTemplate进行feign调用new HttpEntity<>报错解决方案 问题背景HttpEntity<>标红解决方案心得Lyric&#xff1a; 沙漠之中怎么会有泥鳅 问题背景 今天才知道restTemplate可以直接调用feign&#xff0c;高级用法呀&#xff0c;但使用restTemplate进行feign调…

HttpClient 源码详解之HttpEntity

HttpClient 源码详解 之HttpEntity 1. 类释义 An entity that can be sent or received with an HTTP message. Entities can be found in some requests and in responses, where they are optional. There are three distinct types of entities in HttpCore, depending on …