SciSharp / NumSharp

High Performance Computation for N-D Tensors in .NET, similar API to NumPy.
https://github.com/SciSharp
Apache License 2.0
1.37k stars 192 forks source link

how can i do in c# #469

Closed choigawoon closed 2 years ago

choigawoon commented 2 years ago

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 2 years ago

close issue and move to numpy.net