Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

是否可以考虑提供C#的P/Invoke版本 #59

Open
fengbozs opened this issue Jan 2, 2024 · 2 comments
Open

是否可以考虑提供C#的P/Invoke版本 #59

fengbozs opened this issue Jan 2, 2024 · 2 comments

Comments

@fengbozs
Copy link

fengbozs commented Jan 2, 2024

是否可以考虑提供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();
@fengbozs
Copy link
Author

fengbozs commented Jan 2, 2024

输出信息:
root@EASY-EAI-NANO:/userdata/apps/test# dotnet TestConsoleApp.dll
librknn_runtime version 1.7.3 (2e55827 build: 2022-08-25 10:45:32 base: 1131)
rknn init result:0---4978904
rknn_query_sdk_version success! result:0
drv_version:System.Char[] api_version:System.Char[]
rknn_query_in_out_num success! result:0
input_num:1 output_num:3
0Input------ images_283 RKNN_TENSOR_UINT8 RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC
0Output------ Conv_Conv_279/out0_0 RKNN_TENSOR_UINT8 RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC
1Output------ Conv_Conv_280/out0_1 RKNN_TENSOR_UINT8 RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC
2Output------ Conv_Conv_281/out0_2 RKNN_TENSOR_UINT8 RKNN_TENSOR_QNT_AFFINE_ASYMMETRIC
model is NCHW input fmt
model input height=640, width=640, channel=3
rknn_inputs_set result:0
rknn_run success!
111111111111111111
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at TestConsoleApp.Program.Main(String[] args) in D:\BRCodes\AvaloniaApplication\TestConsoleApp\Program.cs:line 174
Aborted
root@EASY-EAI-NANO:/userdata/apps/test#

@eRaul
Copy link

eRaul commented Mar 7, 2024

没有这样的计划

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants