mediapipe
mediapipe copied to clipboard
Showing only certain landmarks on android FaceLandmarker App
Hello, I am playing around with your Face Landmarker app for android.
I am very inexperienced with Koltin, so my apologies. I would like to display only certain landmarks on the face when running the app and I'm not sure where to start. For example, if I only wanted to show the left eye landmarks on the app, how would I do that?
In python, I would find the variable storing the facelandmark coordinates, and I would index it by these values to get the left eyelandmarks: [85, 246, 161, 160, 159, 158, 157, 173, 155, 154, 153, 145, 144, 163]. How would I do that in this koltin project? What variable contains the landmarks and how would I index it like this?
It looks like OverlayView.kt setResults function might be the place to start, but I'm really not sure. Any advise would be helpful. Thank you!
https://github.com/googlesamples/mediapipe/tree/main/examples/face_landmarker/android
Yup the OverlayView setResults function is where the landmarks to display are set! :) You can add a filter before sending those results to limit it to only the landmarks that you want.
Thank you for your reply. That is really helpful. Can you critique this specific section? My approach is to modify setResults() to:
- create index of the only landmarks I want to keep
- filter results by these indices
- rewrite results with the landmark data for only the previously specified indices
fun setResults(
faceLandmarkerResults: FaceLandmarkerResult,
imageHeight: Int,
imageWidth: Int,
runningMode: RunningMode = RunningMode.IMAGE
) {
results = faceLandmarkerResults
val indexList = listOf(85, 246, 161, 160, 159, 158, 157, 173, 155, 154, 153, 145, 144, 163)
val filteredNumbers = results.filterIndexed { index, value ->
index in indexList
}
results = filteredNumbers
this.imageHeight = imageHeight
this.imageWidth = imageWidth
scaleFactor = when (runningMode) {
RunningMode.IMAGE,
RunningMode.VIDEO -> {
min(width * 1f / imageWidth, height * 1f / imageHeight)
}
RunningMode.LIVE_STREAM -> {
// PreviewView is in FILL_START mode. So we need to scale up the
// landmarks to match with the size that the captured images will be
// displayed.
max(width * 1f / imageWidth, height * 1f / imageHeight)
}
}
invalidate()
}
However, I keep getting the error that the code cannot infer the type for this parameter (point to index and value). How should can I properly type these parameters, or, is there another way I should do this?
Thank you!
The full error is below.
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:public inline fun <T> Array<out TypeVariable(T)>.filterIndexed(predicate: (index: Int, TypeVariable(T)) -> Boolean): List<TypeVariable(T)> defined in kotlin.collections
public inline fun BooleanArray.filterIndexed(predicate: (index: Int, Boolean) -> Boolean): List<Boolean> defined in kotlin.collections
public inline fun ByteArray.filterIndexed(predicate: (index: Int, Byte) -> Boolean): List<Byte> defined in kotlin.collections
public inline fun CharArray.filterIndexed(predicate: (index: Int, Char) -> Boolean): List<Char> defined in kotlin.collections
public inline fun CharSequence.filterIndexed(predicate: (index: Int, Char) -> Boolean): CharSequence defined in kotlin.text
public inline fun DoubleArray.filterIndexed(predicate: (index: Int, Double) -> Boolean): List<Double> defined in kotlin.collections
public inline fun FloatArray.filterIndexed(predicate: (index: Int, Float) -> Boolean): List<Float> defined in kotlin.collections
public inline fun IntArray.filterIndexed(predicate: (index: Int, Int) -> Boolean): List<Int> defined in kotlin.collections
public inline fun LongArray.filterIndexed(predicate: (index: Int, Long) -> Boolean): List<Long> defined in kotlin.collections
public inline fun ShortArray.filterIndexed(predicate: (index: Int, Short) -> Boolean): List<Short> defined in kotlin.collections
public inline fun String.filterIndexed(predicate: (index: Int, Char) -> Boolean): String defined in kotlin.text
public inline fun UByteArray.filterIndexed(predicate: (index: Int, UByte) -> Boolean): List<UByte> defined in kotlin.collections
public inline fun UIntArray.filterIndexed(predicate: (index: Int, UInt) -> Boolean): List<UInt> defined in kotlin.collections
public inline fun ULongArray.filterIndexed(predicate: (index: Int, ULong) -> Boolean): List<ULong> defined in kotlin.collections
public inline fun UShortArray.filterIndexed(predicate: (index: Int, UShort) -> Boolean): List<UShort> defined in kotlin.collections
public inline fun <T> Iterable<TypeVariable(T)>.filterIndexed(predicate: (index: Int, TypeVariable(T)) -> Boolean): List<TypeVariable(T)> defined in kotlin.collections
public fun <T> Sequence<TypeVariable(T)>.filterIndexed(predicate: (index: Int, TypeVariable(T)) -> Boolean): Sequence<TypeVariable(T)> defined in kotlin.sequences