Skip to content

Commit

Permalink
Finish implemnting search feature
Browse files Browse the repository at this point in the history
  • Loading branch information
albertusivan committed Jun 12, 2023
1 parent 55f38d9 commit d7846cc
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 47 deletions.
2 changes: 1 addition & 1 deletion app/src/main/assets/labels.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
background
c
tench
goldfish
great white shark
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/example/sabi/data/api/ApiService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ interface ApiService {
@GET("list")
suspend fun getDictonaryList(
): List<ResponseListItem>

@GET("searchWord")
suspend fun getSearchList(
@Query("word") query: String
): List<ResponseListItem>
}
11 changes: 11 additions & 0 deletions app/src/main/java/com/example/sabi/data/repository/Repository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.example.sabi.data.local.LocalDataStore
import com.example.sabi.model.ResponseListItem
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext

class Repository(private val apiService: ApiService, private val localDataStore: LocalDataStore) {

Expand All @@ -26,6 +27,16 @@ class Repository(private val apiService: ApiService, private val localDataStore:
}
}

fun searchDictonaryList(query: String): LiveData<Result<List<ResponseListItem>>> = liveData(Dispatchers.IO) {
emit(Result.Loading)
try {
val response = apiService.getSearchList(query)
emit(Result.Success(response))
} catch (e: Exception) {
emit(Result.Error(e.message.toString()))
}
}

companion object {
@Volatile
private var instance: Repository? = null
Expand Down
73 changes: 35 additions & 38 deletions app/src/main/java/com/example/sabi/ui/camera/CameraActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import android.os.HandlerThread
import android.view.Surface
import android.view.TextureView
import android.widget.ImageView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
Expand All @@ -27,30 +28,35 @@ import com.example.sabi.R
import com.example.sabi.databinding.ActivityCameraBinding
import com.example.sabi.databinding.ActivityDictonaryBinding
import com.example.sabi.ml.SsdMobilenetV11Metadata1
import com.example.sabi.ml.Sabimodel

import com.example.sabi.ui.ViewModelFactory
import com.example.sabi.ui.home.HomeActivity
import org.tensorflow.lite.DataType
import org.tensorflow.lite.support.common.FileUtil
import org.tensorflow.lite.support.image.ImageProcessor
import org.tensorflow.lite.support.image.TensorImage
import org.tensorflow.lite.support.image.ops.ResizeOp
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer

class CameraActivity : AppCompatActivity() {

lateinit var labels:List<String>
val colors = listOf<Int>(
Color.BLUE, Color.GREEN, Color.RED, Color.CYAN, Color.GRAY, Color.BLACK,
Color.DKGRAY, Color.MAGENTA, Color.YELLOW, Color.RED
)
// val colors = listOf<Int>(
// Color.BLUE, Color.GREEN, Color.RED, Color.CYAN, Color.GRAY, Color.BLACK,
// Color.DKGRAY, Color.MAGENTA, Color.YELLOW, Color.RED
// )
val paint = Paint()

lateinit var imageProcessor: ImageProcessor
lateinit var model: Sabimodel
lateinit var bitmap: Bitmap
lateinit var cameraDevice: CameraDevice
lateinit var imageView: ImageView

lateinit var handler: Handler
lateinit var cameraDevice: CameraDevice
lateinit var cameManager: CameraManager
lateinit var textureView: TextureView
lateinit var imageView: ImageView
lateinit var model: SsdMobilenetV11Metadata1
private lateinit var binding: ActivityCameraBinding

@RequiresApi(Build.VERSION_CODES.M)
Expand All @@ -61,8 +67,9 @@ class CameraActivity : AppCompatActivity() {
setContentView(binding.root)

labels = FileUtil.loadLabels(this,"labels.txt")
imageProcessor = ImageProcessor.Builder().add(ResizeOp(300,300,ResizeOp.ResizeMethod.BILINEAR)).build()
model = SsdMobilenetV11Metadata1.newInstance(this)
imageProcessor = ImageProcessor.Builder().add(ResizeOp(224,224,ResizeOp.ResizeMethod.BILINEAR)).build()
// model = SsdMobilenetV11Metadata1.newInstance(this)
model = Sabimodel.newInstance(this)
val handlerThread = HandlerThread("videoThread")
handlerThread.start()
handler = Handler(handlerThread.looper)
Expand All @@ -77,6 +84,8 @@ class CameraActivity : AppCompatActivity() {
imageView = findViewById(R.id.iv_response)
textureView = findViewById(R.id.textureView)

paint.setColor(Color.MAGENTA)

textureView.surfaceTextureListener = object:TextureView.SurfaceTextureListener{
override fun onSurfaceTextureAvailable(
surface: SurfaceTexture,
Expand All @@ -100,39 +109,34 @@ class CameraActivity : AppCompatActivity() {

override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
bitmap = textureView.bitmap!!
var tensorImage = TensorImage(DataType.FLOAT32)
tensorImage.load(bitmap)
tensorImage = imageProcessor.process(tensorImage)

var image = TensorImage.fromBitmap(bitmap)
image = imageProcessor.process(image)
val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 224, 224, 3), DataType.FLOAT32)
inputFeature0.loadBuffer(tensorImage.buffer)

val outputs = model.process(image)
val locations = outputs.locationsAsTensorBuffer.floatArray
val classes = outputs.classesAsTensorBuffer.floatArray
val scores = outputs.scoresAsTensorBuffer.floatArray
val numberOfDetections = outputs.numberOfDetectionsAsTensorBuffer.floatArray
val outputs = model.process(inputFeature0)
val outputFeature0 = outputs.outputFeature0AsTensorBuffer.floatArray

var mutable = bitmap.copy(Bitmap.Config.ARGB_8888, true)
var mutable = bitmap.copy(Bitmap.Config.ARGB_8888,true)
var canvas = Canvas(mutable)
var h = bitmap.height
var w = bitmap.width
var x = 0

val h = mutable.height
val w = mutable.width

paint.textSize= h/15f
paint.strokeWidth = h/85f

var x = 0
scores.forEachIndexed { index, fl ->
x = index
x *= 4
if(fl > 0.5){
paint.setColor(colors.get(index))
paint.style = Paint.Style.STROKE
canvas.drawRect(RectF(locations.get(x+1)*w,locations.get(x+1)*h,locations.get(x+3)*w,locations.get(x+3)*h),paint)
paint.style = Paint.Style.FILL
canvas.drawText(labels.get(classes.get(index).toInt())+" "+fl.toString(), locations.get(x+1)*w, locations.get(x)*h,paint)
while (x <= 26){
if (outputFeature0.get(x) > 0.45){
Toast.makeText(getApplicationContext(),"output: "+outputFeature0.toString(),Toast.LENGTH_SHORT).show();
}

x+=3
}

imageView.setImageBitmap(mutable)

}

}
Expand All @@ -152,13 +156,6 @@ class CameraActivity : AppCompatActivity() {
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
}
cameManager.openCamera(cameManager.cameraIdList[0],object:CameraDevice.StateCallback(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.app.ActivityOptionsCompat
Expand Down Expand Up @@ -44,8 +46,47 @@ class DictonaryActivity : AppCompatActivity() {
val intent = Intent(this@DictonaryActivity, HomeActivity::class.java)
startActivity(intent)
}
etQuery.setOnKeyListener { v, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER){
searchDictonary()
return@setOnKeyListener true
}
return@setOnKeyListener false
}
}

loadDictonary()
setContentView(binding.root)
}
@SuppressLint("NotifyDataSetChanged")
private fun setList(data: List<ResponseListItem?>) {
val adapter = DictonaryAdapter(data)
adapter.notifyDataSetChanged()
binding.rvDictonary.adapter = adapter
}

private fun searchDictonary(){
binding.apply {
val query = etQuery.text.toString()
dictonaryViewModel.getSearch(query).observe(this@DictonaryActivity){
when (it) {
is Result.Error -> showLoading(false)
is Result.Loading -> showLoading(true)
is Result.Success -> {
if(it.data.isEmpty()){
Toast.makeText(this@DictonaryActivity,"Data dictonary tidak ditemukan",Toast.LENGTH_SHORT).show();
loadDictonary()
}else{
setList(it.data)
showLoading(false)
}
}
}
}
}
}

private fun loadDictonary(){
dictonaryViewModel.getList().observe(this) {
when (it) {
is Result.Error -> showLoading(false)
Expand All @@ -56,15 +97,7 @@ class DictonaryActivity : AppCompatActivity() {
}
}
}
setContentView(binding.root)
}
@SuppressLint("NotifyDataSetChanged")
private fun setList(data: List<ResponseListItem?>) {
val adapter = DictonaryAdapter(data)
adapter.notifyDataSetChanged()
binding.rvDictonary.adapter = adapter
}

private fun showLoading(isLoading: Boolean) {
if (isLoading) {
binding.progressbar.visibility = View.VISIBLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ import com.example.sabi.data.repository.Repository

class DictonaryViewModel(private val repository: Repository) : ViewModel() {
fun getList() = repository.getDictonaryList()

fun getSearch(query: String) = repository.searchDictonaryList(query)
}
Binary file added app/src/main/ml/sabimodel.tflite
Binary file not shown.

0 comments on commit d7846cc

Please sign in to comment.