All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.triniwiz.fancycamera.facedetection.FaceDetection.kt Maven / Gradle / Ivy

There is a newer version: 4.0.0-alpha.17
Show newest version
package io.github.triniwiz.fancycamera.facedetection

import android.graphics.Bitmap
import com.google.android.gms.tasks.Tasks
import com.google.gson.Gson
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.face.FaceDetectorOptions
import io.github.triniwiz.fancycamera.ImageProcessor
import org.json.JSONObject
import java.util.concurrent.ExecutionException
import java.util.concurrent.Future
import java.util.concurrent.FutureTask

class FaceDetection : ImageProcessor {
    var options = Options()

    override val type: Int
        get() = 1
    private val gson = Gson()
    override fun process(image: InputImage): FutureTask {
        val opts = FaceDetectorOptions.Builder()
        if (options.faceTracking) {
            opts.enableTracking()
        }
        opts.setPerformanceMode(options.detectionMode.toNative())
        opts.setMinFaceSize(options.minimumFaceSize)
        opts.setLandmarkMode(options.landmarkMode.toNative())
        opts.setContourMode(options.contourMode.toNative())
        opts.setClassificationMode(options.classificationMode.toNative())
        val client = com.google.mlkit.vision.face.FaceDetection.getClient(opts.build())

        return FutureTask {
            try {
                val results = Tasks.await(client.process(image))
                val result = mutableListOf()
                for (face in results) {
                    result.add(Result(face))
                }

                if (result.isNotEmpty()) {
                    gson.toJson(result)
                } else {
                    ""
                }
            } catch (e: ExecutionException) {
                throw e
            } catch (e: InterruptedException) {
                throw e
            } finally {
                client.close()
            }
        }
    }

    enum class DetectionMode(private val mode: String) {
        Accurate("accurate"),
        Fast("fast");

        companion object {
            @JvmStatic
            fun fromString(value: String): DetectionMode? {
                return when (value) {
                    "accurate" -> Accurate
                    "fast" -> Fast
                    else -> null
                }
            }
        }

        internal fun toNative(): Int {
            return when (this) {
                Accurate -> FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE
                Fast -> FaceDetectorOptions.PERFORMANCE_MODE_FAST
            }
        }

        override fun toString(): String {
            return mode
        }
    }

    enum class LandMarkMode(private val mode: String) {
        None("none"),
        All("all");

        companion object {
            @JvmStatic
            fun fromString(value: String): LandMarkMode? {
                return when (value) {
                    "all" -> All
                    "none" -> None
                    else -> null
                }
            }
        }

        override fun toString(): String {
            return mode
        }

        internal fun toNative(): Int {
            return when (this) {
                None -> FaceDetectorOptions.LANDMARK_MODE_NONE
                All -> FaceDetectorOptions.LANDMARK_MODE_ALL
            }
        }
    }

    enum class ContourMode(private val mode: String) {
        None("none"),
        All("all");

        companion object {
            @JvmStatic
            fun fromString(value: String): ContourMode? {
                return when (value) {
                    "all" -> All
                    "none" -> None
                    else -> null
                }
            }
        }

        override fun toString(): String {
            return mode
        }

        internal fun toNative(): Int {
            return when (this) {
                None -> FaceDetectorOptions.CONTOUR_MODE_NONE
                All -> FaceDetectorOptions.CONTOUR_MODE_ALL
            }
        }
    }

    enum class ClassificationMode(private val mode: String) {
        None("none"),
        All("all");

        companion object {
            @JvmStatic
            fun fromString(value: String): ClassificationMode? {
                return when (value) {
                    "all" -> All
                    "none" -> None
                    else -> null
                }
            }
        }

        override fun toString(): String {
            return mode
        }

        internal fun toNative(): Int {
            return when (this) {
                None -> FaceDetectorOptions.CLASSIFICATION_MODE_NONE
                All -> FaceDetectorOptions.CLASSIFICATION_MODE_ALL
            }
        }
    }

    class Options {
        var faceTracking: Boolean = false
        var minimumFaceSize: Float = 0.1F
        var detectionMode = DetectionMode.Fast
        var landmarkMode = LandMarkMode.All
        var contourMode = ContourMode.All
        var classificationMode = ClassificationMode.All

        fun setDetectionMode(mode: String) {
            val mMode = DetectionMode.fromString(mode) ?: return
            detectionMode = mMode
        }

        fun setLandMarkMode(mode: String) {
            val mMode = LandMarkMode.fromString(mode) ?: return
            landmarkMode = mMode
        }

        fun setContourMode(mode: String) {
            val mMode = ContourMode.fromString(mode) ?: return
            contourMode = mMode
        }

        fun setClassificationMode(mode: String) {
            val mMode = ClassificationMode.fromString(mode) ?: return
            classificationMode = mMode
        }

        override fun toString(): String {
            return "faceTracking: $faceTracking, minimumFaceSize: $minimumFaceSize, detectionMode: $detectionMode, landmarkMode: $landmarkMode, contourMode: $contourMode, classificationMode: $classificationMode"
        }

        companion object {
            @JvmStatic
            fun fromJson(value: String): Options? {
                return fromJson(value, false)
            }

            @JvmStatic
            fun fromJson(value: String, returnDefault: Boolean): Options? {
                return try {
                    val json = JSONObject(value)
                    fromJson(json, returnDefault)
                } catch (e: Exception) {
                    if (returnDefault) {
                        Options()
                    } else {
                        null
                    }
                }
            }

            @JvmStatic
            fun fromJson(value: JSONObject, returnDefault: Boolean): Options? {
                try {
                    val default = Options()
                    default.faceTracking = value.optBoolean("faceTracking", default.faceTracking)
                    default.minimumFaceSize =
                        value.optDouble("minimumFaceSize", default.minimumFaceSize.toDouble())
                            .toFloat()
                    default.setDetectionMode(value.optString("detectionMode", "fast"))
                    default.setLandMarkMode(value.optString("landmarkMode", "all"))
                    default.setContourMode(value.optString("contourMode", "all"))
                    default.setClassificationMode(value.optString("classificationMode", "all"))

                    return default
                } catch (e: Exception) {
                    return if (returnDefault) {
                        Options()
                    } else {
                        null
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy