diff --git a/java/android/app/src/main/AndroidManifest.xml b/java/android/app/src/main/AndroidManifest.xml index aaad8ac85..bb2df4ce4 100644 --- a/java/android/app/src/main/AndroidManifest.xml +++ b/java/android/app/src/main/AndroidManifest.xml @@ -11,18 +11,18 @@ - + diff --git a/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationMainActivity.java b/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationMainActivity.java index 1b6f28774..404252814 100644 --- a/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationMainActivity.java +++ b/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationMainActivity.java @@ -1,4 +1,479 @@ package com.baidu.paddle.fastdeploy.app.examples.segmentation; -public class SegmentationMainActivity { +import static com.baidu.paddle.fastdeploy.app.ui.Utils.decodeBitmap; +import static com.baidu.paddle.fastdeploy.app.ui.Utils.getRealPathFromURI; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.baidu.paddle.fastdeploy.RuntimeOption; +import com.baidu.paddle.fastdeploy.app.examples.R; +import com.baidu.paddle.fastdeploy.app.ui.Utils; +import com.baidu.paddle.fastdeploy.app.ui.view.CameraSurfaceView; +import com.baidu.paddle.fastdeploy.app.ui.view.ResultListView; +import com.baidu.paddle.fastdeploy.app.ui.view.adapter.BaseResultAdapter; +import com.baidu.paddle.fastdeploy.app.ui.view.model.BaseResultModel; +import com.baidu.paddle.fastdeploy.vision.SegmentationResult; +import com.baidu.paddle.fastdeploy.vision.Visualize; +import com.baidu.paddle.fastdeploy.vision.segmentation.PaddleSegModel; + +import java.io.File; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public class SegmentationMainActivity extends Activity implements View.OnClickListener, CameraSurfaceView.OnTextureChangedListener { + private static final String TAG = SegmentationMainActivity.class.getSimpleName(); + + CameraSurfaceView svPreview; + TextView tvStatus; + ImageButton btnSwitch; + ImageButton btnShutter; + ImageButton btnSettings; + ImageView realtimeToggleButton; + boolean isRealtimeStatusRunning = false; + ImageView backInPreview; + private ImageView albumSelectButton; + private View cameraPageView; + private ViewGroup resultPageView; + private ImageView resultImage; + private ImageView backInResult; + private SeekBar confidenceSeekbar; + private TextView seekbarText; + private float resultNum = 1.0f; + private ResultListView detectResultView; + private Bitmap shutterBitmap; + private Bitmap originShutterBitmap; + private Bitmap picBitmap; + private Bitmap originPicBitmap; + private boolean isShutterBitmapCopied = false; + + public static final int TYPE_UNKNOWN = -1; + public static final int BTN_SHUTTER = 0; + public static final int ALBUM_SELECT = 1; + public static final int REALTIME_DETECT = 2; + private static int TYPE = REALTIME_DETECT; + + private static final int REQUEST_PERMISSION_CODE_STORAGE = 101; + private static final int INTENT_CODE_PICK_IMAGE = 100; + private static final int TIME_SLEEP_INTERVAL = 50; // ms + + String savedImagePath = "result.jpg"; + long timeElapsed = 0; + long frameCounter = 0; + + // Call 'init' and 'release' manually later + PaddleSegModel predictor = new PaddleSegModel(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Fullscreen + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + + setContentView(R.layout.segmentation_activity_main); + + // Clear all setting items to avoid app crashing due to the incorrect settings + initSettings(); + + // Init the camera preview and UI components + initView(); + + // Check and request CAMERA and WRITE_EXTERNAL_STORAGE permissions + if (!checkAllPermissions()) { + requestAllPermissions(); + } + } + + @SuppressLint("NonConstantResourceId") + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.btn_switch: + svPreview.switchCamera(); + break; + case R.id.btn_shutter: + TYPE = BTN_SHUTTER; + shutterAndPauseCamera(); + break; + case R.id.btn_settings: + startActivity(new Intent(SegmentationMainActivity.this, SegmentationSettingsActivity.class)); + break; + case R.id.realtime_toggle_btn: + toggleRealtimeStyle(); + break; + case R.id.back_in_preview: + finish(); + break; + case R.id.album_select: + TYPE = ALBUM_SELECT; + // Judge whether authority has been granted. + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + // If this permission was requested before the application but the user refused the request, this method will return true. + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE_STORAGE); + } else { + Intent intent = new Intent(Intent.ACTION_PICK); + intent.setType("image/*"); + startActivityForResult(intent, INTENT_CODE_PICK_IMAGE); + } + break; + case R.id.back_in_result: + resultPageView.setVisibility(View.GONE); + cameraPageView.setVisibility(View.VISIBLE); + TYPE = REALTIME_DETECT; + isShutterBitmapCopied = false; + svPreview.onResume(); + break; + } + } + + private void shutterAndPauseCamera() { + new Thread(new Runnable() { + @Override + public void run() { + try { + // Sleep some times to ensure picture has been correctly shut. + Thread.sleep(TIME_SLEEP_INTERVAL * 10); // 500ms + } catch (InterruptedException e) { + e.printStackTrace(); + } + runOnUiThread(new Runnable() { + @SuppressLint("SetTextI18n") + public void run() { + // These codes will run in main thread. + svPreview.onPause(); + cameraPageView.setVisibility(View.GONE); + resultPageView.setVisibility(View.VISIBLE); + seekbarText.setText(resultNum + ""); + confidenceSeekbar.setProgress((int) (resultNum * 100)); + if (shutterBitmap != null && !shutterBitmap.isRecycled()) { + resultImage.setImageBitmap(shutterBitmap); + } else { + new AlertDialog.Builder(SegmentationMainActivity.this) + .setTitle("Empty Result!") + .setMessage("Current picture is empty, please shutting it again!") + .setCancelable(true) + .show(); + } + } + }); + } + }).start(); + } + + private void copyBitmapFromCamera(Bitmap ARGB8888ImageBitmap) { + if (isShutterBitmapCopied || ARGB8888ImageBitmap == null) { + return; + } + if (!ARGB8888ImageBitmap.isRecycled()) { + synchronized (this) { + shutterBitmap = ARGB8888ImageBitmap.copy(Bitmap.Config.ARGB_8888, true); + originShutterBitmap = ARGB8888ImageBitmap.copy(Bitmap.Config.ARGB_8888, true); + } + SystemClock.sleep(TIME_SLEEP_INTERVAL); + isShutterBitmapCopied = true; + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == INTENT_CODE_PICK_IMAGE) { + if (resultCode == Activity.RESULT_OK) { + cameraPageView.setVisibility(View.GONE); + resultPageView.setVisibility(View.VISIBLE); + seekbarText.setText(resultNum + ""); + confidenceSeekbar.setProgress((int) (resultNum * 100)); + Uri uri = data.getData(); + String path = getRealPathFromURI(this, uri); + picBitmap = decodeBitmap(path, 720, 1280); + originPicBitmap = picBitmap.copy(Bitmap.Config.ARGB_8888, true); + resultImage.setImageBitmap(picBitmap); + } + } + } + + private void toggleRealtimeStyle() { + if (isRealtimeStatusRunning) { + isRealtimeStatusRunning = false; + realtimeToggleButton.setImageResource(R.drawable.realtime_stop_btn); + svPreview.setOnTextureChangedListener(this); + tvStatus.setVisibility(View.VISIBLE); + } else { + isRealtimeStatusRunning = true; + realtimeToggleButton.setImageResource(R.drawable.realtime_start_btn); + tvStatus.setVisibility(View.GONE); + // Camera is still working but detecting loop is on pause. + svPreview.setOnTextureChangedListener(new CameraSurfaceView.OnTextureChangedListener() { + @Override + public boolean onTextureChanged(Bitmap ARGB8888ImageBitmap) { + return false; + } + }); + } + } + + @Override + public boolean onTextureChanged(Bitmap ARGB8888ImageBitmap) { + if (TYPE == BTN_SHUTTER) { + copyBitmapFromCamera(ARGB8888ImageBitmap); + return false; + } + + String savedImagePath = ""; + synchronized (this) { + savedImagePath = Utils.getDCIMDirectory() + File.separator + "result.jpg"; + } + + boolean modified = false; + + long tc = System.currentTimeMillis(); + SegmentationResult result = predictor.predict(ARGB8888ImageBitmap); + timeElapsed += (System.currentTimeMillis() - tc); + + Visualize.visSegmentation(ARGB8888ImageBitmap, result); + + modified = result.initialized(); + if (!savedImagePath.isEmpty()) { + synchronized (this) { + SegmentationMainActivity.this.savedImagePath = "result.jpg"; + } + } + + frameCounter++; + if (frameCounter >= 30) { + final int fps = (int) (1000 / (timeElapsed / 30)); + runOnUiThread(new Runnable() { + @SuppressLint("SetTextI18n") + public void run() { + tvStatus.setText(Integer.toString(fps) + "fps"); + } + }); + frameCounter = 0; + timeElapsed = 0; + } + return modified; + } + + @Override + protected void onResume() { + super.onResume(); + // Reload settings and re-initialize the predictor + checkAndUpdateSettings(); + // Open camera until the permissions have been granted + if (!checkAllPermissions()) { + svPreview.disableCamera(); + } + svPreview.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + svPreview.onPause(); + } + + @Override + protected void onDestroy() { + if (predictor != null) { + predictor.release(); + } + super.onDestroy(); + } + + public void initView() { + TYPE = REALTIME_DETECT; + // For front face camera and human seg, the smaller width and height + // may get both better result and performance. EXPECTED_PREVIEW_HEIGHT + // should be 'width' and EXPECTED_PREVIEW_WIDTH should be 'height' if + // your camera display orientation is rotate (degree == 90 || degree == 270). + // The transformation will auto process in camera. + CameraSurfaceView.EXPECTED_PREVIEW_HEIGHT = 360; + CameraSurfaceView.EXPECTED_PREVIEW_WIDTH = 720; + svPreview = (CameraSurfaceView) findViewById(R.id.sv_preview); + svPreview.setOnTextureChangedListener(this); + svPreview.switchCamera(); // switch to front camera for human seg + tvStatus = (TextView) findViewById(R.id.tv_status); + btnSwitch = (ImageButton) findViewById(R.id.btn_switch); + btnSwitch.setOnClickListener(this); + btnShutter = (ImageButton) findViewById(R.id.btn_shutter); + btnShutter.setOnClickListener(this); + btnSettings = (ImageButton) findViewById(R.id.btn_settings); + btnSettings.setOnClickListener(this); + realtimeToggleButton = findViewById(R.id.realtime_toggle_btn); + realtimeToggleButton.setOnClickListener(this); + backInPreview = findViewById(R.id.back_in_preview); + backInPreview.setOnClickListener(this); + albumSelectButton = findViewById(R.id.album_select); + albumSelectButton.setOnClickListener(this); + cameraPageView = findViewById(R.id.camera_page); + resultPageView = findViewById(R.id.result_page); + resultImage = findViewById(R.id.result_image); + backInResult = findViewById(R.id.back_in_result); + backInResult.setOnClickListener(this); + confidenceSeekbar = findViewById(R.id.confidence_seekbar); + seekbarText = findViewById(R.id.seekbar_text); + detectResultView = findViewById(R.id.result_list_view); + + List results = new ArrayList<>(); + // TODO: add model results from SegmentationResult instead of using fake data. + results.add(new BaseResultModel(1, "human", 1.0f)); + results.add(new BaseResultModel(2, "human", 1.0f)); + results.add(new BaseResultModel(3, "human", 1.0f)); + final BaseResultAdapter adapter = new BaseResultAdapter(this, R.layout.facedet_result_page_item, results); + detectResultView.setAdapter(adapter); + detectResultView.invalidate(); + + confidenceSeekbar.setMax(100); + confidenceSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + float resultConfidence = seekBar.getProgress() / 100f; + BigDecimal bd = new BigDecimal(resultConfidence); + resultNum = bd.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); + seekbarText.setText(resultNum + ""); + confidenceSeekbar.setProgress((int) (resultNum * 100)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (TYPE == ALBUM_SELECT) { + SystemClock.sleep(TIME_SLEEP_INTERVAL * 10); // 500ms + if (!picBitmap.isRecycled()) { + predictor.predict(picBitmap, true, resultNum); + resultImage.setImageBitmap(picBitmap); + picBitmap = originPicBitmap.copy(Bitmap.Config.ARGB_8888, true); + } + resultNum = 1.0f; + } else { + SystemClock.sleep(TIME_SLEEP_INTERVAL * 10); // 500ms + if (!shutterBitmap.isRecycled()) { + predictor.predict(shutterBitmap, true, resultNum); + resultImage.setImageBitmap(shutterBitmap); + shutterBitmap = originShutterBitmap.copy(Bitmap.Config.ARGB_8888, true); + } + resultNum = 1.0f; + } + } + }); + } + }); + } + + @SuppressLint("ApplySharedPref") + public void initSettings() { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.clear(); + editor.commit(); + SegmentationSettingsActivity.resetSettings(); + } + + public void checkAndUpdateSettings() { + if (SegmentationSettingsActivity.checkAndUpdateSettings(this)) { + String realModelDir = getCacheDir() + "/" + SegmentationSettingsActivity.modelDir; + Utils.copyDirectoryFromAssets(this, SegmentationSettingsActivity.modelDir, realModelDir); + + String modelFile = realModelDir + "/" + "model.pdmodel"; + String paramsFile = realModelDir + "/" + "model.pdiparams"; + String configFile = realModelDir + "/" + "deploy.yaml"; + RuntimeOption option = new RuntimeOption(); + option.setCpuThreadNum(SegmentationSettingsActivity.cpuThreadNum); + option.setLitePowerMode(SegmentationSettingsActivity.cpuPowerMode); + if (Boolean.parseBoolean(SegmentationSettingsActivity.enableLiteFp16)) { + option.enableLiteFp16(); + } + predictor.init(modelFile, paramsFile, configFile, option); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) { + new AlertDialog.Builder(SegmentationMainActivity.this) + .setTitle("Permission denied") + .setMessage("Click to force quit the app, then open Settings->Apps & notifications->Target " + + "App->Permissions to grant all of the permissions.") + .setCancelable(false) + .setPositiveButton("Exit", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + SegmentationMainActivity.this.finish(); + } + }).show(); + } + } + + private void requestAllPermissions() { + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.CAMERA}, 0); + } + + private boolean checkAllPermissions() { + return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED + && ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; + } } + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationSettingsActivity.java b/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationSettingsActivity.java index 1cbc0f5cc..866c2c712 100644 --- a/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationSettingsActivity.java +++ b/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/examples/segmentation/SegmentationSettingsActivity.java @@ -1,4 +1,166 @@ package com.baidu.paddle.fastdeploy.app.examples.segmentation; -public class SegmentationSettingsActivity { +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.PreferenceManager; +import android.support.v7.app.ActionBar; + +import com.baidu.paddle.fastdeploy.app.examples.R; +import com.baidu.paddle.fastdeploy.app.ui.Utils; +import com.baidu.paddle.fastdeploy.app.ui.view.AppCompatPreferenceActivity; + +import java.util.ArrayList; +import java.util.List; + +public class SegmentationSettingsActivity extends AppCompatPreferenceActivity implements + SharedPreferences.OnSharedPreferenceChangeListener { + private static final String TAG = SegmentationSettingsActivity.class.getSimpleName(); + + static public int selectedModelIdx = -1; + static public String modelDir = ""; + static public int cpuThreadNum = 2; + static public String cpuPowerMode = ""; + static public String enableLiteFp16 = "true"; + + ListPreference lpChoosePreInstalledModel = null; + EditTextPreference etModelDir = null; + ListPreference lpCPUThreadNum = null; + ListPreference lpCPUPowerMode = null; + ListPreference lpEnableLiteFp16 = null; + + List preInstalledModelDirs = null; + List preInstalledCPUThreadNums = null; + List preInstalledCPUPowerModes = null; + List preInstalledEnableLiteFp16s = null; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.segmentation_setting); + ActionBar supportActionBar = getSupportActionBar(); + if (supportActionBar != null) { + supportActionBar.setDisplayHomeAsUpEnabled(true); + } + + // Initialize pre-installed models + preInstalledModelDirs = new ArrayList(); + preInstalledCPUThreadNums = new ArrayList(); + preInstalledCPUPowerModes = new ArrayList(); + preInstalledEnableLiteFp16s = new ArrayList(); + preInstalledModelDirs.add(getString(R.string.SEGMENTATION_MODEL_DIR_DEFAULT)); + preInstalledCPUThreadNums.add(getString(R.string.CPU_THREAD_NUM_DEFAULT)); + preInstalledCPUPowerModes.add(getString(R.string.CPU_POWER_MODE_DEFAULT)); + preInstalledEnableLiteFp16s.add(getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT)); + + // Setup UI components + lpChoosePreInstalledModel = + (ListPreference) findPreference(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY)); + String[] preInstalledModelNames = new String[preInstalledModelDirs.size()]; + for (int i = 0; i < preInstalledModelDirs.size(); i++) { + preInstalledModelNames[i] = preInstalledModelDirs.get(i).substring(preInstalledModelDirs.get(i).lastIndexOf("/") + 1); + } + lpChoosePreInstalledModel.setEntries(preInstalledModelNames); + lpChoosePreInstalledModel.setEntryValues(preInstalledModelDirs.toArray(new String[preInstalledModelDirs.size()])); + lpCPUThreadNum = (ListPreference) findPreference(getString(R.string.CPU_THREAD_NUM_KEY)); + lpCPUPowerMode = (ListPreference) findPreference(getString(R.string.CPU_POWER_MODE_KEY)); + etModelDir = (EditTextPreference) findPreference(getString(R.string.MODEL_DIR_KEY)); + etModelDir.setTitle("Model dir (SDCard: " + Utils.getSDCardDirectory() + ")"); + lpEnableLiteFp16 = (ListPreference) findPreference(getString(R.string.ENABLE_LITE_FP16_MODE_KEY)); + } + + @SuppressLint("ApplySharedPref") + private void reloadSettingsAndUpdateUI() { + SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences(); + + String selected_model_dir = sharedPreferences.getString(getString(R.string.CHOOSE_PRE_INSTALLED_MODEL_KEY), + getString(R.string.SEGMENTATION_MODEL_DIR_DEFAULT)); + int selected_model_idx = lpChoosePreInstalledModel.findIndexOfValue(selected_model_dir); + if (selected_model_idx >= 0 && selected_model_idx < preInstalledModelDirs.size() && selected_model_idx != selectedModelIdx) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(getString(R.string.MODEL_DIR_KEY), preInstalledModelDirs.get(selected_model_idx)); + editor.putString(getString(R.string.CPU_THREAD_NUM_KEY), preInstalledCPUThreadNums.get(selected_model_idx)); + editor.putString(getString(R.string.CPU_POWER_MODE_KEY), preInstalledCPUPowerModes.get(selected_model_idx)); + editor.putString(getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT), preInstalledEnableLiteFp16s.get(selected_model_idx)); + editor.commit(); + lpChoosePreInstalledModel.setSummary(selected_model_dir); + selectedModelIdx = selected_model_idx; + } + + String model_dir = sharedPreferences.getString(getString(R.string.MODEL_DIR_KEY), + getString(R.string.SEGMENTATION_MODEL_DIR_DEFAULT)); + String cpu_thread_num = sharedPreferences.getString(getString(R.string.CPU_THREAD_NUM_KEY), + getString(R.string.CPU_THREAD_NUM_DEFAULT)); + String cpu_power_mode = sharedPreferences.getString(getString(R.string.CPU_POWER_MODE_KEY), + getString(R.string.CPU_POWER_MODE_DEFAULT)); + String score_threshold = sharedPreferences.getString(getString(R.string.SCORE_THRESHOLD_KEY), + getString(R.string.SCORE_THRESHOLD_FACEDET)); + String enable_lite_fp16 = sharedPreferences.getString(getString(R.string.ENABLE_LITE_FP16_MODE_KEY), + getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT)); + + etModelDir.setSummary(model_dir); + lpCPUThreadNum.setValue(cpu_thread_num); + lpCPUThreadNum.setSummary(cpu_thread_num); + lpCPUPowerMode.setValue(cpu_power_mode); + lpCPUPowerMode.setSummary(cpu_power_mode); + lpEnableLiteFp16.setValue(enable_lite_fp16); + lpEnableLiteFp16.setSummary(enable_lite_fp16); + + } + + static boolean checkAndUpdateSettings(Context ctx) { + boolean settingsChanged = false; + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(ctx); + + String model_dir = sharedPreferences.getString(ctx.getString(R.string.MODEL_DIR_KEY), + ctx.getString(R.string.SEGMENTATION_MODEL_DIR_DEFAULT)); + settingsChanged |= !modelDir.equalsIgnoreCase(model_dir); + modelDir = model_dir; + + String cpu_thread_num = sharedPreferences.getString(ctx.getString(R.string.CPU_THREAD_NUM_KEY), + ctx.getString(R.string.CPU_THREAD_NUM_DEFAULT)); + settingsChanged |= cpuThreadNum != Integer.parseInt(cpu_thread_num); + cpuThreadNum = Integer.parseInt(cpu_thread_num); + + String cpu_power_mode = sharedPreferences.getString(ctx.getString(R.string.CPU_POWER_MODE_KEY), + ctx.getString(R.string.CPU_POWER_MODE_DEFAULT)); + settingsChanged |= !cpuPowerMode.equalsIgnoreCase(cpu_power_mode); + cpuPowerMode = cpu_power_mode; + + String enable_lite_fp16 = sharedPreferences.getString(ctx.getString(R.string.ENABLE_LITE_FP16_MODE_KEY), + ctx.getString(R.string.ENABLE_LITE_FP16_MODE_DEFAULT)); + settingsChanged |= !enableLiteFp16.equalsIgnoreCase(enable_lite_fp16); + enableLiteFp16 = enable_lite_fp16; + + return settingsChanged; + } + + static void resetSettings() { + selectedModelIdx = -1; + modelDir = ""; + cpuThreadNum = 2; + cpuPowerMode = ""; + enableLiteFp16 = "true"; + } + + @Override + protected void onResume() { + super.onResume(); + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + reloadSettingsAndUpdateUI(); + } + + @Override + protected void onPause() { + super.onPause(); + getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + reloadSettingsAndUpdateUI(); + } } diff --git a/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/ui/view/CameraSurfaceView.java b/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/ui/view/CameraSurfaceView.java index b4456e8a4..9269a4828 100644 --- a/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/ui/view/CameraSurfaceView.java +++ b/java/android/app/src/main/java/com/baidu/paddle/fastdeploy/app/ui/view/CameraSurfaceView.java @@ -30,8 +30,8 @@ public class CameraSurfaceView extends GLSurfaceView implements Renderer, SurfaceTexture.OnFrameAvailableListener { private static final String TAG = CameraSurfaceView.class.getSimpleName(); - public static final int EXPECTED_PREVIEW_WIDTH = 1280; - public static final int EXPECTED_PREVIEW_HEIGHT = 720; + public static int EXPECTED_PREVIEW_WIDTH = 1280; + public static int EXPECTED_PREVIEW_HEIGHT = 720; protected int numberOfCameras; protected int selectedCameraId; diff --git a/java/android/app/src/main/res/values/strings.xml b/java/android/app/src/main/res/values/strings.xml index b5f9cd2e8..267871056 100644 --- a/java/android/app/src/main/res/values/strings.xml +++ b/java/android/app/src/main/res/values/strings.xml @@ -35,7 +35,7 @@ models/scrfd_500m_bnkps_shape320x320_pd - models/Portrait_PP_HumanSegV2_Lite_256x144_infer + models/portrait_pp_humansegv2_lite_256x144_inference_model 拍照识别 实时识别 diff --git a/java/android/app/src/main/res/xml/segmentation_setting.xml b/java/android/app/src/main/res/xml/segmentation_setting.xml index 91082dd8f..56dd41528 100644 --- a/java/android/app/src/main/res/xml/segmentation_setting.xml +++ b/java/android/app/src/main/res/xml/segmentation_setting.xml @@ -26,10 +26,6 @@ android:negativeButtonText="@null" android:positiveButtonText="@null" android:title="CPU Power Mode" /> - FindClass( "com/baidu/paddle/fastdeploy/vision/SegmentationResult"); const jfieldID j_seg_label_map_id = env->GetFieldID( - j_seg_result_clazz, "mLabelMap", "[I"); + j_seg_result_clazz, "mLabelMap", "[B"); const jfieldID j_seg_shape_id = env->GetFieldID( j_seg_result_clazz, "mShape", "[J"); const jfieldID j_seg_contain_shape_map_id = env->GetFieldID( @@ -292,10 +292,10 @@ bool AllocateJavaSegmentationResultFromCxx( // mLabelMap int[] shape (n): [I const auto &label_map_uint8 = c_result_ptr->label_map; - std::vector label_map; // cast uint8 -> int32 - label_map.assign(label_map_uint8.begin(), label_map_uint8.end()); - jintArray j_seg_label_map_int_arr = env->NewIntArray(len); - env->SetIntArrayRegion(j_seg_label_map_int_arr, 0, len, label_map.data()); + jbyteArray j_seg_label_map_byte_arr = env->NewByteArray(len); + env->SetByteArrayRegion(j_seg_label_map_byte_arr, 0, len, + reinterpret_cast(const_cast( + label_map_uint8.data()))); // mShape long[] shape (2) (H,W): [J const auto &shape = c_result_ptr->shape; @@ -319,12 +319,13 @@ bool AllocateJavaSegmentationResultFromCxx( } // Set object fields - env->SetObjectField(j_seg_result_obj, j_seg_label_map_id, j_seg_label_map_int_arr); + env->SetObjectField(j_seg_result_obj, j_seg_label_map_id, j_seg_label_map_byte_arr); env->SetObjectField(j_seg_result_obj, j_seg_shape_id, j_seg_shape_long_arr); env->SetBooleanField(j_seg_result_obj, j_seg_initialized_id, JNI_TRUE); // Release local Refs - env->DeleteLocalRef(j_seg_label_map_int_arr); + // env->DeleteLocalRef(j_seg_label_map_int_arr); + env->DeleteLocalRef(j_seg_label_map_byte_arr); env->DeleteLocalRef(j_seg_shape_long_arr); env->DeleteLocalRef(j_seg_result_clazz); @@ -421,7 +422,6 @@ bool AllocateJavaFaceDetectionResultFromCxx( return true; } - bool AllocateJavaResultFromCxx( JNIEnv *env, jobject j_result_obj, void *cxx_result, vision::ResultType type) { @@ -825,7 +825,7 @@ bool AllocateSegmentationResultFromJava( const jclass j_seg_result_clazz_cc = env->FindClass( "com/baidu/paddle/fastdeploy/vision/SegmentationResult"); const jfieldID j_seg_label_map_id_cc = env->GetFieldID( - j_seg_result_clazz_cc, "mLabelMap", "[I"); + j_seg_result_clazz_cc, "mLabelMap", "[B"); const jfieldID j_seg_shape_id_cc = env->GetFieldID( j_seg_result_clazz_cc, "mShape", "[J"); const jfieldID j_seg_contain_shape_map_id_cc = env->GetFieldID( @@ -846,34 +846,25 @@ bool AllocateSegmentationResultFromJava( return false; } - jintArray j_seg_label_map_int_arr = reinterpret_cast( + jbyteArray j_seg_label_map_byte_arr = reinterpret_cast( env->GetObjectField(j_seg_result_obj, j_seg_label_map_id_cc)); jlongArray j_seg_shape_long_arr = reinterpret_cast( env->GetObjectField(j_seg_result_obj, j_seg_shape_id_cc)); jboolean j_seg_contain_score_map = env->GetBooleanField(j_seg_result_obj, j_seg_contain_shape_map_id_cc); - jfloatArray j_seg_score_map_float_arr = reinterpret_cast( - env->GetObjectField(j_seg_result_obj, j_seg_score_map_id_cc)); // Init cxx result c_result_ptr->Clear(); - const int label_len = env->GetArrayLength(j_seg_label_map_int_arr); // HxW + const int label_len = env->GetArrayLength(j_seg_label_map_byte_arr); // HxW const int shape_len = env->GetArrayLength(j_seg_shape_long_arr); // 2 - const int score_len = env->GetArrayLength(j_seg_score_map_float_arr); // 0 | HxW c_result_ptr->label_map.resize(label_len); c_result_ptr->shape.resize(shape_len); - if (j_seg_contain_score_map) { - c_result_ptr->contain_score_map = true; - c_result_ptr->score_map.resize(score_len); - } // mLabelMap int[] shape (n): [I - std::vector label_map_int8; // cast int32 -> uint8_t - jint *j_seg_label_map_int_ptr = - env->GetIntArrayElements(j_seg_label_map_int_arr, nullptr); - label_map_int8.assign(j_seg_label_map_int_ptr,j_seg_label_map_int_ptr + label_len); - std::memcpy(c_result_ptr->label_map.data(), label_map_int8.data(), label_len * sizeof(int)); - env->ReleaseIntArrayElements(j_seg_label_map_int_arr, j_seg_label_map_int_ptr,0); + jbyte *j_seg_label_map_byte_ptr = + env->GetByteArrayElements(j_seg_label_map_byte_arr, nullptr); + std::memcpy(c_result_ptr->label_map.data(), j_seg_label_map_byte_ptr, label_len * sizeof(jbyte)); + env->ReleaseByteArrayElements(j_seg_label_map_byte_arr, j_seg_label_map_byte_ptr,0); // mShape long[] shape (2) (H,W): [J jlong *j_seg_shape_long_ptr = @@ -883,10 +874,19 @@ bool AllocateSegmentationResultFromJava( // mScoreMap float[] shape (n): [F if (j_seg_contain_score_map) { - jfloat *j_seg_score_map_float_ptr = - env->GetFloatArrayElements(j_seg_score_map_float_arr, nullptr); - std::memcpy(c_result_ptr->score_map.data(), j_seg_score_map_float_ptr, score_len * sizeof(float)); - env->ReleaseFloatArrayElements(j_seg_score_map_float_arr, j_seg_score_map_float_ptr, 0); + jfloatArray j_seg_score_map_float_arr = reinterpret_cast( + env->GetObjectField(j_seg_result_obj, j_seg_score_map_id_cc)); + + if (j_seg_score_map_float_arr != NULL) { + const int score_len = env->GetArrayLength(j_seg_score_map_float_arr); // 0 | HxW + + c_result_ptr->contain_score_map = true; + c_result_ptr->score_map.resize(score_len); + jfloat *j_seg_score_map_float_ptr = + env->GetFloatArrayElements(j_seg_score_map_float_arr, nullptr); + std::memcpy(c_result_ptr->score_map.data(), j_seg_score_map_float_ptr, score_len * sizeof(float)); + env->ReleaseFloatArrayElements(j_seg_score_map_float_arr, j_seg_score_map_float_ptr, 0); + } } // Release local Refs diff --git a/java/android/fastdeploy/src/main/cpp/fastdeploy_jni/vision/segmentation/paddleseg_model_jni.cc b/java/android/fastdeploy/src/main/cpp/fastdeploy_jni/vision/segmentation/paddleseg_model_jni.cc index 63d9faf6e..0bdad7a4d 100644 --- a/java/android/fastdeploy/src/main/cpp/fastdeploy_jni/vision/segmentation/paddleseg_model_jni.cc +++ b/java/android/fastdeploy/src/main/cpp/fastdeploy_jni/vision/segmentation/paddleseg_model_jni.cc @@ -66,7 +66,6 @@ Java_com_baidu_paddle_fastdeploy_vision_segmentation_PaddleSegModel_predictNativ fni::RenderingSegmentation(env, c_bgr, c_result, argb8888_bitmap, save_image, weight, save_path); } - return fni::NewJavaResultFromCxx(env, reinterpret_cast(&c_result), vision::ResultType::SEGMENTATION); } diff --git a/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/SegmentationResult.java b/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/SegmentationResult.java index 0663c7330..974abeb66 100644 --- a/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/SegmentationResult.java +++ b/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/SegmentationResult.java @@ -4,7 +4,7 @@ import android.support.annotation.NonNull; public class SegmentationResult { // Init from native - public int[] mLabelMap; + public byte[] mLabelMap; public float[] mScoreMap; public long[] mShape; public boolean mContainScoreMap = false; @@ -18,7 +18,7 @@ public class SegmentationResult { return mInitialized; } - public void setLabelMap(@NonNull int[] labelMapBuffer) { + public void setLabelMap(@NonNull byte[] labelMapBuffer) { if (labelMapBuffer.length > 0) { mLabelMap = labelMapBuffer.clone(); } diff --git a/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/segmentation/PaddleSegModel.java b/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/segmentation/PaddleSegModel.java index c7c74cd6c..d2bd9f7ae 100644 --- a/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/segmentation/PaddleSegModel.java +++ b/java/android/fastdeploy/src/main/java/com/baidu/paddle/fastdeploy/vision/segmentation/PaddleSegModel.java @@ -81,7 +81,6 @@ public class PaddleSegModel { public SegmentationResult predict(Bitmap ARGB8888Bitmap, String savedImagePath, float weight) { - // scoreThreshold is for visualizing only. if (mCxxContext == 0) { return new SegmentationResult(); }