Integre el servicio de reconocimiento de puntos clave de mano de Huawei para reconocer fácilmente las letras del lenguaje de señas

Introducción

Huawei Machine Learning (ML Kit) proporciona servicios de reconocimiento de puntos clave de mano, que se pueden utilizar para el reconocimiento de lenguaje de señas. El servicio de reconocimiento de puntos clave de la mano puede identificar 21 puntos clave de la mano y encontrar el alfabeto del lenguaje de señas comparando la dirección de cada dedo con las reglas del lenguaje de señas.

Escenario de aplicación

El lenguaje de señas es utilizado generalmente por personas con discapacidades auditivas y del habla, es una colección de gestos que incluye movimientos y gestos usados ​​en interacciones diarias.

Use ML Kit para crear un reconocedor inteligente del alfabeto del lenguaje de señas, que puede traducir gestos en palabras u oraciones como un ayudante, o traducir palabras u oraciones en gestos.

Lo que probé aquí es el alfabeto del lenguaje de señas estadounidense en gestos, que se clasifican en función de las posiciones de las articulaciones, los dedos y las muñecas. A continuación, el editor intentará recopilar la palabra "HOLA" de los gestos.

Inserte la descripción de la imagen aquí

Pasos de desarrollo

1. Preparar

Para conocer los pasos de preparación detallados, consulte Huawei Developer Alliance:

https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/ml-process-4

Estos son los pasos de desarrollo clave.

1.1 Iniciar el kit de AA

En Huawei Developer AppGallery Connect, seleccione Desarrollar> Administrar API . Asegúrate de que ML Kit esté activado.

1.2 Configurar la dirección del almacén de Maven en gradle a nivel de proyecto
buildscript {
 repositories {
 ...
 maven {url 'https://developer.huawei.com/repo/'}
 }
 }
 dependencies {
 ...
 classpath 'com.huawei.agconnect:agcp:1.3.1.301'
 }
 allprojects {
 repositories {
 ...
 maven {url 'https://developer.huawei.com/repo/'}
 }
 }
1.3 Después de integrar el SDK, agregue la configuración al encabezado del archivo.
apply plugin: 'com.android.application'      
 apply plugin: 'com.huawei.agconnect' 

 dependencies{
  //   Import the base SDK.
      implementation   'com.huawei.hms:ml-computer-vision-handkeypoint:2.0.2.300'
  //   Import the hand keypoint detection model package.
      implementation   'com.huawei.hms:ml-computer-vision-handkeypoint-model:2.0.2.300'
  }
1.4 Agregue la siguiente declaración al archivo AndroidManifest.xml
<meta-data    
            android:name="com.huawei.hms.ml.DEPENDENCY"    
            android:value= "handkeypoint"/>
1.5 Solicite el permiso de la cámara y el permiso de lectura de archivos locales
<!--Camera permission-->
 <uses-permission android:name="android.permission.CAMERA" />
 <!--Read permission-->
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. Desarrollo de código

2.1 Cree una vista de superficie para la vista previa de la cámara y cree una vista de superficie para obtener resultados.

Actualmente solo mostramos los resultados en la interfaz de usuario, también puede usar TTS para identificar extensiones y leer los resultados.

mSurfaceHolderCamera.addCallback(surfaceHolderCallback) 
    private val surfaceHolderCallback = object : SurfaceHolder.Callback {    
      override fun surfaceCreated(holder: SurfaceHolder) {    
          createAnalyzer()    
      }    
      override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {    
          prepareLensEngine(width, height)    
          mLensEngine.run(holder)    
      }    
      override fun surfaceDestroyed(holder: SurfaceHolder) {    
          mLensEngine.release()    
      }    
  }
2.2 Crear un analizador de puntos clave de mano
//Creates MLKeyPointAnalyzer with MLHandKeypointAnalyzerSetting.
val settings = MLHandKeypointAnalyzerSetting.Factory()
        .setSceneType(MLHandKeypointAnalyzerSetting.TYPE_ALL)
        .setMaxHandResults(2)
        .create()
// Set the maximum number of hand regions  that can be detected within an image. A maximum of 10 hand regions can be   detected by default

mAnalyzer = MLHandKeypointAnalyzerFactory.getInstance().getHandKeypointAnalyzer(settings)
mAnalyzer.setTransactor(mHandKeyPointTransactor)
2.3 El desarrollador crea la clase de procesamiento de resultados de reconocimiento "HandKeypointTransactor", la interfaz MLAnalyzer.MLTransactor <T> de esta clase, y utiliza el método "transactResult" en esta clase para obtener los resultados de detección e implementar servicios específicos.
class HandKeyPointTransactor(surfaceHolder: SurfaceHolder? = null): MLAnalyzer.MLTransactor<MLHandKeypoints> {

override fun transactResult(result: MLAnalyzer.Result<MLHandKeypoints>?) {

    var foundCharacter = findTheCharacterResult(result)

    if (foundCharacter.isNotEmpty() && !foundCharacter.equals(lastCharacter)) {
        lastCharacter = foundCharacter
        displayText.append(lastCharacter)
    }

    canvas.drawText(displayText.toString(), paddingleft, paddingRight, Paint().also {
        it.style = Paint.Style.FILL
        it.color = Color.YELLOW
    })

}
2.4 Crear LensEngine
LensEngine lensEngine = new LensEngine.Creator(getApplicationContext(), analyzer)
setLensType(LensEngine.BACK_LENS)
applyDisplayDimension(width, height) // adjust width and height depending on the orientation
applyFps(5f)
enableAutomaticFocus(true)
create();
2.5 Ejecutar LensEngine
private val surfaceHolderCallback = object : SurfaceHolder.Callback { 

// run the LensEngine in surfaceChanged() 
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
    createLensEngine(width, height)
    mLensEngine.run(holder)
}

}
2.6 Detenga el analizador y libere los recursos de detección
fun stopAnalyzer() {    
      mAnalyzer.stop()    
  }
2.7 Procesando transactResult () para detectar caracteres

Puede utilizar el método transtresult en la clase HandKeypointTransactor para obtener resultados de detección e implementar servicios específicos. Además de la información de coordenadas de cada punto clave de la mano, el resultado de la detección también incluye la palma y el valor de confianza de cada punto clave. Los errores de reconocimiento de puntos clave de la palma y la mano se pueden filtrar en función del valor de confianza. En aplicaciones prácticas, el umbral se puede establecer de forma flexible de acuerdo con la tolerancia de identificación errónea.

2.7.1 Encuentre la dirección del dedo:

Supongamos primero que las pendientes vectoriales de los posibles dedos están en los ejes X e Y respectivamente.

private const val X_COORDINATE = 0
private const val Y_COORDINATE = 1

Suponga que tenemos dedos en 5 vectores, y la dirección de cualquier dedo se puede clasificar como arriba, abajo, abajo-arriba, arriba-abajo e inmóvil en cualquier momento.

enum class FingerDirection {
    VECTOR_UP, VECTOR_DOWN, VECTOR_UP_DOWN, VECTOR_DOWN_UP, VECTOR_UNDEFINED
}

enum class Finger {
    THUMB, FIRST_FINGER, MIDDLE_FINGER, RING_FINGER, LITTLE_FINGER
}

Primero separe los puntos clave correspondientes del resultado a la matriz de puntos clave de diferentes dedos, así:

var firstFinger = arrayListOf<MLHandKeypoint>()
var middleFinger = arrayListOf<MLHandKeypoint>()
var ringFinger = arrayListOf<MLHandKeypoint>()
var littleFinger = arrayListOf<MLHandKeypoint>()
var thumb = arrayListOf<MLHandKeypoint>()

Cada punto clave del dedo corresponde a la articulación del dedo, y la pendiente se puede calcular calculando la distancia entre la articulación y el valor de posición promedio del dedo. Según las coordenadas de los puntos clave cercanos, consulte las coordenadas de los puntos clave.

P.ej:

Tome los dos puntos clave simples de la letra H

int[] datapointSampleH1 = {623, 497, 377, 312,    348, 234, 162, 90,     377, 204, 126, 54,     383, 306, 413, 491,     455, 348, 419, 521 };
int [] datapointSampleH2 = {595, 463, 374, 343,    368, 223, 147, 78,     381, 217, 110, 40,     412, 311, 444, 526,     450, 406, 488, 532};

Usa el promedio de las coordenadas de los dedos para calcular el vector

//For ForeFinger - 623, 497, 377, 312

double avgFingerPosition = (datapoints[0].getX()+datapoints[1].getX()+datapoints[2].getX()+datapoints[3].getX())/4;
// find the average and subract it from the value of x
double diff = datapointSampleH1 [position] .getX() - avgFingerPosition ;
//vector either positive or negative representing the direction
int vector =  (int)((diff *100)/avgFingerPosition ) ;

El resultado del vector será positivo o negativo, si es positivo aparecerá en las cuatro direcciones positivas del eje X. Si es opuesto, será negativo. Use este método para mapear todas las letras, una vez que haya dominado todos los vectores, podemos usarlos para programar.

Inserte la descripción de la imagen aquí

Usando la dirección del vector anterior, podemos clasificar el vector y definir el primero como la enumeración de las direcciones de los dedos

private fun getSlope(keyPoints: MutableList<MLHandKeypoint>, coordinate: Int): FingerDirection {

    when (coordinate) {
        X_COORDINATE -> {
            if (keyPoints[0].pointX > keyPoints[3].pointX && keyPoints[0].pointX > keyPoints[2].pointX)
                return FingerDirection.VECTOR_DOWN
            if (keyPoints[0].pointX > keyPoints[1].pointX && keyPoints[3].pointX > keyPoints[2].pointX)
                return FingerDirection.VECTOR_DOWN_UP
            if (keyPoints[0].pointX < keyPoints[1].pointX && keyPoints[3].pointX < keyPoints[2].pointX)
                return FingerDirection.VECTOR_UP_DOWN
            if (keyPoints[0].pointX < keyPoints[3].pointX && keyPoints[0].pointX < keyPoints[2].pointX)
                return FingerDirection.VECTOR_UP
        }
        Y_COORDINATE -> {
            if (keyPoints[0].pointY > keyPoints[1].pointY && keyPoints[2].pointY > keyPoints[1].pointY && keyPoints[3].pointY > keyPoints[2].pointY)
                return FingerDirection.VECTOR_UP_DOWN
            if (keyPoints[0].pointY > keyPoints[3].pointY && keyPoints[0].pointY > keyPoints[2].pointY)
                return FingerDirection.VECTOR_UP
            if (keyPoints[0].pointY < keyPoints[1].pointY && keyPoints[3].pointY < keyPoints[2].pointY)
                return FingerDirection.VECTOR_DOWN_UP
            if (keyPoints[0].pointY < keyPoints[3].pointY && keyPoints[0].pointY < keyPoints[2].pointY)
                return FingerDirection.VECTOR_DOWN
        }

    }
return FingerDirection.VECTOR_UNDEFINED

Obtenga la dirección de cada dedo y guárdelo en una matriz.

xDirections[Finger.FIRST_FINGER] = getSlope(firstFinger, X_COORDINATE)
yDirections[Finger.FIRST_FINGER] = getSlope(firstFinger, Y_COORDINATE )

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquí

2.7.2 Encuentre el carácter en la dirección del dedo:

Ahora lo tratamos como la única palabra "HOLA", necesita las letras H, E, L, O. Sus correspondientes vectores del eje X y del eje Y se muestran en la figura.

Suposición:

  1. La dirección de la mano es siempre vertical.

  2. Coloque la palma y la muñeca paralelas al teléfono, que está a 90 grados del eje X.

  3. Mantenga la postura durante al menos 3 segundos para grabar personajes.

Comience a usar vectores de mapas de caracteres para encontrar cadenas

// Alphabet H
if (xDirections[Finger.LITTLE_FINGER] == FingerDirection.VECTOR_DOWN_UP
        && xDirections [Finger.RING_FINGER] ==  FingerDirection.VECTOR_DOWN_UP
    && xDirections [Finger.MIDDLE_FINGER] ==  FingerDirection.VECTOR_DOWN
    && xDirections [Finger.FIRST_FINGER] ==  FingerDirection.VECTOR_DOWN
        && xDirections [Finger.THUMB] ==  FingerDirection.VECTOR_DOWN)
    return "H"

//Alphabet E
if (yDirections[Finger.LITTLE_FINGER] == FingerDirection.VECTOR_UP_DOWN
        && yDirections [Finger.RING_FINGER] ==  FingerDirection.VECTOR_UP_DOWN
        && yDirections [Finger.MIDDLE_FINGER] ==  FingerDirection.VECTOR_UP_DOWN
        && yDirections [Finger.FIRST_FINGER] ==  FingerDirection.VECTOR_UP_DOWN
        && xDirections [Finger.THUMB] ==  FingerDirection.VECTOR_DOWN)
    return "E"

if (yDirections[Finger.LITTLE_FINGER] == FingerDirection.VECTOR_UP_DOWN
        && yDirections [Finger.RING_FINGER] ==  FingerDirection.VECTOR_UP_DOWN
        && yDirections [Finger.MIDDLE_FINGER] ==  FingerDirection.VECTOR_UP_DOWN
        && yDirections [Finger.FIRST_FINGER] ==  FingerDirection.VECTOR_UP
        && yDirections [Finger.THUMB] ==  FingerDirection.VECTOR_UP)
    return "L"

if (xDirections[Finger.LITTLE_FINGER] == FingerDirection.VECTOR_UP
        && xDirections [Finger.RING_FINGER] ==  FingerDirection.VECTOR_UP
        && yDirections [Finger.THUMB] ==  FingerDirection.VECTOR_UP)
return "O"

3. Pantalla y resultados

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquí

4. Más consejos y trucos

  1. Cuando se amplía a 26 letras, el error es aún mayor. Para escanear con mayor precisión, se necesitan de 2 a 3 segundos para encontrar y calcular los caracteres más probables de 2 a 3 segundos, lo que puede reducir el error del alfabeto.

  2. Para admitir todas las direcciones, agregue 8 o más direcciones en el eje XY. Primero, se requieren el grado del dedo y el vector de dedo correspondiente.

para resumir

Este intento es una técnica de coordenadas poderosa, que se puede extender a las 26 letras después de generar un mapa vectorial, y la dirección también se puede extender a las 8 direcciones, por lo que tendrá 26 8 5 dedos = 1040 vectores . Para resolver mejor este problema, podemos usar la función de primera derivada del dedo para reemplazar el vector para simplificar el cálculo.

En lugar de crear vectores, podemos mejorar otros, podemos usar modelos de entrenamiento y clasificación de imágenes, y luego usar modelos personalizados. Esta formación tiene como objetivo comprobar la viabilidad de utilizar funciones de procesamiento de puntos clave en el kit de ML de Huawei.

Para obtener más detalles, consulte:

Sitio web oficial de Huawei Developer Alliance:https://developer.huawei.com/consumer/cn/hms

Obtenga documentos de orientación de desarrollo:https://developer.huawei.com/consumer/cn/doc/development

Para participar en las discusiones de los desarrolladores, vaya a la comunidad de Reddit:https://www.reddit.com/r/HMSCore/

Para descargar la demostración y el código de muestra, vaya a Github:https://github.com/HMS-Core

Para resolver problemas de integración, vaya a Stack Overflow:https://stackoverflow.com/questions/tagged/huawei-mobile-services?tab=Newest


Enlace original:
https://developer.huawei.com/consumer/cn/forum/topic/0204423958265820665?fid=18
Autor: temporizador

Supongo que te gusta

Origin blog.51cto.com/14772288/2569650
Recomendado
Clasificación