@@ -21,8 +21,8 @@ import kotlin.math.min
21
21
@Suppress(" UNNECESSARY_NOT_NULL_ASSERTION" )
22
22
internal class YoloV4Detector (
23
23
assetManager : AssetManager ,
24
- private val detectionModel : DetectionModel ,
25
- private val minimumScore : Float ,
24
+ private val mDetectionModel : DetectionModel ,
25
+ private val mMinimumScore : Float ,
26
26
) : Detector {
27
27
28
28
private companion object {
@@ -33,53 +33,50 @@ internal class YoloV4Detector(
33
33
34
34
}
35
35
36
- private val inputSize : Int = detectionModel .inputSize
36
+ private val mInputSize : Int = mDetectionModel .inputSize
37
37
38
38
// Config values.
39
- // Pre-allocated buffers.
40
- private val labels: List <String >
41
- private val interpreter: Interpreter
39
+ private val mLabels: List <String >
40
+ private val mInterpreter: Interpreter
42
41
private val mNmsThresh = 0.6f
43
42
44
- private val intValues = IntArray (inputSize * inputSize)
45
-
46
- private val byteBuffer: Array <ByteBuffer >
47
-
48
- private val outputMap: MutableMap <Int , Array <Array <FloatArray >>> = HashMap ()
43
+ // Pre-allocated buffers.
44
+ private val intValues = IntArray (mInputSize * mInputSize)
45
+ private val mByteBuffer: Array <ByteBuffer >
46
+ private val mOutputMap: MutableMap <Int , Array <Array <FloatArray >>> = HashMap ()
49
47
50
48
init {
51
-
52
- val labelsFilename = detectionModel.labelFilePath
49
+ val labelsFilename = mDetectionModel.labelFilePath
53
50
.split(" file:///android_asset/" )
54
51
.toTypedArray()[1 ]
55
52
56
- labels = assetManager.open(labelsFilename)
53
+ mLabels = assetManager.open(labelsFilename)
57
54
.use { it.readBytes() }
58
55
.decodeToString()
59
56
.trim()
60
57
.split(" \n " )
61
58
.map { it.trim() }
62
59
63
- interpreter = initializeInterpreter(assetManager)
60
+ mInterpreter = initializeInterpreter(assetManager)
64
61
65
- val numBytesPerChannel = if (detectionModel .isQuantized) {
62
+ val numBytesPerChannel = if (mDetectionModel .isQuantized) {
66
63
1 // Quantized (int8)
67
64
} else {
68
65
4 // Floating point (fp32)
69
66
}
70
67
71
68
// input size * input size * pixel count (RGB) * pixel size (int8/fp32)
72
- byteBuffer = arrayOf(
73
- ByteBuffer .allocateDirect(inputSize * inputSize * 3 * numBytesPerChannel)
69
+ mByteBuffer = arrayOf(
70
+ ByteBuffer .allocateDirect(mInputSize * mInputSize * 3 * numBytesPerChannel)
74
71
)
75
- byteBuffer [0 ].order(ByteOrder .nativeOrder())
72
+ mByteBuffer [0 ].order(ByteOrder .nativeOrder())
76
73
77
- outputMap [0 ] = arrayOf(Array (detectionModel .outputSize) { FloatArray (numBytesPerChannel) })
78
- outputMap [1 ] = arrayOf(Array (detectionModel .outputSize) { FloatArray (labels .size) })
74
+ mOutputMap [0 ] = arrayOf(Array (mDetectionModel .outputSize) { FloatArray (numBytesPerChannel) })
75
+ mOutputMap [1 ] = arrayOf(Array (mDetectionModel .outputSize) { FloatArray (mLabels .size) })
79
76
}
80
77
81
78
override fun getDetectionModel (): DetectionModel {
82
- return detectionModel
79
+ return mDetectionModel
83
80
}
84
81
85
82
override fun runDetection (bitmap : Bitmap ): List <Detection > {
@@ -105,7 +102,7 @@ internal class YoloV4Detector(
105
102
}
106
103
}
107
104
108
- return assetManager.openFd(detectionModel .modelFilename).use { fileDescriptor ->
105
+ return assetManager.openFd(mDetectionModel .modelFilename).use { fileDescriptor ->
109
106
val fileInputStream = FileInputStream (fileDescriptor.fileDescriptor)
110
107
val fileByteBuffer = fileInputStream.channel.map(
111
108
FileChannel .MapMode .READ_ONLY ,
@@ -122,36 +119,36 @@ internal class YoloV4Detector(
122
119
*/
123
120
private fun convertBitmapToByteBuffer (bitmap : Bitmap ) {
124
121
val startTime = SystemClock .uptimeMillis()
125
- val scaledBitmap = Bitmap .createScaledBitmap(bitmap, inputSize, inputSize , true )
122
+ val scaledBitmap = Bitmap .createScaledBitmap(bitmap, mInputSize, mInputSize , true )
126
123
127
- scaledBitmap.getPixels(intValues, 0 , inputSize , 0 , 0 , inputSize, inputSize )
124
+ scaledBitmap.getPixels(intValues, 0 , mInputSize , 0 , 0 , mInputSize, mInputSize )
128
125
scaledBitmap.recycle()
129
126
130
- byteBuffer [0 ].clear()
127
+ mByteBuffer [0 ].clear()
131
128
for (pixel in intValues) {
132
129
val r = (pixel and 0xFF ) / 255.0f
133
130
val g = (pixel shr 8 and 0xFF ) / 255.0f
134
131
val b = (pixel shr 16 and 0xFF ) / 255.0f
135
132
136
- byteBuffer [0 ].putFloat(r)
137
- byteBuffer [0 ].putFloat(g)
138
- byteBuffer [0 ].putFloat(b)
133
+ mByteBuffer [0 ].putFloat(r)
134
+ mByteBuffer [0 ].putFloat(g)
135
+ mByteBuffer [0 ].putFloat(b)
139
136
}
140
137
Log .v(TAG , " ByteBuffer conversion time : ${SystemClock .uptimeMillis() - startTime} ms" )
141
138
}
142
139
143
140
private fun getDetections (imageWidth : Int , imageHeight : Int ): List <Detection > {
144
- interpreter .runForMultipleInputsOutputs(byteBuffer, outputMap as Map <Int , Any >)
141
+ mInterpreter .runForMultipleInputsOutputs(mByteBuffer, mOutputMap as Map <Int , Any >)
145
142
146
- val boundingBoxes = outputMap [0 ]!! [0 ]
147
- val outScore = outputMap [1 ]!! [0 ]
143
+ val boundingBoxes = mOutputMap [0 ]!! [0 ]
144
+ val outScore = mOutputMap [1 ]!! [0 ]
148
145
149
146
return outScore.zip(boundingBoxes)
150
147
.mapIndexedNotNull { index, (classScores, boundingBoxes) ->
151
- val bestClassIndex: Int = labels .indices.maxByOrNull { classScores[it] }!!
148
+ val bestClassIndex: Int = mLabels .indices.maxByOrNull { classScores[it] }!!
152
149
val bestScore = classScores[bestClassIndex]
153
150
154
- if (bestScore <= minimumScore ) {
151
+ if (bestScore <= mMinimumScore ) {
155
152
return @mapIndexedNotNull null
156
153
}
157
154
@@ -167,8 +164,8 @@ internal class YoloV4Detector(
167
164
)
168
165
169
166
return @mapIndexedNotNull Detection (
170
- id = index.toString(),
171
- className = labels [bestClassIndex],
167
+ mId = index.toString(),
168
+ className = mLabels [bestClassIndex],
172
169
detectedClass = bestClassIndex,
173
170
score = bestScore,
174
171
boundingBox = rectF
@@ -179,7 +176,7 @@ internal class YoloV4Detector(
179
176
private fun nms (detections : List <Detection >): List <Detection > {
180
177
val nmsList: MutableList <Detection > = mutableListOf ()
181
178
182
- for (labelIndex in labels .indices) {
179
+ for (labelIndex in mLabels .indices) {
183
180
val priorityQueue = PriorityQueue <Detection >(50 )
184
181
priorityQueue.addAll(detections.filter { it.detectedClass == labelIndex })
185
182
0 commit comments