I have piece of code where I draw output from model pixel by pixel:
fun draw(
canvas: Canvas) {
val rotated = sensorOrientation % 180 == 90
var rotatedW = frameWidth;
var rotatedH = frameHeight;
if(rotated) {
rotatedW = frameHeight
rotatedH = frameWidth
}
val multiplier =
min(
canvas.height.toFloat() / rotatedH.toFloat(),
canvas.width.toFloat() / rotatedW.toFloat()
)
val w = (rotatedW * multiplier).toInt()
val h = (rotatedH * multiplier).toInt()
results?.let {
var pos: Int
val xw = w / 256f
val xh = h / 256f
val rectF = RectF()
for (y in 0 until 256) {
for (x in 0 until 256) {
pos = getIndexOfMax(results!![0][y][x])
if (pos > 0) {
val vertical = y / 256f * h
val horizontal = x / 256f * w
rectF.left = horizontal - xw
rectF.top = vertical - xh
rectF.right = horizontal + xw
rectF.bottom = vertical + xh
canvas.drawRect(rectF, boxPaint)
}
}
}
}
}
However this works really slow. Nested for
is probably one of the main issues here. I don't know how can I speed it up. As you can see both counters are necessary here because I need to get certain field from results
. I've heard that Bitmap uasage instead of Canvas
would be partial solution because I am able to get certain pixels but I don't really know how to use it right. Method draw()
is called here inside MainActivity
:
trackingOverlay.addCallback(
object : OverlayView.DrawCallback {
override fun drawCallback(canvas: Canvas?) = tracker.draw(canvas!!)
}
)
And the trackingOverlay
is an instance of OverlayView
class which inherits from View
:
class OverlayView(ctx: Context, attr: AttributeSet) : View(ctx, attr) {
private val callbacks: MutableList<DrawCallback> =
LinkedList()
fun addCallback(callback: DrawCallback) { callbacks.add(callback) }
@Synchronized
override fun draw(canvas: Canvas) {
for (callback in callbacks) {
callback.drawCallback(canvas)
}
}
interface DrawCallback {
fun drawCallback(canvas: Canvas?)
}
}
I've tried creating Bitmap
before draw (to reuse it) and then use canvas.drawBitmap()
but it needs transformation Matrix
to fill whole screen, otherwise it covers only small chunk of it and even then I haven't noticed any performance increase.
EDIT
That's how getIndexOfMax()
looks like:
private fun getIndexOfMax(array: FloatArray): Int {
if (array.isEmpty()) return -1
return when {
array[0] > array[1] -> 0
else -> 1
}
}
Results is 4 dim Array
of Float