Você pode ouvir uma imagem?

Mar 22 2023
Atualmente estou trabalhando como Android Engineer no Bumble, mas o conteúdo deste artigo não está relacionado ao meu trabalho no Bumble. Acessibilidade não é um recurso, é uma tendência social — Antonio Santos A acessibilidade é um aspecto frequentemente negligenciado no desenvolvimento de aplicativos.

Atualmente estou trabalhando como Android Engineer no Bumble, mas o conteúdo deste artigo não está relacionado ao meu trabalho no Bumble.

Acessibilidade não é uma característica, é uma tendência social — Antonio Santos

A acessibilidade é um aspecto frequentemente negligenciado no desenvolvimento de aplicativos. Requer alguma premeditação sobre design e implementação. Infelizmente, muitos desenvolvedores consideram que não vale a pena o esforço, pois sua base de usuários atualmente não contém muitas pessoas usando recursos de acessibilidade.

Aqui reside o problema. Se você não desenvolver seu aplicativo tendo a acessibilidade em mente, as pessoas que usam recursos de acessibilidade não farão o download do seu aplicativo, tornando sua base de usuários principalmente o recurso de não acessibilidade usando pessoas. Isso leva os desenvolvedores a pensar que não seria tão benéfico implementar recursos de acessibilidade, então eles não o fazem. E o ciclo continua.

Fonte

Recentemente, ouvi alguém falando sobre acessibilidade em aplicativos móveis e eles apontaram que a primeira coisa que você vê no perfil de alguém é a foto. Eles então apontaram para todos que, sendo deficientes visuais, não podiam ver e receberam apenas um pequeno texto informando que havia uma foto nessa parte da tela.

Eu ouço você dizer "bem, sim, o que mais isso vai fazer?" .

E você estaria certo em sua suposição de que é exatamente o que quase todo leitor de tela faz quando encontra uma imagem. E isso ocorre porque os desenvolvedores fornecem ao leitor de tela um texto alternativo ( alt text ) para ler em vez disso. E a coisa mais fácil de fazer nesta situação é escrever:

altText = "image"

Se levarmos em conta algumas características que normalmente notamos em uma pessoa quando vemos uma foto dela, tenho certeza que seria mais ou menos assim: cor do cabelo, cor dos olhos, usa óculos? etc. E se um leitor de tela pudesse lhe dizer todas essas informações em vez de “isto é uma imagem”?

Apresentando o TensorFlow Lite

O TensorFlow é uma plataforma para aprendizado de máquina e fornece uma biblioteca Android (e iOS!) que usarei neste exemplo.

Se pegarmos apenas uma das características do exemplo anterior: cor do cabelo; podemos “ensinar” um aplicativo a dizer a cor do cabelo da pessoa em uma foto.

Para começar, vou assumir que você sabe como criar um aplicativo Android (se não, aqui está um tutorial ), então vá em frente e faça um novo projeto.

Veja como é o meu:

Fonte da foto

Eu tenho um ImageView da imagem que gostaria de saber mais e depois um Button que usarei para determinar a cor do cabelo. Há também um TextView que usarei para mostrar os resultados logo abaixo do botão.

Você vai precisar importar o TensorFlow Lite também:

implementation 'org.tensorflow:tensorflow-lite-support:0.1.0'
implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'

aaptOptions {
    noCompress "tflite"
}

Treinando um modelo

Antes de prosseguirmos, precisamos treinar um modelo. Um modelo é o que nosso aplicativo usará para decidir a cor do cabelo em nossa foto.

Existem algumas maneiras de fazer isso, mas como estou limitado ao poder de processamento da minha máquina, optei por usar o CoLab (essa opção requer que você escreva um pouco de Python, mas não se preocupe se você não estiver familiarizado, vou colar o código que você precisa aqui).

Vá em frente e crie um novo notebook no CoLab e cole o seguinte:

!pip install tf-nightly
!pip install tflite-model-maker

Em seguida, no mesmo notebook, adicione as seguintes importações de python:

from tflite_model_maker import image_classifier
from tflite_model_maker.image_classifier import DataLoader

data = DataLoader.from_folder('test-data/')
model = image_classifier.create(data)
loss, accuracy = model.evaluate(data)
model.export(export_dir='/tmp/')

Isso carregará imagens de uma pasta chamada test-data, classificará-as e produzirá um modelo TensorFlow na pasta /tmp/.

Mas antes de executarmos este código, precisamos preencher nossa pasta test-data com fotos. Para que isso funcione, precisamos de uma pasta dentro de test-data para cada cor de cabelo que queremos distinguir. Por exemplo: loira, morena, preta, ruiva, cinza. Em seguida, preencha cada pasta de cor de cabelo com fotos de pessoas com essa cor de cabelo (fique em jpgs e pngs, pois aceita apenas alguns tipos de arquivo). Certifique-se de que esta pasta de dados de teste está dentro da pasta de dados de amostra no CoLab. Apontar para pelo menos 10 imagens em cada conjunto de dados, mas quanto mais imagens, mais confiante pode ser!

Vamos executá-lo!

Se tudo correr bem durante o tempo de execução*, você deverá ter um arquivo model.tflite na pasta /tmp/ do CoLab. Baixe este arquivo e importe-o para o seu projeto Android. Você precisará adicionar uma nova pasta de recursos chamada “ml” no mesmo nível das outras pastas de recursos. Adicione seu modelo lá.

Classifique sua foto

A última coisa a fazer agora é executar nossa foto no aplicativo em nosso modelo TensorFlow. Se sua foto ainda não for um bitmap, você precisará convertê-la. Aqui está como eu fiz isso:

val img: ImageView = findViewById(R.id.image)
val fileName = "person.jpeg"
val bitmap: Bitmap? = assetsToBitmap(fileName)
bitmap?.apply {
    img.setImageBitmap(this)
}

btn.setOnClickListener {

    var tfImage = TensorImage(DataType.FLOAT32)
    tfImage.load(bitmap)

    val imageProcessor = ImageProcessor.Builder()
        .add(ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR))
        .build()
    tfImage = imageProcessor.process(tfImage)

    val model = Model.newInstance(this@MainActivity)
    val outputs = model.process(tfImage)
    val outputBuffer = outputs.probabilityAsCategoryList
    var outputText = ""
    for (label in outputBuffer.iterator()) {
        val text = label.label
        val confidence = label.score
        outputText += "$text : $confidence\n"
    }
    txtOutput.text = outputText
}

val outputs = model.process(tfImage)

A última linha desse snippet é responsável por mostrar as pontuações de confiança em meu TextView. Nesse contexto, a pontuação de confiança informará a probabilidade de a pessoa na foto ter cada cor de cabelo.

Veja como é o meu:

Fonte da foto

Você pode ver aqui que há 47% de confiança de que a pessoa tem cabelo preto, mas também 35% de confiança de que é grisalho. Isso ocorre porque usei um conjunto de dados relativamente pequeno de cerca de 100 imagens diferentes. Se eu usasse um conjunto de dados de 1.000 imagens, as taxas de confiança seriam muito maiores.

Então, agora que temos as pontuações de confiança, podemos pegar aquela com a maior confiança e, usando alguma manipulação de string, transformá-la em um fato legível por humanos, por exemplo: “Esta é a foto de uma pessoa com cabelo preto”. Isso pode então ser substituído pelo texto alternativo em uma imagem. Portanto, descrevendo uma imagem!

Podemos usar esse mesmo processo para produzir modelos para outras características, como cor dos olhos, penteado, se estão sorrindo, etc., para tornar nosso texto alternativo ainda mais descritivo!

O aprendizado de máquina geralmente parece um conceito assustadoramente difícil de entender, mas com opções como TensorFlow Lite e MLKit disponíveis, é algo que qualquer nível de desenvolvedor pode tentar.

Espero que este artigo possa inspirar os desenvolvedores a considerar mais a acessibilidade em seus aplicativos e até mesmo ajudá-los a começar a trabalhar em uma solução viável!

Fonte

Codificação feliz! ⭐️

Solução de problemas

(*) Se você está tendo problemas para executar o script do CoLab, pode ser necessário remover o seguinte (substituindo a pasta de cores de cabelo por cada uma que você possui):

test-data/blonde/.ipynb_checkpoints