Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,38 +1,13 @@
package com.simprints.face.infra.basebiosdk.matching

abstract class FaceMatcher {
abstract class FaceMatcher(
open val probeSamples: List<FaceSample>
) : AutoCloseable {
/**
* The matching SDK name
*/
abstract val matcherName: String
abstract val supportedTemplateFormat: String

/**
* Returns a comparison score of two templates from 0.0 - 100.0
*/
abstract suspend fun getComparisonScore(
probe: ByteArray,
matchAgainst: ByteArray,
): Float

/**
* Get highest comparison score for matching candidate template against all probes
* Get highest comparison score for matching candidate template against samples
*
* @param probes
* @param candidate
* @return the highest comparison score
*/
suspend fun getHighestComparisonScoreForCandidate(
probes: List<FaceSample>,
candidate: FaceIdentity,
): Float {
var highestScore = 0f
probes.forEach { probe ->
candidate.faces.forEach { face ->
val score = getComparisonScore(probe.template, face.template)
if (score > highestScore) highestScore = score
}
}
return highestScore
}
abstract suspend fun getHighestComparisonScoreForCandidate(candidate: FaceIdentity): Float
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ package com.simprints.face.infra.biosdkresolver
import com.simprints.face.infra.basebiosdk.detection.FaceDetector
import com.simprints.face.infra.basebiosdk.initialization.FaceBioSdkInitializer
import com.simprints.face.infra.basebiosdk.matching.FaceMatcher
import com.simprints.face.infra.basebiosdk.matching.FaceSample

interface FaceBioSDK {
val initializer: FaceBioSdkInitializer
val detector: FaceDetector
val matcher: FaceMatcher

val version: String
val templateFormat: String
val matcherName: String

fun createMatcher(probeSamples: List<FaceSample>): FaceMatcher
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.simprints.face.infra.biosdkresolver

import com.simprints.face.infra.basebiosdk.matching.FaceMatcher
import com.simprints.face.infra.basebiosdk.matching.FaceSample
import com.simprints.face.infra.rocv1.detection.RocV1Detector
import com.simprints.face.infra.rocv1.detection.RocV1Detector.Companion.RANK_ONE_TEMPLATE_FORMAT_1_23
import com.simprints.face.infra.rocv1.initialization.RocV1Initializer
import com.simprints.face.infra.rocv1.matching.RocV1Matcher
import javax.inject.Inject
Expand All @@ -10,7 +13,10 @@ import javax.inject.Singleton
class RocV1BioSdk @Inject constructor(
override val initializer: RocV1Initializer,
override val detector: RocV1Detector,
override val matcher: RocV1Matcher,
) : FaceBioSDK {
override val version: String = "1.23"
override val templateFormat: String = RANK_ONE_TEMPLATE_FORMAT_1_23
override val matcherName: String = "RANK_ONE"

override fun createMatcher(probeSamples: List<FaceSample>): FaceMatcher = RocV1Matcher(probeSamples)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.simprints.face.infra.biosdkresolver

import com.simprints.face.infra.basebiosdk.matching.FaceMatcher
import com.simprints.face.infra.basebiosdk.matching.FaceSample
import com.simprints.face.infra.rocv3.detection.RocV3Detector
import com.simprints.face.infra.rocv3.detection.RocV3Detector.Companion.RANK_ONE_TEMPLATE_FORMAT_3_1
import com.simprints.face.infra.rocv3.initialization.RocV3Initializer
import com.simprints.face.infra.rocv3.matching.RocV3Matcher
import javax.inject.Inject
Expand All @@ -10,7 +13,10 @@ import javax.inject.Singleton
class RocV3BioSdk @Inject constructor(
override val initializer: RocV3Initializer,
override val detector: RocV3Detector,
override val matcher: RocV3Matcher,
) : FaceBioSDK {
override val version: String = "3.1"
override val templateFormat: String = RANK_ONE_TEMPLATE_FORMAT_3_1
override val matcherName: String = "RANK_ONE"

override fun createMatcher(probeSamples: List<FaceSample>): FaceMatcher = RocV3Matcher(probeSamples)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.simprints.face.infra.biosdkresolver

import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.*
import com.simprints.infra.config.store.ConfigRepository
import io.mockk.coEvery
import io.mockk.mockk
import io.mockk.*
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import java.lang.IllegalArgumentException

class ResolveFaceBioSdkUseCaseTest {
private lateinit var resolveFaceBioSdkUseCase: ResolveFaceBioSdkUseCase
Expand All @@ -17,9 +15,10 @@ class ResolveFaceBioSdkUseCaseTest {

@Before
fun setUp() {
rocV1BioSdk = RocV1BioSdk(mockk(), mockk(), mockk())
rocV3BioSdk = RocV3BioSdk(mockk(), mockk(), mockk())
resolveFaceBioSdkUseCase = ResolveFaceBioSdkUseCase(configRepository, rocV1BioSdk, rocV3BioSdk)
rocV1BioSdk = RocV1BioSdk(mockk(), mockk())
rocV3BioSdk = RocV3BioSdk(mockk(), mockk())
resolveFaceBioSdkUseCase =
ResolveFaceBioSdkUseCase(configRepository, rocV1BioSdk, rocV3BioSdk)
}

@Test(expected = IllegalArgumentException::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.simprints.face.infra.biosdkresolver


import com.google.common.truth.Truth.*
import io.mockk.*
import org.junit.Test

class RocV1BioSdkTest {


private lateinit var rocV1BioSdk: RocV1BioSdk

@Test
fun createMatcher() {
rocV1BioSdk = RocV1BioSdk(mockk(), mockk())

val matcher = rocV1BioSdk.createMatcher(emptyList())

assertThat(matcher).isNotNull()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.simprints.face.infra.biosdkresolver


import com.google.common.truth.Truth.*
import io.mockk.*
import org.junit.Test

class RocV3BioSdkTest {

private lateinit var rocV3BioSdk: RocV3BioSdk

@Test
fun createMatcher() {
rocV3BioSdk = RocV3BioSdk(mockk(), mockk())

val matcher = rocV3BioSdk.createMatcher(emptyList())

assertThat(matcher).isNotNull()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.simprints.face.infra.basebiosdk.initialization.FaceBioSdkInitializer
import com.simprints.face.infra.basebiosdk.matching.FaceMatcher
import com.simprints.face.infra.rocv1.detection.RocV1Detector
import com.simprints.face.infra.rocv1.initialization.RocV1Initializer
import com.simprints.face.infra.rocv1.matching.RocV1Matcher
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -19,7 +18,4 @@ abstract class RocV1WrapperModule {

@Binds
abstract fun provideFaceDetector(impl: RocV1Detector): FaceDetector

@Binds
abstract fun provideFaceMatcher(impl: RocV1Matcher): FaceMatcher
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,53 @@
package com.simprints.face.infra.rocv1.matching

import com.simprints.core.ExcludedFromGeneratedTestCoverageReports
import com.simprints.face.infra.basebiosdk.matching.FaceIdentity
import com.simprints.face.infra.basebiosdk.matching.FaceMatcher
import com.simprints.face.infra.rocv1.detection.RocV1Detector.Companion.RANK_ONE_TEMPLATE_FORMAT_1_23
import com.simprints.face.infra.basebiosdk.matching.FaceSample
import io.rankone.rocsdk.embedded.SWIGTYPE_p_unsigned_char
import io.rankone.rocsdk.embedded.roc
import io.rankone.rocsdk.embedded.rocConstants.ROC_FAST_FV_SIZE
import javax.inject.Inject

class RocV1Matcher @Inject constructor() : FaceMatcher() {
override val matcherName
get() = "RANK_ONE"

override val supportedTemplateFormat
get() = RANK_ONE_TEMPLATE_FORMAT_1_23

// Ignore this method from test coverage calculations
// because it uses jni native code which is hard to test
@ExcludedFromGeneratedTestCoverageReports(
reason = "This function uses roc class that has native functions and can't be mocked",
)
override suspend fun getComparisonScore(
probe: ByteArray,
matchAgainst: ByteArray,
): Float {
val probeTemplate = roc.new_uint8_t_array(ROC_FAST_FV_SIZE.toInt())
roc.memmove(roc.roc_cast(probeTemplate), probe)

@ExcludedFromGeneratedTestCoverageReports(
reason = "This function uses roc class that has native functions and can't be mocked",
)
class RocV1Matcher(
override val probeSamples: List<FaceSample>
) : FaceMatcher(probeSamples) {

var probeTemplates: List<SWIGTYPE_p_unsigned_char> = probeSamples.mapIndexed { i, probe ->
val probeTemplate: SWIGTYPE_p_unsigned_char =
roc.new_uint8_t_array(ROC_FAST_FV_SIZE.toInt())
roc.memmove(roc.roc_cast(probeTemplate), probe.template)
probeTemplate
}

override suspend fun getHighestComparisonScoreForCandidate(candidate: FaceIdentity): Float =
probeTemplates.flatMap { probeTemplate ->
candidate.faces.map { face ->
getSimilarityScoreForCandidate(probeTemplate, face.template)
}
}.max()

private fun getSimilarityScoreForCandidate(
probeTemplate: SWIGTYPE_p_unsigned_char,
candidateTemplate: ByteArray
): Float {
val matchTemplate = roc.new_uint8_t_array(ROC_FAST_FV_SIZE.toInt())
roc.memmove(roc.roc_cast(matchTemplate), matchAgainst)
roc.memmove(roc.roc_cast(matchTemplate), candidateTemplate)

val similarity = roc.roc_embedded_compare_templates(
probeTemplate,
ROC_FAST_FV_SIZE,
matchTemplate,
ROC_FAST_FV_SIZE,
)

roc.delete_uint8_t_array(probeTemplate)
roc.delete_uint8_t_array(matchTemplate)

return (similarity * 100)
return similarity * 100f
}

override fun close() {
probeTemplates.forEach { roc.delete_uint8_t_array(it) }
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.simprints.infra.rocwrapper.matching

import com.google.common.truth.Truth
import com.google.common.truth.*
import com.simprints.face.infra.rocv1.matching.RocV1Matcher
import org.junit.Test

class RocV1MatcherTest {
// Dummy test to generate jacoco reports.
@Test
fun getMatcherName() {
RocV1Matcher().matcherName
Truth.assertThat(RocV1Matcher().matcherName).isEqualTo("RANK_ONE")
Truth.assertThat(RocV1Matcher(emptyList())).isNotNull()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package com.simprints.face.infra.rocv3

import com.simprints.face.infra.basebiosdk.detection.FaceDetector
import com.simprints.face.infra.basebiosdk.initialization.FaceBioSdkInitializer
import com.simprints.face.infra.basebiosdk.matching.FaceMatcher
import com.simprints.face.infra.rocv3.detection.RocV3Detector
import com.simprints.face.infra.rocv3.initialization.RocV3Initializer
import com.simprints.face.infra.rocv3.matching.RocV3Matcher
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -19,7 +17,4 @@ abstract class RocV3WrapperModule {

@Binds
abstract fun provideFaceDetector(impl: RocV3Detector): FaceDetector

@Binds
abstract fun provideFaceMatcher(impl: RocV3Matcher): FaceMatcher
}
Loading