mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-05 08:37:06 +08:00
1.Move EasyEdge Ui code to fastdeploy;
2.Add photo recognition, real-time recognition, album selection recognition, detail page display and other functions.
This commit is contained in:
@@ -15,14 +15,14 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name="com.baidu.paddle.fastdeploy.app.examples.ocr.MainActivity">
|
<activity android:name=".detection.MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="com.baidu.paddle.fastdeploy.app.examples.ocr.SettingsActivity"
|
android:name=".detection.SettingsActivity"
|
||||||
android:label="Settings">
|
android:label="Settings">
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
@@ -9,30 +9,40 @@ import android.content.DialogInterface;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.provider.MediaStore;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.baidu.paddle.fastdeploy.RuntimeOption;
|
import com.baidu.paddle.fastdeploy.RuntimeOption;
|
||||||
import com.baidu.paddle.fastdeploy.app.examples.R;
|
import com.baidu.paddle.fastdeploy.app.examples.R;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.CameraSurfaceView;
|
import com.baidu.paddle.fastdeploy.app.ui.CameraSurfaceView;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.Utils;
|
import com.baidu.paddle.fastdeploy.app.ui.view.ResultListView;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.Utils;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.adapter.DetectResultAdapter;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.model.BaseResultModel;
|
||||||
import com.baidu.paddle.fastdeploy.vision.DetectionResult;
|
import com.baidu.paddle.fastdeploy.vision.DetectionResult;
|
||||||
import com.baidu.paddle.fastdeploy.vision.detection.PicoDet;
|
import com.baidu.paddle.fastdeploy.vision.detection.PicoDet;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.text.SimpleDateFormat;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MainActivity extends Activity implements View.OnClickListener, CameraSurfaceView.OnTextureChangedListener {
|
public class MainActivity extends Activity implements View.OnClickListener, CameraSurfaceView.OnTextureChangedListener {
|
||||||
private static final String TAG = MainActivity.class.getSimpleName();
|
private static final String TAG = MainActivity.class.getSimpleName();
|
||||||
@@ -45,6 +55,25 @@ public class MainActivity extends Activity implements View.OnClickListener, Came
|
|||||||
ImageView realtimeToggleButton;
|
ImageView realtimeToggleButton;
|
||||||
boolean isRealtimeStatusRunning = false;
|
boolean isRealtimeStatusRunning = false;
|
||||||
ImageView backInPreview;
|
ImageView backInPreview;
|
||||||
|
private ImageView albumSelectButton;
|
||||||
|
private View mCameraPageView;
|
||||||
|
private ViewGroup mResultPageView;
|
||||||
|
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;
|
||||||
|
public static final int BTN_SHUTTER = 0;
|
||||||
|
public static final int ALBUM_SELECT = 1;
|
||||||
|
private static int TYPE = BTN_SHUTTER;
|
||||||
|
|
||||||
|
private static final int REQUEST_PERMISSION_CODE_STORAGE = 101;
|
||||||
|
private static final int INTENT_CODE_PICK_IMAGE = 100;
|
||||||
|
|
||||||
String savedImagePath = "result.jpg";
|
String savedImagePath = "result.jpg";
|
||||||
int lastFrameIndex = 0;
|
int lastFrameIndex = 0;
|
||||||
@@ -83,12 +112,13 @@ public class MainActivity extends Activity implements View.OnClickListener, Came
|
|||||||
svPreview.switchCamera();
|
svPreview.switchCamera();
|
||||||
break;
|
break;
|
||||||
case R.id.btn_shutter:
|
case R.id.btn_shutter:
|
||||||
@SuppressLint("SimpleDateFormat")
|
TYPE = BTN_SHUTTER;
|
||||||
SimpleDateFormat date = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
svPreview.onPause();
|
||||||
synchronized (this) {
|
mCameraPageView.setVisibility(View.GONE);
|
||||||
savedImagePath = Utils.getDCIMDirectory() + File.separator + date.format(new Date()).toString() + ".png";
|
mResultPageView.setVisibility(View.VISIBLE);
|
||||||
}
|
seekbarText.setText(resultNum + "");
|
||||||
Toast.makeText(MainActivity.this, "Save snapshot to " + savedImagePath, Toast.LENGTH_SHORT).show();
|
confidenceSeekbar.setProgress((int) (resultNum * 100));
|
||||||
|
resultImage.setImageBitmap(shutterBitmap);
|
||||||
break;
|
break;
|
||||||
case R.id.btn_settings:
|
case R.id.btn_settings:
|
||||||
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
|
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
|
||||||
@@ -99,9 +129,64 @@ public class MainActivity extends Activity implements View.OnClickListener, Came
|
|||||||
case R.id.back_in_preview:
|
case R.id.back_in_preview:
|
||||||
finish();
|
finish();
|
||||||
break;
|
break;
|
||||||
|
case R.id.albumSelect:
|
||||||
|
TYPE = ALBUM_SELECT;
|
||||||
|
// 判断是否已经赋予权限
|
||||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// 如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 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:
|
||||||
|
mResultPageView.setVisibility(View.GONE);
|
||||||
|
mCameraPageView.setVisibility(View.VISIBLE);
|
||||||
|
svPreview.onResume();
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
mCameraPageView.setVisibility(View.GONE);
|
||||||
|
mResultPageView.setVisibility(View.VISIBLE);
|
||||||
|
seekbarText.setText(resultNum + "");
|
||||||
|
confidenceSeekbar.setProgress((int) (resultNum * 100));
|
||||||
|
Uri uri = data.getData();
|
||||||
|
String path = getRealPathFromURI(uri);
|
||||||
|
picBitmap = decodeBitmap(path, 720, 1280);
|
||||||
|
originPicBitmap = picBitmap.copy(Bitmap.Config.ARGB_8888, true);
|
||||||
|
resultImage.setImageBitmap(picBitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRealPathFromURI(Uri contentURI) {
|
||||||
|
String result;
|
||||||
|
Cursor cursor = null;
|
||||||
|
try {
|
||||||
|
cursor = getContentResolver().query(contentURI, null, null, null, null);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (cursor == null) {
|
||||||
|
result = contentURI.getPath();
|
||||||
|
} else {
|
||||||
|
cursor.moveToFirst();
|
||||||
|
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
|
||||||
|
result = cursor.getString(idx);
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private void toggleRealtimeStyle() {
|
private void toggleRealtimeStyle() {
|
||||||
if (isRealtimeStatusRunning) {
|
if (isRealtimeStatusRunning) {
|
||||||
isRealtimeStatusRunning = false;
|
isRealtimeStatusRunning = false;
|
||||||
@@ -125,8 +210,10 @@ public class MainActivity extends Activity implements View.OnClickListener, Came
|
|||||||
public boolean onTextureChanged(Bitmap ARGB8888ImageBitmap) {
|
public boolean onTextureChanged(Bitmap ARGB8888ImageBitmap) {
|
||||||
String savedImagePath = "";
|
String savedImagePath = "";
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
savedImagePath = MainActivity.this.savedImagePath;
|
savedImagePath = Utils.getDCIMDirectory() + File.separator + "result.png";
|
||||||
}
|
}
|
||||||
|
shutterBitmap = ARGB8888ImageBitmap.copy(Bitmap.Config.ARGB_8888,true);
|
||||||
|
originShutterBitmap = ARGB8888ImageBitmap.copy(Bitmap.Config.ARGB_8888,true);
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
DetectionResult result = predictor.predict(
|
DetectionResult result = predictor.predict(
|
||||||
ARGB8888ImageBitmap, savedImagePath, SettingsActivity.scoreThreshold);
|
ARGB8888ImageBitmap, savedImagePath, SettingsActivity.scoreThreshold);
|
||||||
@@ -151,6 +238,38 @@ public class MainActivity extends Activity implements View.OnClickListener, Came
|
|||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param path 路径
|
||||||
|
* @param displayWidth 需要显示的宽度
|
||||||
|
* @param displayHeight 需要显示的高度
|
||||||
|
* @return Bitmap
|
||||||
|
*/
|
||||||
|
public static Bitmap decodeBitmap(String path, int displayWidth, int displayHeight) {
|
||||||
|
BitmapFactory.Options op = new BitmapFactory.Options();
|
||||||
|
op.inJustDecodeBounds = true;
|
||||||
|
// op.inJustDecodeBounds = true;表示我们只读取Bitmap的宽高等信息,不读取像素。
|
||||||
|
Bitmap bmp = BitmapFactory.decodeFile(path, op); // 获取尺寸信息
|
||||||
|
// op.outWidth表示的是图像真实的宽度
|
||||||
|
// op.inSamplySize 表示的是缩小的比例
|
||||||
|
// op.inSamplySize = 4,表示缩小1/4的宽和高,1/16的像素,android认为设置为2是最快的。
|
||||||
|
// 获取比例大小
|
||||||
|
int wRatio = (int) Math.ceil(op.outWidth / (float) displayWidth);
|
||||||
|
int hRatio = (int) Math.ceil(op.outHeight / (float) displayHeight);
|
||||||
|
// 如果超出指定大小,则缩小相应的比例
|
||||||
|
if (wRatio > 1 && hRatio > 1) {
|
||||||
|
if (wRatio > hRatio) {
|
||||||
|
// 如果太宽,我们就缩小宽度到需要的大小,注意,高度就会变得更加的小。
|
||||||
|
op.inSampleSize = wRatio;
|
||||||
|
} else {
|
||||||
|
op.inSampleSize = hRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
op.inJustDecodeBounds = false;
|
||||||
|
bmp = BitmapFactory.decodeFile(path, op);
|
||||||
|
// 从原Bitmap创建一个给定宽高的Bitmap
|
||||||
|
return Bitmap.createScaledBitmap(bmp, displayWidth, displayHeight, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
@@ -191,6 +310,63 @@ public class MainActivity extends Activity implements View.OnClickListener, Came
|
|||||||
realtimeToggleButton.setOnClickListener(this);
|
realtimeToggleButton.setOnClickListener(this);
|
||||||
backInPreview = findViewById(R.id.back_in_preview);
|
backInPreview = findViewById(R.id.back_in_preview);
|
||||||
backInPreview.setOnClickListener(this);
|
backInPreview.setOnClickListener(this);
|
||||||
|
albumSelectButton = findViewById(R.id.albumSelect);
|
||||||
|
albumSelectButton.setOnClickListener(this);
|
||||||
|
mCameraPageView = findViewById(R.id.camera_page);
|
||||||
|
mResultPageView = 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<BaseResultModel> results = new ArrayList<>();
|
||||||
|
results.add(new BaseResultModel(1, "cup", 0.4f));
|
||||||
|
results.add(new BaseResultModel(2, "pen", 0.6f));
|
||||||
|
results.add(new BaseResultModel(3, "tang", 1.0f));
|
||||||
|
final DetectResultAdapter adapter = new DetectResultAdapter(this, R.layout.result_detect_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(500);
|
||||||
|
predictor.predict(picBitmap, savedImagePath, resultNum);
|
||||||
|
resultImage.setImageBitmap(picBitmap);
|
||||||
|
picBitmap = originPicBitmap.copy(Bitmap.Config.ARGB_8888, true);
|
||||||
|
resultNum = 1.0f;
|
||||||
|
} else {
|
||||||
|
SystemClock.sleep(500);
|
||||||
|
predictor.predict(shutterBitmap, savedImagePath, resultNum);
|
||||||
|
resultImage.setImageBitmap(shutterBitmap);
|
||||||
|
shutterBitmap = originShutterBitmap.copy(Bitmap.Config.ARGB_8888, true);
|
||||||
|
resultNum = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ApplySharedPref")
|
@SuppressLint("ApplySharedPref")
|
||||||
|
@@ -11,7 +11,7 @@ import android.support.v7.app.ActionBar;
|
|||||||
|
|
||||||
import com.baidu.paddle.fastdeploy.app.examples.R;
|
import com.baidu.paddle.fastdeploy.app.examples.R;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.AppCompatPreferenceActivity;
|
import com.baidu.paddle.fastdeploy.app.ui.AppCompatPreferenceActivity;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.Utils;
|
import com.baidu.paddle.fastdeploy.app.ui.view.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -46,8 +46,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
// addPreferencesFromResource(R.xml.settings);
|
addPreferencesFromResource(R.xml.settings);
|
||||||
addPreferencesFromResource(R.xml.detection_settings);
|
|
||||||
ActionBar supportActionBar = getSupportActionBar();
|
ActionBar supportActionBar = getSupportActionBar();
|
||||||
if (supportActionBar != null) {
|
if (supportActionBar != null) {
|
||||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
|
@@ -26,7 +26,7 @@ import android.widget.Toast;
|
|||||||
import com.baidu.paddle.fastdeploy.RuntimeOption;
|
import com.baidu.paddle.fastdeploy.RuntimeOption;
|
||||||
import com.baidu.paddle.fastdeploy.app.examples.R;
|
import com.baidu.paddle.fastdeploy.app.examples.R;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.CameraSurfaceView;
|
import com.baidu.paddle.fastdeploy.app.ui.CameraSurfaceView;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.Utils;
|
import com.baidu.paddle.fastdeploy.app.ui.view.Utils;
|
||||||
import com.baidu.paddle.fastdeploy.vision.OCRResult;
|
import com.baidu.paddle.fastdeploy.vision.OCRResult;
|
||||||
import com.baidu.paddle.fastdeploy.pipeline.PPOCRv2;
|
import com.baidu.paddle.fastdeploy.pipeline.PPOCRv2;
|
||||||
import com.baidu.paddle.fastdeploy.vision.ocr.Classifier;
|
import com.baidu.paddle.fastdeploy.vision.ocr.Classifier;
|
||||||
|
@@ -11,7 +11,7 @@ import android.support.v7.app.ActionBar;
|
|||||||
|
|
||||||
import com.baidu.paddle.fastdeploy.app.examples.R;
|
import com.baidu.paddle.fastdeploy.app.examples.R;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.AppCompatPreferenceActivity;
|
import com.baidu.paddle.fastdeploy.app.ui.AppCompatPreferenceActivity;
|
||||||
import com.baidu.paddle.fastdeploy.app.ui.Utils;
|
import com.baidu.paddle.fastdeploy.app.ui.view.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@@ -15,6 +15,8 @@ import android.opengl.Matrix;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.Utils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
@@ -0,0 +1,19 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.camera;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2017/11/30.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CameraListener {
|
||||||
|
public interface CommonListener {
|
||||||
|
void onSurfaceReady();
|
||||||
|
|
||||||
|
void onSwitchCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface TakePictureListener {
|
||||||
|
void onTakenPicture(Bitmap bitmap);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,296 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.camera;
|
||||||
|
|
||||||
|
import static android.hardware.Camera.getCameraInfo;
|
||||||
|
import static android.hardware.Camera.getNumberOfCameras;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.ImageFormat;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.SurfaceTexture;
|
||||||
|
import android.graphics.YuvImage;
|
||||||
|
import android.hardware.Camera;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.util.ImageUtil;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.util.UiLog;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/4/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CameraProxy1 implements ICameraProxy {
|
||||||
|
|
||||||
|
private static final int STATUS_INIT = 0;
|
||||||
|
|
||||||
|
private static final int STATUS_OPENED = 1;
|
||||||
|
|
||||||
|
private static final int STATUS_PREVIEWING = 2;
|
||||||
|
|
||||||
|
private static final int TEXTURE_STATUS_INITED = 0;
|
||||||
|
|
||||||
|
private static final int TEXTURE_STATUS_READY = 1;
|
||||||
|
|
||||||
|
private SurfaceTexture mSurfaceTexture;
|
||||||
|
|
||||||
|
private boolean isBack = true;
|
||||||
|
|
||||||
|
private Camera mCamera;
|
||||||
|
|
||||||
|
private int status;
|
||||||
|
private int textureStatus;
|
||||||
|
|
||||||
|
private boolean hasDestoryUnexcepted = false;
|
||||||
|
|
||||||
|
private int layoutWidth;
|
||||||
|
private int layoutHeight;
|
||||||
|
|
||||||
|
private int[] previewSize = new int[2];
|
||||||
|
|
||||||
|
private CameraListener.CommonListener mCameraListener;
|
||||||
|
|
||||||
|
private int minPreviewCandidateWidth = 0;
|
||||||
|
|
||||||
|
private int previewRotation = 90;
|
||||||
|
private int displayRotation = 0;
|
||||||
|
|
||||||
|
private int previewCaptureRotation = 0;
|
||||||
|
|
||||||
|
private Camera.Parameters cameraParameters;
|
||||||
|
|
||||||
|
public CameraProxy1(int width, int height) {
|
||||||
|
layoutWidth = width;
|
||||||
|
layoutHeight = height;
|
||||||
|
status = STATUS_INIT;
|
||||||
|
textureStatus = TEXTURE_STATUS_INITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getPreviewSize() {
|
||||||
|
return previewSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Camera.Size getPreviewSize(List<Camera.Size> list) {
|
||||||
|
ArrayList validSizeList = new ArrayList<Camera.Size>();
|
||||||
|
float ratio = (float) layoutHeight / layoutWidth;
|
||||||
|
for (Camera.Size size : list) {
|
||||||
|
if ((float) size.width / size.height >= ratio && size.width > minPreviewCandidateWidth) {
|
||||||
|
validSizeList.add(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有符合条件的,直接返回第一个吧
|
||||||
|
if (validSizeList.size() == 0) {
|
||||||
|
UiLog.info("no valid preview size");
|
||||||
|
return list.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera.Size size = (Camera.Size) Collections.min(validSizeList, new Comparator<Camera.Size>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Camera.Size s1, Camera.Size s2) {
|
||||||
|
return s1.width - s2.width;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (Camera.Size) validSizeList.get(1);
|
||||||
|
// return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Camera open(boolean isOpenBack) {
|
||||||
|
int numberOfCameras = getNumberOfCameras();
|
||||||
|
UiLog.info("cameraNumber is " + numberOfCameras);
|
||||||
|
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
||||||
|
for (int i = 0; i < numberOfCameras; i++) {
|
||||||
|
getCameraInfo(i, cameraInfo);
|
||||||
|
if (isOpenBack) {
|
||||||
|
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
|
||||||
|
caculatePreviewRotation(cameraInfo);
|
||||||
|
return Camera.open(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
||||||
|
caculatePreviewRotation(cameraInfo);
|
||||||
|
return Camera.open(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// 兼容只有前置摄像头的开发板
|
||||||
|
return Camera.open(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayRotation(int degree) {
|
||||||
|
displayRotation = degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void caculatePreviewRotation(Camera.CameraInfo info) {
|
||||||
|
int degree;
|
||||||
|
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
||||||
|
degree = (info.orientation + displayRotation) % 360;
|
||||||
|
degree = (360 - degree) % 360; // compensate the mirror
|
||||||
|
previewCaptureRotation = (360 - degree) % 360;
|
||||||
|
} else { // back-facing
|
||||||
|
degree = (info.orientation - displayRotation + 360) % 360;
|
||||||
|
previewCaptureRotation = (360 + degree) % 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
previewRotation = degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startPreview() {
|
||||||
|
// MIUI上会在activity stop时destory关闭相机,触发textureview的destory方法
|
||||||
|
if (hasDestoryUnexcepted) {
|
||||||
|
openCamera();
|
||||||
|
}
|
||||||
|
// 如果已经TextureAvailable,设置texture并且预览,(必须先调用了openCamera)
|
||||||
|
if (textureStatus == TEXTURE_STATUS_READY) {
|
||||||
|
try {
|
||||||
|
mCamera.setPreviewTexture(mSurfaceTexture);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
mCamera.startPreview();
|
||||||
|
mCamera.setPreviewCallback(mPreviewCallback);
|
||||||
|
status = STATUS_PREVIEWING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumePreview() {
|
||||||
|
mCamera.startPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] currentFrameData;
|
||||||
|
|
||||||
|
private Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {
|
||||||
|
@Override
|
||||||
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||||
|
// 在某些机型和某项项目中,某些帧的data的数据不符合nv21的格式,需要过滤,否则后续处理会导致crash
|
||||||
|
if (data.length != cameraParameters.getPreviewSize().width
|
||||||
|
* cameraParameters.getPreviewSize().height * 1.5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentFrameData = data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void openCamera() {
|
||||||
|
mCamera = open(isBack);
|
||||||
|
cameraParameters = mCamera.getParameters();
|
||||||
|
Camera.Size previewSize = cameraParameters.getPreviewSize();
|
||||||
|
List<Camera.Size> supportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
|
||||||
|
Camera.Size size = getPreviewSize(supportedPreviewSizes);
|
||||||
|
if (previewRotation == 90 || previewRotation == 270) {
|
||||||
|
this.previewSize[0] = size.height;
|
||||||
|
this.previewSize[1] = size.width;
|
||||||
|
} else {
|
||||||
|
this.previewSize[0] = size.width;
|
||||||
|
this.previewSize[1] = size.height;
|
||||||
|
}
|
||||||
|
previewSize.height = size.height;
|
||||||
|
if (isBack && cameraParameters.getSupportedFocusModes().contains(
|
||||||
|
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
|
||||||
|
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
|
||||||
|
}
|
||||||
|
cameraParameters.setPreviewSize(size.width, size.height);
|
||||||
|
mCamera.setDisplayOrientation(previewRotation);
|
||||||
|
mCamera.setParameters(cameraParameters);
|
||||||
|
status = STATUS_OPENED;
|
||||||
|
if (mCameraListener != null) {
|
||||||
|
mCameraListener.onSwitchCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeCamera() {
|
||||||
|
stopPreview();
|
||||||
|
mCamera.setPreviewCallback(null);
|
||||||
|
mCamera.release();
|
||||||
|
mCamera = null;
|
||||||
|
status = STATUS_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopPreview() {
|
||||||
|
|
||||||
|
mCamera.stopPreview();
|
||||||
|
mCamera.setPreviewCallback(null);
|
||||||
|
status = STATUS_OPENED;
|
||||||
|
Log.e("literrr", "stoped");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void switchSide() {
|
||||||
|
isBack = !isBack;
|
||||||
|
stopPreview();
|
||||||
|
closeCamera();
|
||||||
|
openCamera();
|
||||||
|
startPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap convertPreviewDataToBitmap(byte[] data) {
|
||||||
|
Camera.Size size = cameraParameters.getPreviewSize();
|
||||||
|
YuvImage img = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
|
||||||
|
ByteArrayOutputStream os = null;
|
||||||
|
os = new ByteArrayOutputStream(data.length);
|
||||||
|
img.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, os);
|
||||||
|
byte[] jpeg = os.toByteArray();
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length);
|
||||||
|
Bitmap bitmapRotate;
|
||||||
|
if (isBack) {
|
||||||
|
bitmapRotate = ImageUtil.createRotateBitmap(bitmap, previewCaptureRotation);
|
||||||
|
} else {
|
||||||
|
bitmapRotate = ImageUtil.createMirrorRotateBitmap(bitmap, previewCaptureRotation);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
os.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
UiLog.info("convertPreviewDataToBitmap close bitmap");
|
||||||
|
}
|
||||||
|
return bitmapRotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void takePicture(CameraListener.TakePictureListener listener) {
|
||||||
|
if (currentFrameData != null) {
|
||||||
|
Bitmap bitmap = convertPreviewDataToBitmap(currentFrameData);
|
||||||
|
listener.onTakenPicture(bitmap);
|
||||||
|
UiLog.info("convert bitmap success");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEventListener(CameraListener.CommonListener listener) {
|
||||||
|
mCameraListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||||
|
mSurfaceTexture = surface;
|
||||||
|
textureStatus = TEXTURE_STATUS_READY;
|
||||||
|
mCameraListener.onSurfaceReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||||
|
hasDestoryUnexcepted = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.camera;
|
||||||
|
|
||||||
|
import android.view.TextureView;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2017/3/29.
|
||||||
|
*/
|
||||||
|
public interface ICameraProxy extends TextureView.SurfaceTextureListener {
|
||||||
|
void openCamera();
|
||||||
|
|
||||||
|
void setDisplayRotation(int degree);
|
||||||
|
|
||||||
|
void startPreview();
|
||||||
|
|
||||||
|
void stopPreview();
|
||||||
|
|
||||||
|
void closeCamera();
|
||||||
|
|
||||||
|
void switchSide();
|
||||||
|
|
||||||
|
int[] getPreviewSize();
|
||||||
|
|
||||||
|
void takePicture(CameraListener.TakePictureListener listener);
|
||||||
|
|
||||||
|
void setEventListener(CameraListener.CommonListener commonListener);
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package com.baidu.paddle.fastdeploy.app.ui;
|
package com.baidu.paddle.fastdeploy.app.ui.layout;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
@@ -0,0 +1,37 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.layout;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OperationFrameLayout extends RelativeLayout {
|
||||||
|
private int layoutHeight = 360;
|
||||||
|
|
||||||
|
public OperationFrameLayout(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
int width = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
setMeasuredDimension(width, layoutHeight);
|
||||||
|
setBackgroundColor(Color.BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,155 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.util;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.media.ExifInterface;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ImageUtil {
|
||||||
|
private static final String TAG = "CameraExif";
|
||||||
|
|
||||||
|
public static Bitmap createRotateBitmap(Bitmap bitmap, int rotation) {
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.postRotate(rotation);
|
||||||
|
return Bitmap.createBitmap(
|
||||||
|
bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap createMirrorRotateBitmap(Bitmap bitmap, int rotation) {
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.postRotate(rotation);
|
||||||
|
matrix.postScale(-1, 1);
|
||||||
|
return Bitmap.createBitmap(
|
||||||
|
bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int exifToDegrees(int exifOrientation) {
|
||||||
|
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
|
||||||
|
return 90;
|
||||||
|
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
|
||||||
|
return 180;
|
||||||
|
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
|
||||||
|
return 270;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
|
||||||
|
public static int getOrientation(byte[] jpeg) {
|
||||||
|
if (jpeg == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
// ISO/IEC 10918-1:1993(E)
|
||||||
|
while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
|
||||||
|
int marker = jpeg[offset] & 0xFF;
|
||||||
|
|
||||||
|
// Check if the marker is a padding.
|
||||||
|
if (marker == 0xFF) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
// Check if the marker is SOI or TEM.
|
||||||
|
if (marker == 0xD8 || marker == 0x01) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Check if the marker is EOI or SOS.
|
||||||
|
if (marker == 0xD9 || marker == 0xDA) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the length and check if it is reasonable.
|
||||||
|
length = pack(jpeg, offset, 2, false);
|
||||||
|
if (length < 2 || offset + length > jpeg.length) {
|
||||||
|
Log.e(TAG, "Invalid length");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break if the marker is EXIF in APP1.
|
||||||
|
if (marker == 0xE1 && length >= 8
|
||||||
|
&& pack(jpeg, offset + 2, 4, false) == 0x45786966
|
||||||
|
&& pack(jpeg, offset + 6, 2, false) == 0) {
|
||||||
|
offset += 8;
|
||||||
|
length -= 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip other markers.
|
||||||
|
offset += length;
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JEITA CP-3451 Exif Version 2.2
|
||||||
|
if (length > 8) {
|
||||||
|
// Identify the byte order.
|
||||||
|
int tag = pack(jpeg, offset, 4, false);
|
||||||
|
if (tag != 0x49492A00 && tag != 0x4D4D002A) {
|
||||||
|
Log.e(TAG, "Invalid byte order");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
boolean littleEndian = (tag == 0x49492A00);
|
||||||
|
|
||||||
|
// Get the offset and check if it is reasonable.
|
||||||
|
int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
|
||||||
|
if (count < 10 || count > length) {
|
||||||
|
Log.e(TAG, "Invalid offset");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
offset += count;
|
||||||
|
length -= count;
|
||||||
|
|
||||||
|
// Get the count and go through all the elements.
|
||||||
|
count = pack(jpeg, offset - 2, 2, littleEndian);
|
||||||
|
while (count-- > 0 && length >= 12) {
|
||||||
|
// Get the tag and check if it is orientation.
|
||||||
|
tag = pack(jpeg, offset, 2, littleEndian);
|
||||||
|
if (tag == 0x0112) {
|
||||||
|
// We do not really care about type and count, do we?
|
||||||
|
int orientation = pack(jpeg, offset + 8, 2, littleEndian);
|
||||||
|
switch (orientation) {
|
||||||
|
case 1:
|
||||||
|
return 0;
|
||||||
|
case 3:
|
||||||
|
return 180;
|
||||||
|
case 6:
|
||||||
|
return 90;
|
||||||
|
case 8:
|
||||||
|
return 270;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += 12;
|
||||||
|
length -= 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "Orientation not found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int pack(byte[] bytes, int offset, int length,
|
||||||
|
boolean littleEndian) {
|
||||||
|
int step = 1;
|
||||||
|
if (littleEndian) {
|
||||||
|
offset += length - 1;
|
||||||
|
step = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = 0;
|
||||||
|
while (length-- > 0) {
|
||||||
|
value = (value << 8) | (bytes[offset] & 0xFF);
|
||||||
|
offset += step;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.util;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/24.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StringUtil {
|
||||||
|
public static String formatFloatString(float number) {
|
||||||
|
DecimalFormat df = new DecimalFormat("0.00");
|
||||||
|
return df.format(number);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package com.baidu.paddle.fastdeploy.app.ui.util;
|
||||||
|
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class ThreadPoolManager {
|
||||||
|
|
||||||
|
static Timer timerFocus = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 对焦频率
|
||||||
|
*/
|
||||||
|
static final long cameraScanInterval = 2000;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 线程池大小
|
||||||
|
*/
|
||||||
|
private static int poolCount = Runtime.getRuntime().availableProcessors();
|
||||||
|
|
||||||
|
private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(poolCount);
|
||||||
|
|
||||||
|
private static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给线程池添加任务
|
||||||
|
*
|
||||||
|
* @param runnable 任务
|
||||||
|
*/
|
||||||
|
public static void execute(Runnable runnable) {
|
||||||
|
fixedThreadPool.execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单独线程任务
|
||||||
|
*
|
||||||
|
* @param runnable 任务
|
||||||
|
*/
|
||||||
|
public static void executeSingle(Runnable runnable) {
|
||||||
|
singleThreadPool.execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个定时对焦的timer任务
|
||||||
|
*
|
||||||
|
* @param runnable 对焦代码
|
||||||
|
* @return Timer Timer对象,用来终止自动对焦
|
||||||
|
*/
|
||||||
|
public static Timer createAutoFocusTimerTask(final Runnable runnable) {
|
||||||
|
if (timerFocus != null) {
|
||||||
|
return timerFocus;
|
||||||
|
}
|
||||||
|
timerFocus = new Timer();
|
||||||
|
TimerTask task = new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timerFocus.scheduleAtFixedRate(task, 0, cameraScanInterval);
|
||||||
|
return timerFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终止自动对焦任务,实际调用了cancel方法并且清空对象
|
||||||
|
* 但是无法终止执行中的任务,需额外处理
|
||||||
|
*/
|
||||||
|
public static void cancelAutoFocusTimer() {
|
||||||
|
if (timerFocus != null) {
|
||||||
|
timerFocus.cancel();
|
||||||
|
timerFocus = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,15 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.util;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/4.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class UiLog {
|
||||||
|
private static final String TAG = "edge_log";
|
||||||
|
|
||||||
|
public static void info(String log) {
|
||||||
|
Log.i(TAG, log);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,162 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.baidu.paddle.fastdeploy.app.examples.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/7.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PreviewDecoratorView extends View {
|
||||||
|
|
||||||
|
static final String RUNNING_HINT_TEXT = "对准识别物体,自动识别物体";
|
||||||
|
|
||||||
|
static final String STOP_HINT_TEXT = "已暂定实时识别,请点击下方按钮开启";
|
||||||
|
|
||||||
|
private String hintText = STOP_HINT_TEXT;
|
||||||
|
|
||||||
|
public PreviewDecoratorView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewDecoratorView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewDecoratorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(boolean isRunning) {
|
||||||
|
if (isRunning) {
|
||||||
|
hintText = RUNNING_HINT_TEXT;
|
||||||
|
} else {
|
||||||
|
hintText = STOP_HINT_TEXT;
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
int offset = 50;
|
||||||
|
int offsetBottom = 170;
|
||||||
|
int stokeWidth = 15;
|
||||||
|
int extendOffset = stokeWidth / 2;
|
||||||
|
int height = getHeight();
|
||||||
|
int width = getWidth();
|
||||||
|
int barSize = 40;
|
||||||
|
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
|
||||||
|
Paint paintBar = new Paint();
|
||||||
|
paintBar.setColor(Color.WHITE);
|
||||||
|
paintBar.setStrokeWidth(stokeWidth);
|
||||||
|
paintBar.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
|
|
||||||
|
Point leftTop = new Point(offset, offset);
|
||||||
|
Point rightTop = new Point(width - offset, offset);
|
||||||
|
Point leftBottom = new Point(offset, height - offsetBottom);
|
||||||
|
Point rightBottom = new Point(width - offset, height - offsetBottom);
|
||||||
|
|
||||||
|
|
||||||
|
Path path = new Path();
|
||||||
|
path.moveTo(leftTop.x, leftTop.y + barSize);
|
||||||
|
path.lineTo(leftTop.x, leftTop.y);
|
||||||
|
path.lineTo(leftTop.x + barSize, leftTop.y);
|
||||||
|
|
||||||
|
path.moveTo(rightTop.x - barSize, leftTop.y);
|
||||||
|
path.lineTo(rightTop.x, rightTop.y);
|
||||||
|
path.lineTo(rightTop.x, rightTop.y + barSize);
|
||||||
|
|
||||||
|
path.moveTo(leftBottom.x, leftBottom.y - barSize);
|
||||||
|
path.lineTo(leftBottom.x, leftBottom.y);
|
||||||
|
path.lineTo(leftBottom.x + barSize, leftBottom.y);
|
||||||
|
|
||||||
|
path.moveTo(rightBottom.x - barSize, rightBottom.y);
|
||||||
|
path.lineTo(rightBottom.x, rightBottom.y);
|
||||||
|
path.lineTo(rightBottom.x, rightBottom.y - barSize);
|
||||||
|
|
||||||
|
|
||||||
|
// 绘制半透明遮罩
|
||||||
|
Rect rect = new Rect(0, 0, width, height);
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setColor(Color.BLACK);
|
||||||
|
paint.setAlpha(50);
|
||||||
|
canvas.drawRect(rect, paint);
|
||||||
|
|
||||||
|
// 擦除可见部分半透明遮罩
|
||||||
|
rect = new Rect(leftTop.x - extendOffset, leftTop.y - extendOffset,
|
||||||
|
rightBottom.x + extendOffset, rightBottom.y + extendOffset);
|
||||||
|
canvas.clipRect(rect);
|
||||||
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||||
|
|
||||||
|
// 绘制四个小角
|
||||||
|
canvas.drawPath(path, paintBar);
|
||||||
|
canvas.restore();
|
||||||
|
// 设置留给hint的位置
|
||||||
|
rect = new Rect(0, rightBottom.y + extendOffset, width, height);
|
||||||
|
|
||||||
|
drawHint(canvas, rect, hintText);
|
||||||
|
|
||||||
|
super.onDraw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawHint(Canvas canvas, Rect rect, String text) {
|
||||||
|
int textSizePx = 16;
|
||||||
|
int imageSizePx = 48;
|
||||||
|
int padInTextAndIcon = 22;
|
||||||
|
Paint textPaint = new Paint();
|
||||||
|
textPaint.setTextSize(textSizePx);
|
||||||
|
textPaint.setColor(Color.WHITE);
|
||||||
|
textPaint.setTextAlign(Paint.Align.LEFT);
|
||||||
|
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.scan_icon);
|
||||||
|
|
||||||
|
float textWidth = getTextWidth(this.getContext(), text, textPaint, textSizePx);
|
||||||
|
int width = padInTextAndIcon + imageSizePx + (int) textWidth;
|
||||||
|
int height = imageSizePx;
|
||||||
|
|
||||||
|
int startX = rect.left + (rect.width() - width) / 2;
|
||||||
|
int startY = rect.top + (rect.height() - height) / 2;
|
||||||
|
|
||||||
|
Rect srcRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||||
|
Rect destRect = new Rect(startX, startY, startX + imageSizePx, startY + imageSizePx);
|
||||||
|
|
||||||
|
Paint mBitPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
mBitPaint.setFilterBitmap(true);
|
||||||
|
mBitPaint.setDither(true);
|
||||||
|
canvas.drawBitmap(bitmap, srcRect, destRect, mBitPaint);
|
||||||
|
|
||||||
|
startX += padInTextAndIcon + imageSizePx;
|
||||||
|
|
||||||
|
canvas.drawText(text, startX, startY + textSizePx + 23, textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTextWidth(Context context, String text, Paint paint, int textSize) {
|
||||||
|
float scaledDensity = getResources().getDisplayMetrics().scaledDensity;
|
||||||
|
paint.setTextSize(scaledDensity * textSize);
|
||||||
|
return paint.measureText(text);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,144 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.TextureView;
|
||||||
|
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.camera.CameraListener;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.camera.CameraProxy1;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.camera.ICameraProxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PreviewView extends TextureView {
|
||||||
|
ICameraProxy mCameraProxy;
|
||||||
|
private int layoutWidth;
|
||||||
|
private int layoutHeight;
|
||||||
|
private int actualHeight;
|
||||||
|
private int cropHeight;
|
||||||
|
|
||||||
|
public PreviewView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreviewView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动调用开始预览
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
if (mCameraProxy != null) {
|
||||||
|
mCameraProxy.startPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放摄像头
|
||||||
|
*/
|
||||||
|
public void destory() {
|
||||||
|
if (mCameraProxy != null) {
|
||||||
|
mCameraProxy.closeCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动停止
|
||||||
|
*/
|
||||||
|
public void stopPreview() {
|
||||||
|
mCameraProxy.stopPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置实际可见layout的长宽
|
||||||
|
*/
|
||||||
|
public void setLayoutSize(int width, int height) {
|
||||||
|
layoutWidth = width;
|
||||||
|
layoutHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void takePicture(final CameraListener.TakePictureListener listener) {
|
||||||
|
// 裁剪图片
|
||||||
|
mCameraProxy.takePicture(new CameraListener.TakePictureListener() {
|
||||||
|
@Override
|
||||||
|
public void onTakenPicture(Bitmap bitmap) {
|
||||||
|
Bitmap cropBitmap = Bitmap.createBitmap(bitmap, 0, 0,
|
||||||
|
bitmap.getWidth(), cropHeight);
|
||||||
|
listener.onTakenPicture(cropBitmap);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换摄像头面
|
||||||
|
*/
|
||||||
|
public void switchSide() {
|
||||||
|
mCameraProxy.switchSide();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActualHeight() {
|
||||||
|
return actualHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDisplayDegree() {
|
||||||
|
int rotation = ((Activity) this.getContext()).getWindowManager().getDefaultDisplay()
|
||||||
|
.getRotation();
|
||||||
|
int degrees = 0;
|
||||||
|
switch (rotation) {
|
||||||
|
case Surface.ROTATION_0:
|
||||||
|
degrees = 0;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_90:
|
||||||
|
degrees = 90;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_180:
|
||||||
|
degrees = 180;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_270:
|
||||||
|
degrees = 270;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
degrees = 0;
|
||||||
|
}
|
||||||
|
mCameraProxy.setDisplayRotation(degrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshCropHeight() {
|
||||||
|
int[] size = mCameraProxy.getPreviewSize();
|
||||||
|
actualHeight = (int) (((float) size[1] / size[0]) * layoutWidth);
|
||||||
|
cropHeight = (int) (((float) layoutHeight / layoutWidth) * size[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
if (mCameraProxy == null) {
|
||||||
|
mCameraProxy = new CameraProxy1(layoutWidth, layoutHeight);
|
||||||
|
setDisplayDegree();
|
||||||
|
setSurfaceTextureListener(mCameraProxy);
|
||||||
|
mCameraProxy.openCamera();
|
||||||
|
refreshCropHeight();
|
||||||
|
mCameraProxy.setEventListener(new CameraListener.CommonListener() {
|
||||||
|
@Override
|
||||||
|
public void onSurfaceReady() {
|
||||||
|
mCameraProxy.startPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwitchCamera() {
|
||||||
|
refreshCropHeight();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,47 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/14.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ResultListView extends ListView {
|
||||||
|
public ResultListView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultListView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultListView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Handler handler;
|
||||||
|
|
||||||
|
public void setHandler(Handler mHandler) {
|
||||||
|
handler = mHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
removeAllViewsInLayout();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
|
||||||
|
MeasureSpec.AT_MOST);
|
||||||
|
super.onMeasure(widthMeasureSpec, expandSpec);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,381 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.util.StringUtil;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.model.BasePolygonResultModel;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.model.PoseViewResultModel;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/15.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ResultMaskView extends View {
|
||||||
|
private static final int[][] COLOR_MAP_DEF = {
|
||||||
|
{0, 0, 0},
|
||||||
|
{244, 35, 232},
|
||||||
|
{70, 70, 70},
|
||||||
|
{102, 102, 156},
|
||||||
|
{190, 153, 153},
|
||||||
|
{153, 153, 153},
|
||||||
|
{250, 170, 30},
|
||||||
|
{220, 220, 0},
|
||||||
|
{107, 142, 35},
|
||||||
|
{152, 251, 152},
|
||||||
|
{70, 130, 180},
|
||||||
|
{220, 20, 60},
|
||||||
|
{255, 0, 0},
|
||||||
|
{0, 0, 142},
|
||||||
|
{0, 0, 70},
|
||||||
|
{0, 60, 100},
|
||||||
|
{0, 80, 100},
|
||||||
|
{0, 0, 230},
|
||||||
|
{119, 11, 32},
|
||||||
|
{128, 64, 128}
|
||||||
|
};
|
||||||
|
|
||||||
|
private float sizeRatio;
|
||||||
|
private List<BasePolygonResultModel> mResultModelList;
|
||||||
|
private Point originPt = new Point();
|
||||||
|
private int imgWidth;
|
||||||
|
private int imgHeight;
|
||||||
|
private Paint textPaint;
|
||||||
|
|
||||||
|
private Handler handler;
|
||||||
|
|
||||||
|
public void setHandler(Handler mHandler) {
|
||||||
|
handler = mHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultMaskView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer, Paint> paintFixPool = new HashMap<>();
|
||||||
|
|
||||||
|
public ResultMaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPolygonListInfo(List<BasePolygonResultModel> modelList, int width, int height) {
|
||||||
|
imgWidth = width;
|
||||||
|
imgHeight = height;
|
||||||
|
mResultModelList = modelList;
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
mResultModelList = null;
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preCaculate() {
|
||||||
|
float ratio = (float) getMeasuredWidth() / (float) getMeasuredHeight();
|
||||||
|
float ratioBitmap = (float) imgWidth / (float) imgHeight;
|
||||||
|
// | |#####| |模式
|
||||||
|
if (ratioBitmap < ratio) {
|
||||||
|
sizeRatio = (float) getMeasuredHeight() / (float) imgHeight;
|
||||||
|
int x = (int) (getMeasuredWidth() - sizeRatio * imgWidth) / 2;
|
||||||
|
originPt.set(x, 0);
|
||||||
|
} else {
|
||||||
|
// ------------
|
||||||
|
//
|
||||||
|
// ------------
|
||||||
|
// ############
|
||||||
|
// ------------
|
||||||
|
//
|
||||||
|
// ------------
|
||||||
|
sizeRatio = (float) getMeasuredWidth() / (float) imgWidth;
|
||||||
|
int y = (int) (getMeasuredHeight() - sizeRatio * imgHeight) / 2;
|
||||||
|
originPt.set(0, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer, Paint> paintRandomPool = new HashMap<>();
|
||||||
|
|
||||||
|
public ResultMaskView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
textPaint = new Paint();
|
||||||
|
textPaint.setTextSize(30);
|
||||||
|
textPaint.setARGB(255, 255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Paint getRandomMaskPaint(int index) {
|
||||||
|
if (paintRandomPool.containsKey(index)) {
|
||||||
|
|
||||||
|
return paintRandomPool.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] seed = new int[3];
|
||||||
|
int offset = index % 3;
|
||||||
|
seed[offset] = 255;
|
||||||
|
|
||||||
|
Paint paint = new Paint();
|
||||||
|
Random rnd = new Random();
|
||||||
|
paint.setARGB(170,
|
||||||
|
(rnd.nextInt(255) + seed[0]) / 2,
|
||||||
|
(rnd.nextInt(255) + seed[1]) / 2,
|
||||||
|
(rnd.nextInt(255) + seed[2]) / 2);
|
||||||
|
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
|
||||||
|
paintRandomPool.put(index, paint);
|
||||||
|
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Paint getFixColorPaint(int colorId) {
|
||||||
|
|
||||||
|
// float alpha = 90;
|
||||||
|
String[] colors = {"#FF0000", "#FF0000", "#00FF00", "#0000FF", "#FF00FF"};
|
||||||
|
int index = colorId % colors.length;
|
||||||
|
if (paintFixPool.containsKey(index)) {
|
||||||
|
return paintFixPool.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int color = Color.parseColor(colors[index]);
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setColor(color);
|
||||||
|
//paint.setAlpha(90);
|
||||||
|
paintFixPool.put(index, paint);
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
// 实时识别的时候第一次渲染
|
||||||
|
if (mResultModelList == null) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
preCaculate();
|
||||||
|
|
||||||
|
int stokeWidth = 5;
|
||||||
|
|
||||||
|
int fontSize = 38;
|
||||||
|
int labelPadding = 5;
|
||||||
|
int labelHeight = 46 + 2 * labelPadding;
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setColor(Color.parseColor("#3B85F5"));
|
||||||
|
paint.setStrokeWidth(stokeWidth);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
|
Paint paintFillAlpha = new Paint();
|
||||||
|
paintFillAlpha.setStyle(Paint.Style.FILL);
|
||||||
|
paintFillAlpha.setColor(Color.parseColor("#3B85F5"));
|
||||||
|
paintFillAlpha.setAlpha(50);
|
||||||
|
|
||||||
|
Paint paintFill = new Paint();
|
||||||
|
paintFill.setStyle(Paint.Style.FILL);
|
||||||
|
paintFill.setColor(Color.parseColor("#3B85F5"));
|
||||||
|
|
||||||
|
Paint paintText = new Paint();
|
||||||
|
paintText.setColor(Color.WHITE);
|
||||||
|
paintText.setTextAlign(Paint.Align.LEFT);
|
||||||
|
paintText.setTextSize(fontSize);
|
||||||
|
DecimalFormat df = new DecimalFormat("0.00");
|
||||||
|
|
||||||
|
|
||||||
|
List<Float> points;
|
||||||
|
for (int i = 0; i < mResultModelList.size(); i++) {
|
||||||
|
|
||||||
|
BasePolygonResultModel model = mResultModelList.get(i);
|
||||||
|
Path path = new Path();
|
||||||
|
List<Point> polygon = model.getBounds(sizeRatio, originPt);
|
||||||
|
|
||||||
|
path.moveTo(polygon.get(0).x, polygon.get(0).y);
|
||||||
|
for (int j = 1; j < polygon.size(); j++) {
|
||||||
|
path.lineTo(polygon.get(j).x, polygon.get(j).y);
|
||||||
|
}
|
||||||
|
path.close();
|
||||||
|
|
||||||
|
if (model.isDrawPoints()) {
|
||||||
|
Paint paintFillPoint = new Paint();
|
||||||
|
paintFillPoint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
|
||||||
|
paintFillPoint.setColor(Color.YELLOW);
|
||||||
|
List<Point> polygonPoints = model.getBounds(sizeRatio, originPt);
|
||||||
|
for (Point p : polygonPoints) {
|
||||||
|
canvas.drawCircle(p.x, p.y, 10 * sizeRatio, paintFillPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制框
|
||||||
|
if (!model.isHasMask()) {
|
||||||
|
if (model instanceof PoseViewResultModel && model.isHasGroupColor()) {
|
||||||
|
paint = getFixColorPaint(model.getColorId());
|
||||||
|
paint.setStrokeWidth(stokeWidth);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setAlpha(90);
|
||||||
|
}
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
canvas.drawPath(path, paintFillAlpha);
|
||||||
|
if (model.isRect()) {
|
||||||
|
Rect rect = model.getRect(sizeRatio, originPt);
|
||||||
|
canvas.drawRect(new Rect(rect.left, rect.top, rect.right,
|
||||||
|
rect.top + labelHeight), paintFill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (model.isRect()) {
|
||||||
|
Rect rect = model.getRect(sizeRatio, originPt);
|
||||||
|
canvas.drawText(model.getName() + " " + StringUtil.formatFloatString(model.getConfidence()),
|
||||||
|
rect.left + labelPadding,
|
||||||
|
rect.top + fontSize + labelPadding, paintText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.isTextOverlay()) {
|
||||||
|
canvas.drawText(model.getName(),
|
||||||
|
polygon.get(0).x, polygon.get(0).y, textPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制mask
|
||||||
|
if (model.isHasMask()) {
|
||||||
|
if (!model.isSemanticMask()) {
|
||||||
|
// 实例分割绘制
|
||||||
|
Paint paintMask = getRandomMaskPaint(model.getColorId());
|
||||||
|
points = new ArrayList<>();
|
||||||
|
byte[] maskData = model.getMask();
|
||||||
|
|
||||||
|
for (int w = 0; w < imgWidth * sizeRatio; w++) {
|
||||||
|
for (int h = 0; h < imgHeight * sizeRatio; h++) {
|
||||||
|
|
||||||
|
int realX = (int) (w / sizeRatio);
|
||||||
|
int realY = (int) (h / sizeRatio);
|
||||||
|
|
||||||
|
int offset = imgWidth * realY + realX;
|
||||||
|
if (offset < maskData.length && maskData[offset] == 1) {
|
||||||
|
points.add(originPt.x + (float) w);
|
||||||
|
points.add(originPt.y + (float) h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float[] ptft = new float[points.size()];
|
||||||
|
for (int j = 0; j < points.size(); j++) {
|
||||||
|
ptft[j] = points.get(j);
|
||||||
|
}
|
||||||
|
canvas.drawPoints(ptft, paintMask);
|
||||||
|
} else {
|
||||||
|
// 语义分割绘制
|
||||||
|
drawSemanticMask(canvas, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
super.onDraw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 语义分割基于mask不同值绘制颜色
|
||||||
|
*/
|
||||||
|
private void drawSemanticMask(Canvas canvas, BasePolygonResultModel model) {
|
||||||
|
List<ColorPointsPair> colorPointsPairList = new ArrayList<>();
|
||||||
|
for (int[] rgb : COLOR_MAP_DEF) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setARGB(170, rgb[0], rgb[1], rgb[2]);
|
||||||
|
colorPointsPairList.add(new ColorPointsPair(paint));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] maskData = model.getMask();
|
||||||
|
for (int w = 0; w < imgWidth * sizeRatio; w++) {
|
||||||
|
for (int h = 0; h < imgHeight * sizeRatio; h++) {
|
||||||
|
|
||||||
|
int realX = (int) (w / sizeRatio);
|
||||||
|
int realY = (int) (h / sizeRatio);
|
||||||
|
|
||||||
|
int offset = imgWidth * realY + realX;
|
||||||
|
byte label = maskData[offset];
|
||||||
|
|
||||||
|
if (label >= colorPointsPairList.size()) {
|
||||||
|
for (int i = colorPointsPairList.size(); i <= label; i++ ) {
|
||||||
|
Paint newPaint = getRandomMaskPaint(i);
|
||||||
|
colorPointsPairList.add(new ColorPointsPair(newPaint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colorPointsPairList.get(label).addPoint(originPt.x + (float) w);
|
||||||
|
colorPointsPairList.get(label).addPoint(originPt.y + (float) h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ColorPointsPair pair : colorPointsPairList) {
|
||||||
|
float[] points = pair.getPointsArray();
|
||||||
|
if (points != null) {
|
||||||
|
canvas.drawPoints(points, pair.getPaint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于分割模型,一个颜色对应一系列点
|
||||||
|
*/
|
||||||
|
private class ColorPointsPair {
|
||||||
|
private final Paint paint;
|
||||||
|
private List<Float> points;
|
||||||
|
|
||||||
|
public ColorPointsPair(Paint paint) {
|
||||||
|
this.paint = paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPoint(float point) {
|
||||||
|
if (points == null) {
|
||||||
|
points = new ArrayList<>();
|
||||||
|
}
|
||||||
|
points.add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getPointsArray() {
|
||||||
|
if (points == null || points.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
float[] array = new float[points.size()];
|
||||||
|
for (int i = 0; i < points.size(); i++) {
|
||||||
|
array[i] = points.get(i);
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Paint getPaint() {
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package com.baidu.paddle.fastdeploy.app.ui;
|
package com.baidu.paddle.fastdeploy.app.ui.view;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
@@ -0,0 +1,47 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.baidu.paddle.fastdeploy.app.examples.R;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.util.StringUtil;
|
||||||
|
import com.baidu.paddle.fastdeploy.app.ui.view.model.BaseResultModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/13.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DetectResultAdapter extends ArrayAdapter<BaseResultModel> {
|
||||||
|
private int resourceId;
|
||||||
|
|
||||||
|
public DetectResultAdapter(@NonNull Context context, int resource) {
|
||||||
|
super(context, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DetectResultAdapter(@NonNull Context context, int resource, @NonNull List<BaseResultModel> objects) {
|
||||||
|
super(context, resource, objects);
|
||||||
|
resourceId = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
|
BaseResultModel model = getItem(position);
|
||||||
|
View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
|
||||||
|
TextView indexText = (TextView) view.findViewById(R.id.index);
|
||||||
|
TextView nameText = (TextView) view.findViewById(R.id.name);
|
||||||
|
TextView confidenceText = (TextView) view.findViewById(R.id.confidence);
|
||||||
|
indexText.setText(String.valueOf(model.getIndex()));
|
||||||
|
nameText.setText(String.valueOf(model.getName()));
|
||||||
|
confidenceText.setText(StringUtil.formatFloatString(model.getConfidence()));
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,149 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view.model;
|
||||||
|
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BasePolygonResultModel extends BaseResultModel {
|
||||||
|
private int colorId;
|
||||||
|
private boolean isRect;
|
||||||
|
private boolean isTextOverlay;
|
||||||
|
|
||||||
|
private boolean isHasGroupColor = false;
|
||||||
|
private boolean isDrawPoints = false;
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isTextOverlay() {
|
||||||
|
return isTextOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextOverlay(boolean textOverlay) {
|
||||||
|
isTextOverlay = textOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColorId() {
|
||||||
|
return colorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColorId(int colorId) {
|
||||||
|
this.colorId = colorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] mask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是语义分割mask
|
||||||
|
*/
|
||||||
|
private boolean semanticMask;
|
||||||
|
|
||||||
|
private Rect rect;
|
||||||
|
|
||||||
|
BasePolygonResultModel() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
BasePolygonResultModel(int index, String name, float confidence, Rect bounds) {
|
||||||
|
super(index, name, confidence);
|
||||||
|
parseFromRect(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
BasePolygonResultModel(int index, String name, float confidence, List<Point> bounds) {
|
||||||
|
super(index, name, confidence);
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect getRect() {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rect getRect(float ratio, Point origin) {
|
||||||
|
return new Rect((int) (origin.x + rect.left * ratio),
|
||||||
|
(int) (origin.y + rect.top * ratio),
|
||||||
|
(int) (origin.x + rect.right * ratio),
|
||||||
|
(int) (origin.y + rect.bottom * ratio));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseFromRect(Rect rect) {
|
||||||
|
Point ptTL = new Point(rect.left, rect.top);
|
||||||
|
Point ptTR = new Point(rect.right, rect.top);
|
||||||
|
Point ptRB = new Point(rect.right, rect.bottom);
|
||||||
|
Point ptLB = new Point(rect.left, rect.bottom);
|
||||||
|
this.bounds = new ArrayList<>();
|
||||||
|
this.bounds.add(ptTL);
|
||||||
|
this.bounds.add(ptTR);
|
||||||
|
this.bounds.add(ptRB);
|
||||||
|
this.bounds.add(ptLB);
|
||||||
|
this.rect = rect;
|
||||||
|
isRect = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRect() {
|
||||||
|
return isRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRect(boolean rect) {
|
||||||
|
isRect = rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getMask() {
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMask(byte[] mask) {
|
||||||
|
this.mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSemanticMask(boolean semanticMask) {
|
||||||
|
this.semanticMask = semanticMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSemanticMask() {
|
||||||
|
return semanticMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Point> bounds;
|
||||||
|
|
||||||
|
public List<Point> getBounds() {
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Point> getBounds(float ratio, Point origin) {
|
||||||
|
List<Point> pointList = new ArrayList<>();
|
||||||
|
for (Point pt : bounds) {
|
||||||
|
int nx = (int) (origin.x + pt.x * ratio);
|
||||||
|
int ny = (int) (origin.y + pt.y * ratio);
|
||||||
|
pointList.add(new Point(nx, ny));
|
||||||
|
}
|
||||||
|
return pointList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBounds(List<Point> bounds) {
|
||||||
|
this.bounds = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBounds(Rect bounds) {
|
||||||
|
parseFromRect(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasMask() {
|
||||||
|
return (mask != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasGroupColor() {
|
||||||
|
return isHasGroupColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasGroupColor(boolean hasGroupColor) {
|
||||||
|
isHasGroupColor = hasGroupColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDrawPoints() {
|
||||||
|
return isDrawPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawPoints(boolean drawPoints) {
|
||||||
|
isDrawPoints = drawPoints;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,45 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by ruanshimin on 2018/5/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BaseResultModel {
|
||||||
|
private int index;
|
||||||
|
private String name;
|
||||||
|
private float confidence;
|
||||||
|
|
||||||
|
public BaseResultModel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseResultModel(int index, String name, float confidence) {
|
||||||
|
this.index = index;
|
||||||
|
this.name = name;
|
||||||
|
this.confidence = confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getConfidence() {
|
||||||
|
return confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfidence(float confidence) {
|
||||||
|
this.confidence = confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
package com.baidu.paddle.fastdeploy.app.ui.view.model;
|
||||||
|
|
||||||
|
public class PoseViewResultModel extends BasePolygonResultModel {
|
||||||
|
public PoseViewResultModel() {
|
||||||
|
super();
|
||||||
|
setRect(false);
|
||||||
|
setTextOverlay(false);
|
||||||
|
setDrawPoints(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,163 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:keepScreenOn="true"
|
|
||||||
tools:context="com.baidu.paddle.fastdeploy.app.examples.ocr.MainActivity">
|
|
||||||
|
|
||||||
<RelativeLayout
|
<include
|
||||||
android:layout_width="match_parent"
|
layout="@layout/camera_page"
|
||||||
android:layout_height="match_parent"
|
android:id="@+id/camera_page"></include>
|
||||||
android:background="@color/colorWindow">
|
|
||||||
|
|
||||||
<com.baidu.paddle.fastdeploy.app.ui.ActionBarLayout
|
<include
|
||||||
android:id="@+id/action_bar"
|
layout="@layout/result_page"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/result_page"
|
||||||
android:layout_height="wrap_content">
|
android:visibility="gone"></include>
|
||||||
|
</FrameLayout>
|
||||||
<ImageView
|
|
||||||
android:id="@+id/back_in_preview"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:cropToPadding="true"
|
|
||||||
android:paddingLeft="40px"
|
|
||||||
android:paddingTop="60px"
|
|
||||||
android:paddingRight="60px"
|
|
||||||
android:paddingBottom="40px"
|
|
||||||
android:src="@drawable/back_btn" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="50px"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/action_takepicture_btn"
|
|
||||||
style="@style/action_btn_selected"
|
|
||||||
android:layout_width="300px"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/action_bar_take_photo"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/action_realtime_btn"
|
|
||||||
style="@style/action_btn"
|
|
||||||
android:layout_width="300px"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/action_bar_realtime"
|
|
||||||
android:textAlignment="center" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</com.baidu.paddle.fastdeploy.app.ui.ActionBarLayout>
|
|
||||||
|
|
||||||
<!-- 时实-->
|
|
||||||
<com.baidu.paddle.fastdeploy.app.ui.CameraSurfaceView
|
|
||||||
android:id="@+id/sv_preview"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_above="@+id/contral"
|
|
||||||
android:layout_below="@+id/action_bar"
|
|
||||||
android:layout_centerInParent="true" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/albumSelect"
|
|
||||||
android:layout_width="40dp"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_marginRight="20dp"
|
|
||||||
android:layout_marginBottom="145dp"
|
|
||||||
android:background="@drawable/album_btn"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_status"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginTop="60dp"
|
|
||||||
android:layout_marginRight="30dp"
|
|
||||||
android:textColor="@color/colorText"
|
|
||||||
android:textSize="@dimen/small_font_size" />
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/top_bar_height"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:background="@color/colorTopBar">
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/btn_settings"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="30dp"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginRight="10dp"
|
|
||||||
android:background="@null"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:src="@drawable/btn_settings" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/contral"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:background="@color/colorBottomBar"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/bottom_bar_top_margin"
|
|
||||||
android:orientation="vertical"></LinearLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/large_button_height">
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/btn_switch"
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginLeft="60dp"
|
|
||||||
android:background="#00000000"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:src="@drawable/switch_side_btn" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/btn_shutter"
|
|
||||||
android:layout_width="@dimen/large_button_width"
|
|
||||||
android:layout_height="@dimen/large_button_height"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:background="@null"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:src="@drawable/take_picture_btn" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/realtime_toggle_btn"
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginRight="60dp"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:src="@drawable/realtime_stop_btn" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/bottom_bar_bottom_margin"
|
|
||||||
android:orientation="vertical"></LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</RelativeLayout>
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
161
java/android/app/src/main/res/layout/camera_page.xml
Normal file
161
java/android/app/src/main/res/layout/camera_page.xml
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:keepScreenOn="true"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/colorWindow">
|
||||||
|
|
||||||
|
<com.baidu.paddle.fastdeploy.app.ui.layout.ActionBarLayout
|
||||||
|
android:id="@+id/action_bar_main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back_in_preview"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:cropToPadding="true"
|
||||||
|
android:paddingLeft="40px"
|
||||||
|
android:paddingTop="60px"
|
||||||
|
android:paddingRight="60px"
|
||||||
|
android:paddingBottom="40px"
|
||||||
|
android:src="@drawable/back_btn" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="50px"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/action_takepicture_btn"
|
||||||
|
style="@style/action_btn_selected"
|
||||||
|
android:layout_width="300px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/action_bar_take_photo"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/action_realtime_btn"
|
||||||
|
style="@style/action_btn"
|
||||||
|
android:layout_width="300px"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/action_bar_realtime"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.baidu.paddle.fastdeploy.app.ui.layout.ActionBarLayout>
|
||||||
|
|
||||||
|
<!-- 时实-->
|
||||||
|
<com.baidu.paddle.fastdeploy.app.ui.CameraSurfaceView
|
||||||
|
android:id="@+id/sv_preview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_above="@+id/contral"
|
||||||
|
android:layout_below="@+id/action_bar_main"
|
||||||
|
android:layout_centerInParent="true" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/albumSelect"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginRight="20dp"
|
||||||
|
android:layout_marginBottom="145dp"
|
||||||
|
android:background="@drawable/album_btn"
|
||||||
|
android:scaleType="fitXY" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_status"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:layout_marginRight="30dp"
|
||||||
|
android:textColor="@color/colorText"
|
||||||
|
android:textSize="@dimen/small_font_size" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/top_bar_height"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:background="@color/colorTopBar">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_settings"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginRight="10dp"
|
||||||
|
android:background="@null"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/btn_settings" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/contral"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:background="@color/colorBottomBar"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/bottom_bar_top_margin"
|
||||||
|
android:orientation="vertical"></LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/large_button_height">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_switch"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="60dp"
|
||||||
|
android:background="#00000000"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/switch_side_btn" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_shutter"
|
||||||
|
android:layout_width="@dimen/large_button_width"
|
||||||
|
android:layout_height="@dimen/large_button_height"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:background="@null"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/take_picture_btn" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/realtime_toggle_btn"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginRight="60dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/realtime_stop_btn" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/bottom_bar_bottom_margin"
|
||||||
|
android:orientation="vertical"></LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
26
java/android/app/src/main/res/layout/result_detect_item.xml
Normal file
26
java/android/app/src/main/res/layout/result_detect_item.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/result_page_border_section_bk">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/index"
|
||||||
|
style="@style/list_result_view_item_style"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_weight="0.2" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/name"
|
||||||
|
style="@style/list_result_view_item_style"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_weight="0.6"
|
||||||
|
android:maxWidth="300px" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/confidence"
|
||||||
|
style="@style/list_result_view_item_style"
|
||||||
|
android:layout_weight="0.2"
|
||||||
|
android:layout_width="wrap_content" />
|
||||||
|
</LinearLayout>
|
164
java/android/app/src/main/res/layout/result_page.xml
Normal file
164
java/android/app/src/main/res/layout/result_page.xml
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFFFFF"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.baidu.paddle.fastdeploy.app.ui.layout.ActionBarLayout
|
||||||
|
android:id="@+id/action_bar_result"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back_in_result"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:cropToPadding="true"
|
||||||
|
android:paddingLeft="40px"
|
||||||
|
android:paddingTop="60px"
|
||||||
|
android:paddingRight="60px"
|
||||||
|
android:paddingBottom="40px"
|
||||||
|
android:src="@drawable/back_btn" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/model_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="50px"
|
||||||
|
android:textColor="@color/textColor"
|
||||||
|
android:textSize="@dimen/action_btn_text_size" />
|
||||||
|
</com.baidu.paddle.fastdeploy.app.ui.layout.ActionBarLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="700px">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/result_image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/bk_result_image_padding" />
|
||||||
|
|
||||||
|
<com.baidu.paddle.fastdeploy.app.ui.view.ResultMaskView
|
||||||
|
android:id="@+id/result_mask"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="40px"
|
||||||
|
android:layout_marginTop="26px"
|
||||||
|
android:layout_marginBottom="20px"
|
||||||
|
android:text="@string/result_label"
|
||||||
|
android:textColor="@color/bk_black"
|
||||||
|
android:textSize="56px"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/result_seekbar_section"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="130px"
|
||||||
|
android:layout_marginLeft="@dimen/result_list_padding_lr"
|
||||||
|
android:layout_marginRight="@dimen/result_list_padding_lr"
|
||||||
|
android:layout_marginBottom="@dimen/result_list_gap_width"
|
||||||
|
android:background="@drawable/result_page_border_section_bk"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:paddingLeft="30px"
|
||||||
|
android:text="@string/result_table_header_confidence"
|
||||||
|
android:textColor="@color/table_result_tableheader_text_color"
|
||||||
|
android:textSize="@dimen/result_list_view_text_size" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/confidence_seekbar"
|
||||||
|
android:layout_width="220dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_weight="6"
|
||||||
|
android:focusable="false"
|
||||||
|
android:maxHeight="8px"
|
||||||
|
android:progressDrawable="@drawable/seekbar_progress_result"
|
||||||
|
android:splitTrack="false"
|
||||||
|
android:thumb="@drawable/seekbar_handle" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/seekbar_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingRight="30px"
|
||||||
|
android:textSize="@dimen/result_list_view_text_size"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/result_list_padding_lr"
|
||||||
|
android:layout_marginRight="@dimen/result_list_padding_lr"
|
||||||
|
android:layout_marginBottom="@dimen/result_list_gap_width"
|
||||||
|
android:background="@drawable/result_page_border_section_bk"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/list_result_view_tablehead_style"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/result_table_header_index"
|
||||||
|
android:textColor="@color/table_result_tableheader_text_color" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/list_result_view_tablehead_style"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/result_table_header_name"
|
||||||
|
android:textColor="@color/table_result_tableheader_text_color" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/list_result_view_tablehead_style"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.4"
|
||||||
|
android:gravity="right"
|
||||||
|
android:text="@string/result_table_header_confidence"
|
||||||
|
android:textColor="@color/table_result_tableheader_text_color" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="15px"
|
||||||
|
android:paddingLeft="@dimen/result_list_padding_lr"
|
||||||
|
android:paddingRight="@dimen/result_list_padding_lr">
|
||||||
|
|
||||||
|
<com.baidu.paddle.fastdeploy.app.ui.view.ResultListView
|
||||||
|
android:id="@+id/result_list_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="700px"
|
||||||
|
android:divider="#FFFFFF"
|
||||||
|
android:dividerHeight="@dimen/result_list_gap_width"></com.baidu.paddle.fastdeploy.app.ui.view.ResultListView>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="160dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="right"
|
||||||
|
android:layout_marginTop="80px"
|
||||||
|
android:layout_marginRight="80px">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/bk_blue"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.6"
|
||||||
|
style="@style/list_result_popview_tablehead_style"
|
||||||
|
android:text="@string/result_table_header_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.4"
|
||||||
|
android:gravity="right"
|
||||||
|
android:layout_marginRight="30px"
|
||||||
|
style="@style/list_result_popview_tablehead_style"
|
||||||
|
android:text="@string/result_table_header_confidence" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.baidu.paddle.fastdeploy.app.ui.view.ResultListView
|
||||||
|
android:id="@+id/result_list_popview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"></com.baidu.paddle.fastdeploy.app.ui.view.ResultListView>.
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
@@ -1,6 +1,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<!-- Default App name -->
|
<!-- Default App name -->
|
||||||
<string name="app_name">FastDeploy PicoDet</string>
|
<string name="app_name">EasyEdge</string>
|
||||||
<!-- Other App name -->
|
<!-- Other App name -->
|
||||||
<string name="detection_app_name">FastDeploy PicoDet</string>
|
<string name="detection_app_name">FastDeploy PicoDet</string>
|
||||||
<string name="ocr_app_name">FastDeploy PP-OCRv2</string>
|
<string name="ocr_app_name">FastDeploy PP-OCRv2</string>
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
<string name="CPU_POWER_MODE_DEFAULT">LITE_POWER_HIGH</string>
|
<string name="CPU_POWER_MODE_DEFAULT">LITE_POWER_HIGH</string>
|
||||||
<string name="SCORE_THRESHOLD_DEFAULT">0.4</string>
|
<string name="SCORE_THRESHOLD_DEFAULT">0.4</string>
|
||||||
<string name="ENABLE_LITE_FP16_MODE_DEFAULT">true</string>
|
<string name="ENABLE_LITE_FP16_MODE_DEFAULT">true</string>
|
||||||
|
<!--Other values-->
|
||||||
<!-- Default model & Label paths & other values ... -->
|
<!-- Default model & Label paths & other values ... -->
|
||||||
<string name="MODEL_DIR_DEFAULT">models/picodet_s_320_coco_lcnet</string>
|
<string name="MODEL_DIR_DEFAULT">models/picodet_s_320_coco_lcnet</string>
|
||||||
<string name="LABEL_PATH_DEFAULT">labels/coco_label_list.txt</string>
|
<string name="LABEL_PATH_DEFAULT">labels/coco_label_list.txt</string>
|
||||||
@@ -35,4 +36,4 @@
|
|||||||
<string name="operation_confidence_control">阈值控制</string>
|
<string name="operation_confidence_control">阈值控制</string>
|
||||||
<string name="operation_retry">重新识别</string>
|
<string name="operation_retry">重新识别</string>
|
||||||
<string name="operation_save">保存结果</string>
|
<string name="operation_save">保存结果</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
17
java/android/app/src/main/res/values/values.xml
Normal file
17
java/android/app/src/main/res/values/values.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<dimen name="action_btn_size">120dp</dimen>
|
||||||
|
<dimen name="action_btn_text_size">46px</dimen>
|
||||||
|
|
||||||
|
<dimen name="operation_btn_margin_top_take_picture">126px</dimen>
|
||||||
|
<dimen name="operation_btn_margin_top">136px</dimen>
|
||||||
|
|
||||||
|
<dimen name="result_list_view_text_size">46px</dimen>
|
||||||
|
|
||||||
|
<dimen name="result_list_popview_text_size">36px</dimen>
|
||||||
|
|
||||||
|
<dimen name="result_list_padding_lr">15dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="result_list_gap_width">15dp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
Reference in New Issue
Block a user