how can i do in c#
choigawoon opened this issue · 1 comments
choigawoon commented
i want to migrate the below python code into c# numsharp or numpy.net.
but i cannot find any example using double braces "[[ ]]"
joint = np.zeros((21, 3))
for j, lm in enumerate(res.landmark):
joint[j] = [lm.x, lm.y, lm.z]
# Compute angles between joints
v1 = joint[[0,1,2,3,0,5,6,7,0,9,10,11,0,13,14,15,0,17,18,19],:] # Parent joint
v2 = joint[[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],:] # Child joint
v = v2 - v1 # [20,3]
# Normalize v
v = v / np.linalg.norm(v, axis=1)[:, np.newaxis]
# Get angle using arcos of dot product
angle = np.arccos(np.einsum('nt,nt->n',
v[[0,1,2,4,5,6,8,9,10,12,13,14,16,17,18],:],
v[[1,2,3,5,6,7,9,10,11,13,14,15,17,18,19],:])) # [15,]
angle = np.degrees(angle) # Convert radian to degree
# Inference gesture,
data = np.array([angle], dtype=np.float32)
here's what i tried. i got the error at the line, var v = np.subtract(v2, v1);
said cannot cast from NDArray[] to NDArray
public static float Predict(NormalizedLandmarkList jointList)
{
//joint = np.zeros((21, 3))
var joint = np.zeros((21, 3));
try
{
//for j, lm in enumerate(res.landmark):
// joint[j] = [lm.x, lm.y, lm.z]
for (var j = 0; j < 21; ++j)
{
joint[j] = new float[] { jointList.Landmark[j].X, jointList.Landmark[j].Y, jointList.Landmark[j].Z };
}
//# Compute angles between joints
//v1 = joint[[0, 1, 2, 3, 0, 5, 6, 7, 0, 9, 10, 11, 0, 13, 14, 15, 0, 17, 18, 19],:] # Parent joint
//v2 = joint[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],:] # Child joint
//v = v2 - v1 # [20,3]
//# Normalize v
//v = v / np.linalg.norm(v, axis = 1)[:, np.newaxis]
var v1 = parentJointIndex.Select(index => joint[index]).ToArray();
var v2 = childJointIndex.Select(index => joint[index]).ToArray();
var v = np.subtract(v2, v1);
v = v / np.linalg.norm(v, axis: 1);
var input1 = v1Index.Select(index => v[index]).ToArray();
var input2 = v2Index.Select(index => v[index]).ToArray();
//# Get angle using arcos of dot product
//angle = np.arccos(np.einsum('nt,nt->n',
// v[[0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18],:],
// v[[1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19],:])) # [15,]
var angle = np.arccos(np.einsum("nt,nt->n",
input1,
input2));
//angle = np.degrees(angle) # Convert radian to degree
angle = np.degrees(angle);
NLogModuleWrapper.mediaPipeLogger.Info($"knn, angle({JsonConvert.SerializeObject(angle.GetData<float>(), Formatting.Indented)})");
//# Inference gesture
//data = np.array([angle], dtype = np.float32)
var rawdata = np.array(angle, np.float32);
var matcols = rawdata.len;
// row 1줄을 입력할 예정이고, float32타입
using var mat = new Mat(1, matcols, CvType.CV_32FC1);
NLogModuleWrapper.mediaPipeLogger.Info($"knn, {mat}");
// Mat대입 예제
// https://github.com/EnoxSoftware/OpenCVForUnity/blob/87bcf43f949cbb84e313527ac90baa04d4f655ee/Assets/OpenCVForUnity/Examples/MainModules/ml/SVMExample/SVMExample.cs#L29
// 예제에서 5f라고 label붙은 데이터 가져옴
var putret = mat.put(0, 0, rawdata.GetData<float>());
NLogModuleWrapper.mediaPipeLogger.Info($"knn, mat.put({putret}), {mat}");
var resultMat = new Mat();
var findresult = knn.findNearest(samples: mat, k: 3, results: resultMat);
NLogModuleWrapper.mediaPipeLogger.Info($"knn, findNearest({findresult}), result:{resultMat}, {resultMat.get(0, 0)}");
switch (findresult)
{
case 1f:
NLogModuleWrapper.mediaPipeLogger.Info($"knn, rock");
break;
case 5f:
NLogModuleWrapper.mediaPipeLogger.Info($"knn, paper");
break;
case 9f:
NLogModuleWrapper.mediaPipeLogger.Info($"knn, scissors");
break;
default:
NLogModuleWrapper.mediaPipeLogger.Info($"knn, Unknown");
break;
}
return findresult;
}
catch (Exception ex)
{
NLogModuleWrapper.mediaPipeLogger.Error($"knn, {ex.Message}, {ex.StackTrace}");
NLogModuleWrapper.mediaPipeLogger.Error(ex.StackTrace);
return -1f;
}
}
choigawoon commented
close issue and move to numpy.net