Können Sie ein Bild hören?
Ich arbeite derzeit als Android Engineer bei Bumble, aber der Inhalt dieses Artikels bezieht sich nicht auf meine Arbeit bei Bumble.
Barrierefreiheit ist kein Feature, sondern ein gesellschaftlicher Trend – Antonio Santos
Barrierefreiheit ist ein oft übersehener Aspekt der App-Entwicklung. Es erfordert eine gewisse Voraussicht bei Design und Implementierung. Leider halten viele Entwickler den Aufwand nicht für lohnenswert, da ihre Benutzerbasis derzeit nicht viele Personen umfasst, die Barrierefreiheitsfunktionen nutzen.
Hierin liegt das Problem. Wenn Sie Ihre App nicht unter Berücksichtigung der Barrierefreiheit entwickeln, werden Personen, die Barrierefreiheitsfunktionen verwenden, Ihre App nicht herunterladen, sodass Ihre Benutzerbasis hauptsächlich Personen verwendet, die Barrierefreiheitsfunktionen nicht nutzen. Dies führt dann dazu, dass Entwickler denken, dass es nicht so vorteilhaft wäre, Barrierefreiheitsfunktionen zu implementieren, also lassen sie es lieber bleiben. Und der Zyklus geht weiter.
Kürzlich hörte ich jemandem zu, der über Barrierefreiheit in mobilen Apps sprach, und er wies darauf hin, dass das erste, was man im Profil einer Person sieht, ihr Foto ist. Anschließend machten sie alle darauf aufmerksam, dass sie es aufgrund ihrer Sehbehinderung nicht sehen könnten und nur einen kleinen Text erhalten hätten, der sie darüber informierte, dass sich auf diesem Teil des Bildschirms ein Foto befände.
Ich höre Sie sagen : „Na ja, was soll es sonst noch tun?“ .
Und Sie haben Recht mit Ihrer Annahme, dass es genau das ist, was fast jeder Bildschirmleser tut, wenn er auf ein Bild stößt. Und das liegt daran, dass Entwickler dem Screenreader stattdessen Alternativtext ( Alt-Text ) zum Vorlesen zur Verfügung stellen. Und das einfachste, was man in dieser Situation tun kann, ist zu schreiben:
altText = "image"
Wenn wir einige Merkmale berücksichtigen, die uns normalerweise an einer Person auffallen, wenn wir ein Foto von ihr sehen, dann sind das sicher etwa folgende: Haarfarbe, Augenfarbe, trägt sie eine Brille? usw. Was wäre also, wenn ein Screenreader Ihnen alle diese Informationen anstelle von „Das ist ein Bild“ sagen könnte?
Wir stellen vor: TensorFlow Lite
TensorFlow ist eine Plattform für maschinelles Lernen und stellt sehr hilfreich eine Android-Bibliothek (und eine iOS-Bibliothek!) bereit, die ich in diesem Beispiel verwenden werde.
Wenn wir nur eines der Merkmale aus dem vorherigen Beispiel übernehmen: Haarfarbe; Wir können einer App „beibringen“, wie sie Ihnen sagt, welche Haarfarbe die Person auf einem Foto hat.
Zunächst gehe ich davon aus, dass Sie wissen, wie man eine Android-App erstellt (falls nicht, finden Sie hier ein Tutorial ). Machen Sie also weiter und erstellen Sie ein neues Projekt.
So sieht meiner aus:
Ich habe eine ImageView des Bildes, über das ich mehr erfahren möchte, und dann einen Button, mit dem ich die Haarfarbe bestimmen werde. Es gibt auch eine Textansicht, die ich verwenden werde, um die Ergebnisse direkt unter der Schaltfläche anzuzeigen.
Sie müssen auch TensorFlow Lite importieren:
implementation 'org.tensorflow:tensorflow-lite-support:0.1.0'
implementation 'org.tensorflow:tensorflow-lite-metadata:0.1.0'
aaptOptions {
noCompress "tflite"
}
Ein Modell trainieren
Bevor wir fortfahren, müssen wir ein Modell trainieren. Ein Modell wird von unserer App verwendet, um zu entscheiden, welche Haarfarbe auf unserem Foto ist.
Es gibt mehrere Möglichkeiten, dies zu tun, aber da ich nur über die Rechenleistung meines Computers verfügt, habe ich mich für die Verwendung von CoLab entschieden (für diese Option müssen Sie etwas Python schreiben, aber keine Sorge, wenn Sie nicht damit vertraut sind, werde ich es einfügen Den benötigten Code finden Sie hier).
Erstellen Sie ein neues Notizbuch in CoLab und fügen Sie Folgendes ein:
!pip install tf-nightly
!pip install tflite-model-maker
Fügen Sie dann im selben Notebook die folgenden Python-Importe hinzu:
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/')
Dadurch werden Bilder aus einem Ordner namens test-data geladen, klassifiziert und dann ein TensorFlow-Modell im Ordner /tmp/ erstellt.
Aber bevor wir diesen Code ausführen, müssen wir unseren Testdatenordner mit Fotos füllen. Damit dies funktioniert, benötigen wir für jede Haarfarbe, die wir unterscheiden möchten, einen Ordner in test-data. Zum Beispiel: blond, brünett, schwarz, rotbraun, grau. Füllen Sie dann jeden Haarfarben-Ordner mit Fotos von Personen mit dieser Haarfarbe (halten Sie sich bei JPGs und PNGs, da nur wenige Dateitypen akzeptiert werden). Stellen Sie sicher, dass sich dieser Testdatenordner im Beispieldatenordner in CoLab befindet. Streben Sie mindestens 10 Bilder in jedem Datensatz an, aber je mehr Bilder, desto sicherer kann es sein!
Lassen wir es laufen!
Wenn zur Laufzeit* alles gut geht, sollten Sie jetzt eine model.tflite-Datei in Ihrem CoLab /tmp/-Ordner haben. Laden Sie diese Datei herunter und importieren Sie sie dann in Ihr Android-Projekt. Sie müssen einen neuen Ressourcenordner mit dem Namen „ml“ auf derselben Ebene wie Ihre anderen Ressourcenordner hinzufügen. Fügen Sie dort Ihr Modell hinzu.
Klassifizieren Sie Ihr Foto
Als letztes müssen wir nun unser Foto in der App mit unserem TensorFlow-Modell vergleichen. Wenn Ihr Foto noch kein Bitmap ist, müssen Sie es konvertieren. So habe ich es gemacht:
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)
Die letzte Zeile in diesem Snippet ist für die Anzeige der Konfidenzwerte in meiner TextView verantwortlich. In diesem Zusammenhang gibt Ihnen der Konfidenzwert Aufschluss darüber, wie wahrscheinlich es ist, dass die Person auf dem Foto die jeweilige Haarfarbe hat.
So sieht meiner aus:
Hier sehen Sie, dass 47 % davon überzeugt sind, dass die Person schwarze Haare hat, aber auch 35 % davon überzeugt sind, dass die Person graue Haare hat. Das liegt daran, dass ich einen relativ kleinen Datensatz von etwa 100 verschiedenen Bildern verwendet habe. Wenn ich stattdessen einen Datensatz mit 1000 Bildern verwenden würde, wären die Konfidenzraten viel höher.
Da wir nun die Konfidenzwerte haben, können wir diejenige mit der höchsten Konfidenz nehmen und diese mithilfe einiger Zeichenfolgenmanipulationen in eine für Menschen lesbare Tatsache umwandeln, z. B.: „Dies ist ein Foto einer Person mit schwarzen Haaren.“ Dieser kann dann den Alternativtext auf einem Bild ersetzen. Deshalb ein Bild beschreiben!
Anschließend können wir denselben Prozess verwenden, um Modelle für andere Merkmale wie Augenfarbe, Frisur, Lächeln usw. zu erstellen, um unseren Alternativtext noch aussagekräftiger zu gestalten!
Maschinelles Lernen scheint oft ein erschreckend schwieriges Konzept zu sein, aber mit verfügbaren Optionen wie TensorFlow Lite und MLKit ist es etwas, das jeder Entwickler ausprobieren kann.
Hoffentlich kann dieser Artikel Entwickler dazu inspirieren, die Barrierefreiheit in ihren Apps stärker zu berücksichtigen, und ihnen sogar dabei helfen, mit der Arbeit an einer praktikablen Lösung zu beginnen!
Viel Spaß beim Codieren! ⭐️
Fehlerbehebung
(*) Wenn Sie Probleme beim Ausführen des CoLab-Skripts haben, müssen Sie möglicherweise Folgendes entfernen (und den Haarfarbenordner für alle vorhandenen Dateien ersetzen):
test-data/blonde/.ipynb_checkpoints

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































