Skip to content

Commit 453a8b3

Browse files
committed
Use a lock to ensure only one segmentation is run at a time
1 parent 0c5a219 commit 453a8b3

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

app/src/androidTest/java/org/mydomain/myscan/DocumentDetectionTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import android.util.Log
2121
import androidx.test.core.app.ApplicationProvider
2222
import androidx.test.platform.app.InstrumentationRegistry
2323
import androidx.test.ext.junit.runners.AndroidJUnit4
24+
import kotlinx.coroutines.runBlocking
2425

2526
import org.junit.Test
2627
import org.junit.runner.RunWith
@@ -47,7 +48,9 @@ class DocumentDetectionTest {
4748
val bitmap = BitmapFactory.decodeStream(inputStream)
4849
var outputBitmap: Bitmap? = null
4950

50-
val segmentationResult = segmentationService.runSegmentationAndReturn(bitmap, 0)
51+
val segmentationResult = runBlocking {
52+
segmentationService.runSegmentationAndReturn(bitmap, 0)
53+
}
5154
if (segmentationResult != null) {
5255
val mask = segmentationResult.segmentation.toBinaryMask()
5356
val quad = detectDocumentQuad(mask)

app/src/main/java/org/mydomain/myscan/ImageSegmentation.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
2525
import kotlinx.coroutines.flow.StateFlow
2626
import kotlinx.coroutines.flow.asStateFlow
2727
import kotlinx.coroutines.isActive
28+
import kotlinx.coroutines.sync.Mutex
29+
import kotlinx.coroutines.sync.withLock
2830
import kotlinx.coroutines.withContext
2931
import org.tensorflow.lite.DataType
3032
import org.tensorflow.lite.Interpreter
@@ -47,6 +49,7 @@ class ImageSegmentationService(private val context: Context) {
4749
val segmentation: StateFlow<SegmentationResult?> = _segmentation.asStateFlow()
4850

4951
private var interpreter: Interpreter? = null
52+
private val inferenceLock = Mutex()
5053

5154
fun initialize() {
5255
interpreter = try {
@@ -83,18 +86,19 @@ class ImageSegmentationService(private val context: Context) {
8386
return SegmentationResult(segmentResult, inferenceTime)
8487
}
8588

86-
fun runSegmentationAndReturn(bitmap: Bitmap, rotationDegrees: Int): SegmentationResult? {
87-
if (interpreter != null) {
88-
return runSegmentation(interpreter!!, bitmap, rotationDegrees)
89+
suspend fun runSegmentationAndReturn(bitmap: Bitmap, rotationDegrees: Int): SegmentationResult? {
90+
if (interpreter == null) {
91+
return null
92+
}
93+
return inferenceLock.withLock {
94+
runSegmentation(interpreter!!, bitmap, rotationDegrees)
8995
}
90-
return null
9196
}
9297

9398
suspend fun runSegmentationAndEmit(bitmap: Bitmap, rotationDegrees: Int) {
94-
if (interpreter == null) return
9599
try {
96100
withContext(Dispatchers.IO) {
97-
val segmentationResult = runSegmentation(interpreter!!, bitmap, rotationDegrees)
101+
val segmentationResult = runSegmentationAndReturn(bitmap, rotationDegrees)
98102
if (isActive) {
99103
_segmentation.value = segmentationResult
100104
}

0 commit comments

Comments
 (0)