Я пробовал с java / Kotlin android и затем использовал его как .jar, но не могу заставить его работать. У меня есть этот код на Java, и мне нужно попробовать скопировать его, используя C # для Xamarin / Xamarin.Android
JAVA METHOD
fun estimateSinglePose(bitmap: Bitmap): Person {
var t1: Long = SystemClock.elapsedRealtimeNanos()
val inputArray = arrayOf(initInputArray(bitmap))
var t2: Long = SystemClock.elapsedRealtimeNanos()
Log.i("posenet", String.format("Scaling to [-1,1] took %.2f ms", 1.0f *
(t2 - t1) / 1_000_000))
val outputMap = initOutputMap(interpreter!!)
t1 = SystemClock.elapsedRealtimeNanos()
interpreter!!.runForMultipleInputsOutputs(inputArray, outputMap)
t2 = SystemClock.elapsedRealtimeNanos()
Log.i("posenet", String.format("Interpreter took %.2f ms", 1.0f * (t2 - t1) / 1_000_000))
val heatmaps = outputMap[0] as Array<Array<Array<FloatArray>>>
val offsets = outputMap[1] as Array<Array<Array<FloatArray>>>
val height = heatmaps[0].size
val width = heatmaps[0][0].size
val numKeypoints = heatmaps[0][0][0].size
// Finds the (row, col) locations of where the keypoints are most likely to be.
val keypointPositions = Array(numKeypoints) { Pair(0, 0) }
for (keypoint in 0 until numKeypoints) {
var maxVal = heatmaps[0][0][0][keypoint]
var maxRow = 0
var maxCol = 0
for (row in 0 until height) {
for (col in 0 until width) {
heatmaps[0][row][col][keypoint] = sigmoid(heatmaps[0][row][col][keypoint])
if (heatmaps[0][row][col][keypoint] > maxVal) {
maxVal = heatmaps[0][row][col][keypoint]
maxRow = row
maxCol = col
}
}
}
keypointPositions[keypoint] = Pair(maxRow, maxCol)
}
// Calculating the x and y coordinates of the keypoints with offset adjustment.
val xCoords = IntArray(numKeypoints)
val yCoords = IntArray(numKeypoints)
val confidenceScores = FloatArray(numKeypoints)
keypointPositions.forEachIndexed { idx, position ->
val positionY = keypointPositions[idx].first
val positionX = keypointPositions[idx].second
yCoords[idx] = (
position.first / (height - 1).toFloat() * bitmap.height +
offsets[0][positionY][positionX][idx]
).toInt()
xCoords[idx] = (
position.second / (width - 1).toFloat() * bitmap.width +
offsets[0][positionY]
[positionX][idx + numKeypoints]
).toInt()
confidenceScores[idx] = heatmaps[0][positionY][positionX][idx]
}
val person = Person()
val keypointList = Array(numKeypoints) { KeyPoint() }
var totalScore = 0.0f
enumValues<BodyPart>().forEachIndexed { idx, it ->
keypointList[idx].bodyPart = it
keypointList[idx].position.x = xCoords[idx]
keypointList[idx].position.y = yCoords[idx]
keypointList[idx].score = confidenceScores[idx]
totalScore += confidenceScores[idx]
}
person.keyPoints = keypointList.toList()
person.score = totalScore / numKeypoints
return person
}
Я получилмодель PoseNet работает в методе C #, но этот метод написан для обнаружения объектов и не возвращает ключевые точки, я не знаю, как адаптировать его для получения ключевых точек
C # метод
public void Recognize(int[] colors)
{
if (!initialized)
{
throw new Exception("Initialize TensorflowLiteService first");
}
MessagingCenter.Instance.Send(this, nameof(AR.InputTensorMessage), new InputTensorMessage()
{
Colors = colors,
});
using (var op = new BuildinOpResolver())
{
using (var interpreter = new Interpreter(model, op))
{
InvokeInterpreter(colors, interpreter);
}
}
}
private void InvokeInterpreter(int[] colors, Interpreter interpreter)
{
if (useNumThreads)
{
interpreter.SetNumThreads(Environment.ProcessorCount);
}
var allocateTensorStatus = interpreter.AllocateTensors();
if (allocateTensorStatus == Status.Error)
{
throw new Exception("Failed to allocate tensor");
}
var input = interpreter.GetInput();
using (var inputTensor = interpreter.GetTensor(input[0]))
{
CopyColorsToTensor(inputTensor.DataPointer, colors);
var watchInvoke = Stopwatch.StartNew();
interpreter.Invoke();
watchInvoke.Stop();
Console.WriteLine($"InterpreterInvoke: {watchInvoke.ElapsedMilliseconds}ms");
}
var output = interpreter.GetOutput();
var outputIndex = output[0];
var outputTensors = new Tensor[output.Length];
for (var i = 0; i < output.Length; i++)
{
outputTensors[i] = interpreter.GetTensor(outputIndex + i);
}
var detection_boxes_out = outputTensors[0].GetData() as float[];
var detection_classes_out = outputTensors[1].GetData() as float[];
var detection_scores_out = outputTensors[2].GetData() as float[];
var num_detections_out = outputTensors[3].GetData() as float[];
var numDetections = num_detections_out[0];
LogDetectionResults(detection_classes_out, detection_scores_out, detection_boxes_out, (int)numDetections);
}