-
Notifications
You must be signed in to change notification settings - Fork 71
Description
是否可以考虑提供C#的P/Invoke版本,我在进行P/Invoke封装时,经过rknn_outputs_get以后,outputs变成了空,也没有额外的输出,不知道怎么解决,以下是我的测试代码:
IntPtr rknn_context = IntPtr.Zero;
var modelBuffer = File.ReadAllBytes("yolov5_pre.rknn");
var result = RKNNAPI.rknn_init(ref rknn_context, modelBuffer, modelBuffer.Length, 0);
Console.WriteLine($"rknn init result:{result}---{rknn_context.ToInt64()}");
#region query
rknn_sdk_version rknn_Sdk_Version = new rknn_sdk_version()
{
api_version = new char[256],
drv_version = new char[256]
};
uint dwSize = (uint)Marshal.SizeOf(rknn_Sdk_Version);
IntPtr sdkVersionIntPtr = Marshal.AllocHGlobal((int)dwSize);
Marshal.StructureToPtr(rknn_Sdk_Version, sdkVersionIntPtr, false);
var cmd = rknn_query_cmd.RKNN_QUERY_SDK_VERSION;
result = RKNNAPI.rknn_query(rknn_context, cmd, sdkVersionIntPtr, dwSize);
if (result < 0)
{
Console.WriteLine($"rknn_query_sdk_version failed! result:{result}");
//return;
}
else
{
rknn_Sdk_Version = Marshal.PtrToStructure<rknn_sdk_version>(sdkVersionIntPtr);
Console.WriteLine($"rknn_query_sdk_version success! result:{result}");
Console.WriteLine($"drv_version:{rknn_Sdk_Version.drv_version} api_version:{rknn_Sdk_Version.api_version}");
}
Marshal.FreeHGlobal(sdkVersionIntPtr);
rknn_input_output_num io_num = new rknn_input_output_num();
dwSize = (uint)Marshal.SizeOf(io_num);
IntPtr inputOutputNumIntPtr = Marshal.AllocHGlobal((int)dwSize);
Marshal.StructureToPtr(io_num, inputOutputNumIntPtr, false);
result = RKNNAPI.rknn_query(rknn_context, rknn_query_cmd.RKNN_QUERY_IN_OUT_NUM, inputOutputNumIntPtr, dwSize);
if (result < 0)
{
Console.WriteLine($"rknn_query_in_out_num failed! result:{result}");
//return;
}
else
{
io_num = Marshal.PtrToStructure<rknn_input_output_num>(inputOutputNumIntPtr);
Console.WriteLine($"rknn_query_in_out_num success! result:{result}");
Console.WriteLine($"input_num:{io_num.n_input} output_num:{io_num.n_output}");
}
Marshal.FreeHGlobal(inputOutputNumIntPtr);
rknn_tensor_attr[] input_attrs = new rknn_tensor_attr[io_num.n_input];
for (int i = 0; i < io_num.n_input; i++)
{
input_attrs[i] = new rknn_tensor_attr()
{
index = (uint)i
};
dwSize = (uint)Marshal.SizeOf(input_attrs[i]);
IntPtr tensorAttrIntPtr = Marshal.AllocHGlobal((int)dwSize);
Marshal.StructureToPtr(input_attrs[i], tensorAttrIntPtr, false);
result = RKNNAPI.rknn_query(rknn_context, rknn_query_cmd.RKNN_QUERY_INPUT_ATTR, tensorAttrIntPtr, dwSize);
if (result < 0)
{
Console.WriteLine(i + $"Input------ rknn_query_input_attr failed! result:{result}");
}
else
{
input_attrs[i] = Marshal.PtrToStructure<rknn_tensor_attr>(tensorAttrIntPtr);
Console.WriteLine(i + $"Input------ {input_attrs[i].name} {input_attrs[i].type} {input_attrs[i].qnt_type}");
}
}
rknn_tensor_attr[] output_attrs = new rknn_tensor_attr[io_num.n_output];
for (int i = 0; i < io_num.n_output; i++)
{
output_attrs[i] = new rknn_tensor_attr()
{
index = (uint)i
};
dwSize = (uint)Marshal.SizeOf(output_attrs[i]);
IntPtr tensorAttrIntPtr = Marshal.AllocHGlobal((int)dwSize);
Marshal.StructureToPtr(output_attrs[i], tensorAttrIntPtr, false);
result = RKNNAPI.rknn_query(rknn_context, rknn_query_cmd.RKNN_QUERY_OUTPUT_ATTR, tensorAttrIntPtr, dwSize);
if (result < 0)
{
Console.WriteLine(i + $"Output------ rknn_query_output_attr failed! result:{result}");
}
else
{
output_attrs[i] = Marshal.PtrToStructure<rknn_tensor_attr>(tensorAttrIntPtr);
Console.WriteLine(i + $"Output------ {output_attrs[i].name} {output_attrs[i].type} {output_attrs[i].qnt_type}");
}
}
#endregion
int channel = 3;
int width = 640;
int height = 480;
if (input_attrs[0].fmt == rknn_tensor_format.RKNN_TENSOR_NCHW)
{
Console.WriteLine("model is NCHW input fmt");
width = (int)input_attrs[0].dims[0];
height = (int)input_attrs[0].dims[1];
}
else
{
Console.WriteLine("model is NHWC input fmt\n");
width = (int)input_attrs[0].dims[1];
height = (int)input_attrs[0].dims[2];
}
Console.WriteLine($"model input height={height}, width={width}, channel={channel}");
var files = Directory.GetFiles("Images");
foreach (var file in files)
{
rknn_input[] inputs = [new rknn_input()];
rknn_output[] outputs = new rknn_output[io_num.n_output];
for (int i = 0; i < io_num.n_output; i++)
{
outputs[i].is_prealloc = 0;
outputs[i].want_float = 0;
}
var image = SixLabors.ImageSharp.Image.Load(file);
int img_width = image.Width;
int img_height = image.Height;
if (image == null)
return;
image.Mutate(x => x.Resize(width, height));
inputs[0].index = 0;
inputs[0].type = rknn_tensor_type.RKNN_TENSOR_UINT8;
inputs[0].size = (uint)(width * height * channel);
inputs[0].fmt = rknn_tensor_format.RKNN_TENSOR_NHWC;
inputs[0].pass_through = 0;
var imageRgb24 = image.CloneAs<Rgb24>();
byte[] imageBytes = new byte[width * height * channel];
imageRgb24.CopyPixelDataTo(imageBytes);
GCHandle hObject = GCHandle.Alloc(imageBytes, GCHandleType.Pinned);
IntPtr pObject = hObject.AddrOfPinnedObject();
inputs[0].buf = pObject;
var inputResult = RKNNAPI.rknn_inputs_set(rknn_context, io_num.n_input, inputs);
Console.WriteLine($"rknn_inputs_set result:{inputResult}");
var pResult = RKNNAPI.rknn_run(rknn_context, IntPtr.Zero);
if (pResult < 0)
{
Console.WriteLine($"rknn_run failed! result:{pResult}");
}
else
{
Console.WriteLine($"rknn_run success!");
pResult = RKNNAPI.rknn_outputs_get(rknn_context, io_num.n_output, out outputs, IntPtr.Zero);
if (pResult < 0)
{
Console.WriteLine($"rknn_outputs_get failed! result:{pResult}");
}
else
{
if (outputs == null)
Console.WriteLine("111111111111111111");
Console.WriteLine($"rknn_outputs_get success!io_num.n_output:{io_num.n_output} result:{pResult} outputs.Length:{outputs.Length}");
foreach (var t in outputs)
{
Console.WriteLine($"output[{t.index}] t.buf.ToInt64():{t.buf.ToString()} size:{t.size}");
}
if (outputs.Length > 0 && outputs[0].buf != IntPtr.Zero)
{
float scale_w = (float)width / img_width;
float scale_h = (float)height / img_height;
detect_result_group_t detect_result_group = new();
List<float> out_scales = new List<float>();
List<uint> out_zps = new List<uint>();
for (int i = 0; i < io_num.n_output; ++i)
{
out_scales.Add(output_attrs[i].scale);
out_zps.Add(output_attrs[i].zp);
}
var buf0 = GetBytesFromIntPtr(outputs[0].buf, (int)outputs[0].size);
var buf1 = GetBytesFromIntPtr(outputs[1].buf, (int)outputs[1].size);
var buf2 = GetBytesFromIntPtr(outputs[2].buf, (int)outputs[2].size);
PostProcess(buf0, buf1, buf2, height, width,
0.5f, 0.6f, scale_w, scale_h, out_zps, out_scales, ref detect_result_group);
// Draw Objects
string text;
Color blue = Color.Blue;
Color white = Color.White;
for (int i = 0; i < detect_result_group.count; i++)
{
detect_result_t det_result = detect_result_group.results[i];
text = $"{det_result.name} {det_result.prop:F2}";
Console.WriteLine($"{det_result.name} @ ({det_result.box.left} {det_result.box.top} {det_result.box.right} {det_result.box.bottom}) {det_result.prop:F2}");
int x1 = det_result.box.left;
int y1 = det_result.box.top;
int x2 = det_result.box.right;
int y2 = det_result.box.bottom;
//draw box
image.Mutate(x =>
{
x.DrawPolygon(blue, 1, new PointF[] { new PointF(x1, y1), new PointF(x2, y1), new PointF(x2, y2), new PointF(x1, y2) });
x.DrawText(text, font, white, new PointF(x1, y1 - 12));
});
}
image.SaveAsJpeg($"./Images/{Guid.NewGuid()}.jpg");
var ret = RKNNAPI.rknn_outputs_release(rknn_context, io_num.n_output, outputs);
}
}
}
if (hObject.IsAllocated)
hObject.Free();