Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Showing only certain landmarks on android FaceLandmarker App #372

Open
connormeaton opened this issue Apr 11, 2024 · 2 comments
Open

Showing only certain landmarks on android FaceLandmarker App #372

connormeaton opened this issue Apr 11, 2024 · 2 comments

Comments

@connormeaton
Copy link

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

@PaulTR
Copy link
Collaborator

PaulTR commented Apr 12, 2024

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.

@connormeaton
Copy link
Author

connormeaton commented Apr 12, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants