From: @sishuikang Reviewed-by: @zhanghaibo5,@zhang_xue_tong Signed-off-by: @zhanghaibo5tags/v1.1.0
| @@ -28,6 +28,7 @@ import android.util.Log; | |||||
| import android.util.Pair; | import android.util.Pair; | ||||
| import android.view.View; | import android.view.View; | ||||
| import android.widget.ImageView; | import android.widget.ImageView; | ||||
| import android.widget.Toast; | |||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.app.AppCompatActivity; | import androidx.appcompat.app.AppCompatActivity; | ||||
| @@ -92,6 +93,7 @@ public class ObjectPhotoActivity extends AppCompatActivity { | |||||
| showOriginImage(); | showOriginImage(); | ||||
| } | } | ||||
| } else { | } else { | ||||
| Toast.makeText(this, R.string.image_invalid, Toast.LENGTH_LONG).show(); | |||||
| finish(); | finish(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -107,10 +109,11 @@ public class ObjectPhotoActivity extends AppCompatActivity { | |||||
| if (originBitmap != null) { | if (originBitmap != null) { | ||||
| initMindspore(originBitmap); | initMindspore(originBitmap); | ||||
| preview.setImageBitmap(originBitmap); | preview.setImageBitmap(originBitmap); | ||||
| } else { | |||||
| Toast.makeText(this, R.string.image_invalid, Toast.LENGTH_LONG).show(); | |||||
| } | } | ||||
| } | } | ||||
| private void initMindspore(Bitmap bitmap) { | private void initMindspore(Bitmap bitmap) { | ||||
| try { | try { | ||||
| trackingMobile = new ObjectTrackingMobile(this); | trackingMobile = new ObjectTrackingMobile(this); | ||||
| @@ -118,9 +121,7 @@ public class ObjectPhotoActivity extends AppCompatActivity { | |||||
| Log.e(TAG, Log.getStackTraceString(e)); | Log.e(TAG, Log.getStackTraceString(e)); | ||||
| e.printStackTrace(); | e.printStackTrace(); | ||||
| } | } | ||||
| // 加载模型 | |||||
| boolean ret = trackingMobile.loadModelFromBuf(getAssets()); | boolean ret = trackingMobile.loadModelFromBuf(getAssets()); | ||||
| if (!ret) { | if (!ret) { | ||||
| Log.e(TAG, "Load model error."); | Log.e(TAG, "Load model error."); | ||||
| return; | return; | ||||
| @@ -137,6 +138,8 @@ public class ObjectPhotoActivity extends AppCompatActivity { | |||||
| if (recognitionObjectBeanList != null && recognitionObjectBeanList.size() > 0) { | if (recognitionObjectBeanList != null && recognitionObjectBeanList.size() > 0) { | ||||
| drawRect(bitmap); | drawRect(bitmap); | ||||
| } else { | |||||
| Toast.makeText(this, R.string.train_invalid, Toast.LENGTH_LONG).show(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -20,4 +20,6 @@ | |||||
| <string name="title_time">Inference Time</string> | <string name="title_time">Inference Time</string> | ||||
| <string name="image_invalid">The image path you selected is not valid. Please choose again</string> | |||||
| <string name="train_invalid">Sorry, there is no object identified in this picture. Try another picture</string> | |||||
| </resources> | </resources> | ||||
| @@ -13,7 +13,7 @@ android { | |||||
| minSdkVersion 21 | minSdkVersion 21 | ||||
| targetSdkVersion 30 | targetSdkVersion 30 | ||||
| versionCode 1 | versionCode 1 | ||||
| versionName "1.0" | |||||
| versionName "1.0.0" | |||||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||
| externalNativeBuild { | externalNativeBuild { | ||||
| @@ -23,12 +23,10 @@ android { | |||||
| } | } | ||||
| } | } | ||||
| ndk { | ndk { | ||||
| //abiFilters 'arm64-v8a', 'armeabi-v7a' | |||||
| abiFilters 'arm64-v8a' | abiFilters 'arm64-v8a' | ||||
| } | } | ||||
| } | } | ||||
| aaptOptions { | aaptOptions { | ||||
| // noCompress '.so', ".tflite", ".mnn", ".cambricon", '.mslite', 'om', 'ms' | |||||
| noCompress '.so', 'ms' | noCompress '.so', 'ms' | ||||
| } | } | ||||
| @@ -20,10 +20,6 @@ | |||||
| 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.mindspore.hiobject.objectdetect.DealDataActivity" | |||||
| android:screenOrientation="portrait" | |||||
| android:theme="@style/Theme.AppCompat.NoActionBar"/> | |||||
| <activity | <activity | ||||
| android:name="com.mindspore.hiobject.objectdetect.PhotoActivity" | android:name="com.mindspore.hiobject.objectdetect.PhotoActivity" | ||||
| android:theme="@style/Theme.AppCompat.NoActionBar"/> | android:theme="@style/Theme.AppCompat.NoActionBar"/> | ||||
| @@ -1,52 +1,75 @@ | |||||
| package com.mindspore.hiobject; | package com.mindspore.hiobject; | ||||
| import android.Manifest; | import android.Manifest; | ||||
| import android.app.ProgressDialog; | |||||
| import android.content.DialogInterface; | |||||
| import android.content.Intent; | import android.content.Intent; | ||||
| import android.content.pm.PackageInfo; | |||||
| import android.content.pm.PackageManager; | |||||
| import android.net.Uri; | |||||
| import android.os.Build; | |||||
| import android.os.Bundle; | import android.os.Bundle; | ||||
| import android.provider.MediaStore; | import android.provider.MediaStore; | ||||
| import android.provider.Settings; | |||||
| import android.view.View; | import android.view.View; | ||||
| import android.widget.Button; | import android.widget.Button; | ||||
| import android.widget.TextView; | |||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.app.AlertDialog; | |||||
| import androidx.appcompat.app.AppCompatActivity; | import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.core.app.ActivityCompat; | import androidx.core.app.ActivityCompat; | ||||
| import androidx.core.content.ContextCompat; | |||||
| import com.mindspore.hiobject.objectdetect.CameraActivity; | import com.mindspore.hiobject.objectdetect.CameraActivity; | ||||
| import com.mindspore.hiobject.objectdetect.PhotoActivity; | import com.mindspore.hiobject.objectdetect.PhotoActivity; | ||||
| public class SplashActivity extends AppCompatActivity implements View.OnClickListener { | |||||
| public class SplashActivity extends AppCompatActivity { | |||||
| private static final String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, | |||||
| Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA}; | |||||
| private static final int REQUEST_PERMISSION = 1; | |||||
| private static final int RC_CHOOSE_PHOTO = 1; | |||||
| private static final int REQUEST_CAMERA_PERMISSION = 2; | |||||
| private Button btnPhoto, btnCamera; | |||||
| private boolean isAllGranted; | |||||
| private TextView versionText; | |||||
| @Override | @Override | ||||
| protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
| super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
| setContentView(R.layout.activity_splash); | setContentView(R.layout.activity_splash); | ||||
| versionText = findViewById(R.id.tv_vision); | |||||
| showPackageInfo(); | |||||
| requestPermissions(); | |||||
| } | |||||
| btnPhoto = findViewById(R.id.btn_photo); | |||||
| btnCamera = findViewById(R.id.btn_camera); | |||||
| btnPhoto.setOnClickListener(this); | |||||
| btnCamera.setOnClickListener(this); | |||||
| private void showPackageInfo() { | |||||
| try { | |||||
| PackageManager packageManager = this.getPackageManager(); | |||||
| PackageInfo packageInfo = packageManager.getPackageInfo(this.getPackageName(), 0); | |||||
| versionText.setText("Version: " + packageInfo.versionName); | |||||
| } catch (PackageManager.NameNotFoundException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | } | ||||
| private void requestPermissions() { | |||||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |||||
| isAllGranted = checkPermissionAllGranted(PERMISSIONS); | |||||
| if (!isAllGranted) { | |||||
| ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSION); | |||||
| } | |||||
| } else { | |||||
| isAllGranted = true; | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void onClick(View view) { | |||||
| if (R.id.btn_photo == view.getId()) { | |||||
| ActivityCompat.requestPermissions(this, | |||||
| new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, | |||||
| Manifest.permission.READ_PHONE_STATE}, RC_CHOOSE_PHOTO); | |||||
| } else if (R.id.btn_camera == view.getId()) { | |||||
| ActivityCompat.requestPermissions(this, | |||||
| new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, | |||||
| Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); | |||||
| private boolean checkPermissionAllGranted(String[] permissions) { | |||||
| for (String permission : permissions) { | |||||
| if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| return true; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -54,33 +77,56 @@ public class SplashActivity extends AppCompatActivity implements View.OnClickLis | |||||
| */ | */ | ||||
| @Override | @Override | ||||
| public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | ||||
| if (RC_CHOOSE_PHOTO == requestCode) { | |||||
| choosePhoto(); | |||||
| } else if (REQUEST_CAMERA_PERMISSION == requestCode) { | |||||
| chooseCamera(); | |||||
| if (REQUEST_PERMISSION == requestCode) { | |||||
| isAllGranted = true; | |||||
| for (int grant : grantResults) { | |||||
| if (grant != PackageManager.PERMISSION_GRANTED) { | |||||
| isAllGranted = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (!isAllGranted) { | |||||
| openAppDetails(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| private void choosePhoto() { | |||||
| Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null); | |||||
| intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); | |||||
| startActivityForResult(intentToPickPic, RC_CHOOSE_PHOTO); | |||||
| } | |||||
| private void chooseCamera() { | |||||
| Intent intent = new Intent(SplashActivity.this, CameraActivity.class); | |||||
| startActivity(intent); | |||||
| private void openAppDetails() { | |||||
| AlertDialog.Builder builder = new AlertDialog.Builder(this); | |||||
| builder.setMessage("HiMindSpore需要访问 “相机” 和 “外部存储器”,请到 “应用信息 -> 权限” 中授予!"); | |||||
| builder.setPositiveButton("去手动授权", new DialogInterface.OnClickListener() { | |||||
| @Override | |||||
| public void onClick(DialogInterface dialog, int which) { | |||||
| Intent intent = new Intent(); | |||||
| intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |||||
| intent.addCategory(Intent.CATEGORY_DEFAULT); | |||||
| intent.setData(Uri.parse("package:" + getPackageName())); | |||||
| intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |||||
| intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); | |||||
| intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); | |||||
| startActivity(intent); | |||||
| } | |||||
| }); | |||||
| builder.setNegativeButton("取消", null); | |||||
| builder.show(); | |||||
| } | } | ||||
| @Override | |||||
| protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | |||||
| super.onActivityResult(requestCode, resultCode, data); | |||||
| if (RC_CHOOSE_PHOTO == requestCode && null != data && null != data.getData()) { | |||||
| public void onClickPhoto(View view) { | |||||
| if (isAllGranted){ | |||||
| Intent intent = new Intent(SplashActivity.this, PhotoActivity.class); | Intent intent = new Intent(SplashActivity.this, PhotoActivity.class); | ||||
| intent.setData(data.getData()); | |||||
| startActivity(intent); | startActivity(intent); | ||||
| }else{ | |||||
| requestPermissions(); | |||||
| } | |||||
| } | |||||
| public void onClickCamera(View view) { | |||||
| if (isAllGranted){ | |||||
| Intent intent = new Intent(SplashActivity.this, CameraActivity.class); | |||||
| startActivity(intent); | |||||
| }else{ | |||||
| requestPermissions(); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,151 @@ | |||||
| /** | |||||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||||
| * <p> | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * <p> | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * <p> | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| */ | |||||
| package com.mindspore.hiobject.help; | |||||
| import android.app.Activity; | |||||
| import android.database.Cursor; | |||||
| import android.graphics.Bitmap; | |||||
| import android.graphics.BitmapFactory; | |||||
| import android.graphics.Matrix; | |||||
| import android.media.ExifInterface; | |||||
| import android.net.Uri; | |||||
| import android.provider.MediaStore; | |||||
| import android.util.Log; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| public class BitmapUtils { | |||||
| private static final String TAG = "BitmapUtils"; | |||||
| public static void recycleBitmap(Bitmap... bitmaps) { | |||||
| for (Bitmap bitmap : bitmaps) { | |||||
| if (bitmap != null && !bitmap.isRecycled()) { | |||||
| bitmap.recycle(); | |||||
| bitmap = null; | |||||
| } | |||||
| } | |||||
| } | |||||
| private static String getImagePath(Activity activity, Uri uri) { | |||||
| String[] projection = {MediaStore.Images.Media.DATA}; | |||||
| Cursor cursor = activity.managedQuery(uri, projection, null, null, null); | |||||
| int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); | |||||
| cursor.moveToFirst(); | |||||
| return cursor.getString(columnIndex); | |||||
| } | |||||
| public static Bitmap loadFromPath(Activity activity, int id, int width, int height) { | |||||
| BitmapFactory.Options options = new BitmapFactory.Options(); | |||||
| options.inJustDecodeBounds = true; | |||||
| InputStream is = activity.getResources().openRawResource(id); | |||||
| int sampleSize = calculateInSampleSize(options, width, height); | |||||
| options.inSampleSize = sampleSize; | |||||
| options.inJustDecodeBounds = false; | |||||
| return zoomImage(BitmapFactory.decodeStream(is), width, height); | |||||
| } | |||||
| public static Bitmap loadFromPath(Activity activity, Uri uri, int width, int height) { | |||||
| BitmapFactory.Options options = new BitmapFactory.Options(); | |||||
| options.inJustDecodeBounds = true; | |||||
| String path = getImagePath(activity, uri); | |||||
| BitmapFactory.decodeFile(path, options); | |||||
| int sampleSize = calculateInSampleSize(options, width, height); | |||||
| options.inSampleSize = sampleSize; | |||||
| options.inJustDecodeBounds = false; | |||||
| Bitmap bitmap = zoomImage(BitmapFactory.decodeFile(path, options), width, height); | |||||
| return rotateBitmap(bitmap, getRotationAngle(path)); | |||||
| } | |||||
| private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { | |||||
| final int width = options.outWidth; | |||||
| final int height = options.outHeight; | |||||
| int inSampleSize = 1; | |||||
| if (height > reqHeight || width > reqWidth) { | |||||
| // Calculate height and required height scale. | |||||
| final int heightRatio = Math.round((float) height / (float) reqHeight); | |||||
| // Calculate width and required width scale. | |||||
| final int widthRatio = Math.round((float) width / (float) reqWidth); | |||||
| // Take the larger of the values. | |||||
| inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio; | |||||
| } | |||||
| return inSampleSize; | |||||
| } | |||||
| // Scale pictures to screen width. | |||||
| private static Bitmap zoomImage(Bitmap imageBitmap, int targetWidth, int maxHeight) { | |||||
| float scaleFactor = | |||||
| Math.max( | |||||
| (float) imageBitmap.getWidth() / (float) targetWidth, | |||||
| (float) imageBitmap.getHeight() / (float) maxHeight); | |||||
| Bitmap resizedBitmap = | |||||
| Bitmap.createScaledBitmap( | |||||
| imageBitmap, | |||||
| (int) (imageBitmap.getWidth() / scaleFactor), | |||||
| (int) (imageBitmap.getHeight() / scaleFactor), | |||||
| true); | |||||
| return resizedBitmap; | |||||
| } | |||||
| /** | |||||
| * Get the rotation angle of the photo. | |||||
| * | |||||
| * @param path photo path. | |||||
| * @return angle. | |||||
| */ | |||||
| public static int getRotationAngle(String path) { | |||||
| int rotation = 0; | |||||
| try { | |||||
| ExifInterface exifInterface = new ExifInterface(path); | |||||
| int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); | |||||
| switch (orientation) { | |||||
| case ExifInterface.ORIENTATION_ROTATE_90: | |||||
| rotation = 90; | |||||
| break; | |||||
| case ExifInterface.ORIENTATION_ROTATE_180: | |||||
| rotation = 180; | |||||
| break; | |||||
| case ExifInterface.ORIENTATION_ROTATE_270: | |||||
| rotation = 270; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } catch (IOException e) { | |||||
| Log.e(TAG, "Failed to get rotation: " + e.getMessage()); | |||||
| } | |||||
| return rotation; | |||||
| } | |||||
| public static Bitmap rotateBitmap(Bitmap bitmap, int angle) { | |||||
| Matrix matrix = new Matrix(); | |||||
| matrix.postRotate(angle); | |||||
| Bitmap result = null; | |||||
| try { | |||||
| result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); | |||||
| } catch (OutOfMemoryError e) { | |||||
| Log.e(TAG, "Failed to rotate bitmap: " + e.getMessage()); | |||||
| } | |||||
| if (result == null) { | |||||
| return bitmap; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| /** | |||||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||||
| * <p> | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * <p> | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * <p> | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| */ | |||||
| package com.mindspore.hiobject.help; | |||||
| import android.content.Context; | |||||
| public class DisplayUtil { | |||||
| private DisplayUtil() { | |||||
| /* cannot be instantiated */ | |||||
| throw new UnsupportedOperationException("cannot be instantiated"); | |||||
| } | |||||
| public static int px2dip(Context context, float pxValue) { | |||||
| final float scale = context.getResources().getDisplayMetrics().density; | |||||
| return (int) (pxValue / scale + 0.5f); | |||||
| } | |||||
| public static int dip2px(Context context, float dipValue) { | |||||
| final float scale = context.getResources().getDisplayMetrics().density; | |||||
| return (int) (dipValue * scale + 0.5f); | |||||
| } | |||||
| public static int px2sp(Context context, float pxValue) { | |||||
| final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; | |||||
| return (int) (pxValue / fontScale + 0.5f); | |||||
| } | |||||
| public static int sp2px(Context context, float spValue) { | |||||
| final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; | |||||
| return (int) (spValue * fontScale + 0.5f); | |||||
| } | |||||
| } | |||||
| @@ -2,7 +2,6 @@ package com.mindspore.hiobject.objectdetect; | |||||
| import android.content.Context; | import android.content.Context; | ||||
| import android.graphics.Canvas; | import android.graphics.Canvas; | ||||
| import android.graphics.Color; | |||||
| import android.graphics.Paint; | import android.graphics.Paint; | ||||
| import android.graphics.Paint.Style; | import android.graphics.Paint.Style; | ||||
| import android.graphics.RectF; | import android.graphics.RectF; | ||||
| @@ -10,6 +9,8 @@ import android.util.AttributeSet; | |||||
| import android.util.Log; | import android.util.Log; | ||||
| import android.view.View; | import android.view.View; | ||||
| import com.mindspore.hiobject.R; | |||||
| import com.mindspore.hiobject.help.DisplayUtil; | |||||
| import com.mindspore.hiobject.help.RecognitionObjectBean; | import com.mindspore.hiobject.help.RecognitionObjectBean; | ||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| @@ -32,34 +33,34 @@ public class ObjectRectView extends View { | |||||
| // Frame area | // Frame area | ||||
| private RectF mObjRectF; | private RectF mObjRectF; | ||||
| private Context context; | |||||
| public ObjectRectView(Context context) { | public ObjectRectView(Context context) { | ||||
| super(context); | |||||
| initialize(); | |||||
| this(context, null); | |||||
| } | } | ||||
| public ObjectRectView(Context context, AttributeSet attrs) { | public ObjectRectView(Context context, AttributeSet attrs) { | ||||
| super(context, attrs); | |||||
| initialize(); | |||||
| this(context, attrs, 0); | |||||
| } | } | ||||
| public ObjectRectView(Context context, AttributeSet attrs, int defStyleAttr) { | public ObjectRectView(Context context, AttributeSet attrs, int defStyleAttr) { | ||||
| super(context, attrs, defStyleAttr); | super(context, attrs, defStyleAttr); | ||||
| this.context = context; | |||||
| initialize(); | initialize(); | ||||
| } | } | ||||
| public int[] MyColor = {Color.RED, Color.WHITE, Color.YELLOW, Color.GREEN, Color.LTGRAY, Color.MAGENTA, Color.BLACK, Color.BLUE, Color.CYAN}; | |||||
| private static final int[] MyColor = {R.color.white, R.color.text_blue, R.color.text_yellow, R.color.text_orange, R.color.text_green}; | |||||
| private void initialize() { | private void initialize() { | ||||
| mObjRectF = new RectF(); | mObjRectF = new RectF(); | ||||
| mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | ||||
| mPaint.setTextSize(50); | |||||
| mPaint.setTextSize(DisplayUtil.sp2px(context, 16)); | |||||
| //Draw only outline (stroke) | //Draw only outline (stroke) | ||||
| mPaint.setStyle(Style.STROKE); | mPaint.setStyle(Style.STROKE); | ||||
| mPaint.setStrokeWidth(5); | |||||
| mPaint.setStrokeWidth(DisplayUtil.dip2px(context, 2)); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -68,15 +69,14 @@ public class ObjectRectView extends View { | |||||
| * @param recognitions | * @param recognitions | ||||
| */ | */ | ||||
| public void setInfo(List<RecognitionObjectBean> recognitions) { | public void setInfo(List<RecognitionObjectBean> recognitions) { | ||||
| Log.i(TAG, "setInfo: "+recognitions.size()); | |||||
| Log.i(TAG, "setInfo: " + recognitions.size()); | |||||
| mRecognitions.clear(); | mRecognitions.clear(); | ||||
| mRecognitions.addAll(recognitions); | mRecognitions.addAll(recognitions); | ||||
| invalidate(); | invalidate(); | ||||
| } | } | ||||
| public void clearCanvas(){ | |||||
| public void clearCanvas() { | |||||
| mRecognitions.clear(); | mRecognitions.clear(); | ||||
| invalidate(); | invalidate(); | ||||
| } | } | ||||
| @@ -88,21 +88,21 @@ public class ObjectRectView extends View { | |||||
| if (mRecognitions == null || mRecognitions.size() == 0) { | if (mRecognitions == null || mRecognitions.size() == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| for (int i = 0;i<mRecognitions.size();i++){ | |||||
| for (int i = 0; i < mRecognitions.size(); i++) { | |||||
| RecognitionObjectBean bean = mRecognitions.get(i); | RecognitionObjectBean bean = mRecognitions.get(i); | ||||
| mPaint.setColor(MyColor[i % MyColor.length]); | |||||
| mPaint.setColor(context.getResources().getColor(MyColor[i % MyColor.length])); | |||||
| drawRect(bean, canvas); | drawRect(bean, canvas); | ||||
| } | } | ||||
| } | } | ||||
| public void drawRect(RecognitionObjectBean bean, Canvas canvas) { | public void drawRect(RecognitionObjectBean bean, Canvas canvas) { | ||||
| StringBuilder sb = new StringBuilder(); | StringBuilder sb = new StringBuilder(); | ||||
| sb.append(bean.getRectID()).append("_").append(bean.getObjectName()).append("_").append(String.format("%.2f", (100 * bean.getScore())) + "%"); | sb.append(bean.getRectID()).append("_").append(bean.getObjectName()).append("_").append(String.format("%.2f", (100 * bean.getScore())) + "%"); | ||||
| mObjRectF = new RectF(bean.getLeft(), bean.getTop(), bean.getRight(), bean.getBottom()); | mObjRectF = new RectF(bean.getLeft(), bean.getTop(), bean.getRight(), bean.getBottom()); | ||||
| canvas.drawRoundRect(mObjRectF, 5, 5, mPaint); | |||||
| canvas.drawText(sb.toString(), mObjRectF.left, mObjRectF.top -20 , mPaint); | |||||
| canvas.drawRect(mObjRectF, mPaint); | |||||
| canvas.drawText(sb.toString(), mObjRectF.left, mObjRectF.top - DisplayUtil.dip2px(context, 10), mPaint); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,21 +1,26 @@ | |||||
| package com.mindspore.hiobject.objectdetect; | package com.mindspore.hiobject.objectdetect; | ||||
| import android.content.Intent; | |||||
| import android.content.res.Configuration; | |||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | |||||
| import android.graphics.Canvas; | import android.graphics.Canvas; | ||||
| import android.graphics.Color; | |||||
| import android.graphics.Matrix; | |||||
| import android.graphics.Paint; | import android.graphics.Paint; | ||||
| import android.graphics.RectF; | import android.graphics.RectF; | ||||
| import android.net.Uri; | import android.net.Uri; | ||||
| import android.os.Bundle; | import android.os.Bundle; | ||||
| import android.provider.MediaStore; | |||||
| import android.util.Log; | import android.util.Log; | ||||
| import android.util.Pair; | |||||
| import android.view.View; | |||||
| import android.widget.ImageView; | import android.widget.ImageView; | ||||
| import android.widget.Toast; | |||||
| import androidx.annotation.Nullable; | |||||
| import androidx.appcompat.app.AppCompatActivity; | import androidx.appcompat.app.AppCompatActivity; | ||||
| import com.mindspore.hiobject.R; | import com.mindspore.hiobject.R; | ||||
| import com.mindspore.hiobject.help.ImageDegreeHelper; | |||||
| import com.mindspore.hiobject.help.BitmapUtils; | |||||
| import com.mindspore.hiobject.help.DisplayUtil; | |||||
| import com.mindspore.hiobject.help.RecognitionObjectBean; | import com.mindspore.hiobject.help.RecognitionObjectBean; | ||||
| import com.mindspore.hiobject.help.TrackingMobile; | import com.mindspore.hiobject.help.TrackingMobile; | ||||
| @@ -27,33 +32,62 @@ import static com.mindspore.hiobject.help.RecognitionObjectBean.getRecognitionLi | |||||
| public class PhotoActivity extends AppCompatActivity { | public class PhotoActivity extends AppCompatActivity { | ||||
| private static final String TAG = "PhotoActivity"; | private static final String TAG = "PhotoActivity"; | ||||
| private static final int[] COLORS ={Color.RED, Color.WHITE, Color.YELLOW, Color.GREEN, Color.LTGRAY, Color.MAGENTA, Color.BLACK, Color.BLUE, Color.CYAN}; | |||||
| private static final int[] COLORS = {R.color.white, R.color.text_blue, R.color.text_yellow, R.color.text_orange, R.color.text_green}; | |||||
| private ImageView imgPhoto; | |||||
| private static final int RC_CHOOSE_PHOTO = 1; | |||||
| private ImageView preview; | |||||
| private TrackingMobile trackingMobile; | private TrackingMobile trackingMobile; | ||||
| private List<RecognitionObjectBean> recognitionObjectBeanList; | private List<RecognitionObjectBean> recognitionObjectBeanList; | ||||
| private Integer maxWidthOfImage; | |||||
| private Integer maxHeightOfImage; | |||||
| boolean isLandScape; | |||||
| private Bitmap originBitmap; | |||||
| @Override | @Override | ||||
| protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
| super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
| setContentView(R.layout.activity_photo); | setContentView(R.layout.activity_photo); | ||||
| preview = findViewById(R.id.img_photo); | |||||
| this.isLandScape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; | |||||
| openGallay(); | |||||
| imgPhoto = findViewById(R.id.img_photo); | |||||
| } | |||||
| Uri uri = getIntent().getData(); | |||||
| String imgPath = ImageDegreeHelper.getPath(this,uri); | |||||
| int degree = ImageDegreeHelper.readPictureDegree(imgPath); | |||||
| Bitmap originBitmap = BitmapFactory.decodeFile(imgPath); | |||||
| if (originBitmap != null) { | |||||
| Bitmap bitmap = ImageDegreeHelper.rotaingImageView(degree, originBitmap.copy(Bitmap.Config.ARGB_8888, true)); | |||||
| if (bitmap != null) { | |||||
| Matrix matrix = new Matrix(); | |||||
| matrix.setScale(0.7f, 0.7f); | |||||
| bitmap = Bitmap.createBitmap( bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); | |||||
| imgPhoto.setImageBitmap(bitmap); | |||||
| initMindspore(bitmap); | |||||
| private void openGallay() { | |||||
| Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null); | |||||
| intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); | |||||
| startActivityForResult(intentToPickPic, RC_CHOOSE_PHOTO); | |||||
| } | |||||
| @Override | |||||
| protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { | |||||
| super.onActivityResult(requestCode, resultCode, data); | |||||
| if (RC_CHOOSE_PHOTO == requestCode && null != data && null != data.getData()) { | |||||
| if (data != null) { | |||||
| showOriginImage(data.getData()); | |||||
| } | } | ||||
| } else { | |||||
| Toast.makeText(this, R.string.image_invalid, Toast.LENGTH_LONG).show(); | |||||
| finish(); | |||||
| } | |||||
| } | |||||
| private void showOriginImage(Uri imageUri) { | |||||
| Pair<Integer, Integer> targetedSize = this.getTargetSize(); | |||||
| int targetWidth = targetedSize.first; | |||||
| int maxHeight = targetedSize.second; | |||||
| originBitmap = BitmapUtils.loadFromPath(this, imageUri, targetWidth, maxHeight); | |||||
| // Determine how much to scale down the image. | |||||
| Log.i(TAG, "resized image size width:" + originBitmap.getWidth() + ",height: " + originBitmap.getHeight()); | |||||
| if (originBitmap != null) { | |||||
| initMindspore(originBitmap); | |||||
| preview.setImageBitmap(originBitmap); | |||||
| } else { | |||||
| Toast.makeText(this, R.string.image_invalid, Toast.LENGTH_LONG).show(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -64,9 +98,7 @@ public class PhotoActivity extends AppCompatActivity { | |||||
| Log.e(TAG, Log.getStackTraceString(e)); | Log.e(TAG, Log.getStackTraceString(e)); | ||||
| e.printStackTrace(); | e.printStackTrace(); | ||||
| } | } | ||||
| // 加载模型 | |||||
| boolean ret = trackingMobile.loadModelFromBuf(getAssets()); | boolean ret = trackingMobile.loadModelFromBuf(getAssets()); | ||||
| if (!ret) { | if (!ret) { | ||||
| Log.e(TAG, "Load model error."); | Log.e(TAG, "Load model error."); | ||||
| return; | return; | ||||
| @@ -76,46 +108,83 @@ public class PhotoActivity extends AppCompatActivity { | |||||
| String result = trackingMobile.MindSpore_runnet(bitmap); | String result = trackingMobile.MindSpore_runnet(bitmap); | ||||
| long endTime = System.currentTimeMillis(); | long endTime = System.currentTimeMillis(); | ||||
| Log.d(TAG, "RUNNET CONSUMING:"+(endTime-startTime)+"ms"); | |||||
| Log.d(TAG, "result:"+ result); | |||||
| Log.d(TAG, "RUNNET CONSUMING:" + (endTime - startTime) + "ms"); | |||||
| Log.d(TAG, "result:" + result); | |||||
| recognitionObjectBeanList = getRecognitionList(result); | recognitionObjectBeanList = getRecognitionList(result); | ||||
| if (recognitionObjectBeanList != null && recognitionObjectBeanList.size() > 0) { | if (recognitionObjectBeanList != null && recognitionObjectBeanList.size() > 0) { | ||||
| drawRect(bitmap); | drawRect(bitmap); | ||||
| } else { | |||||
| Toast.makeText(this, R.string.train_invalid, Toast.LENGTH_LONG).show(); | |||||
| } | } | ||||
| } | } | ||||
| private void drawRect(Bitmap bitmap) { | private void drawRect(Bitmap bitmap) { | ||||
| Canvas canvas = new Canvas(bitmap); | Canvas canvas = new Canvas(bitmap); | ||||
| Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | |||||
| paint.setTextSize(dip2px(15)); | |||||
| paint.setStyle(Paint.Style.STROKE); | |||||
| paint.setStrokeWidth(3); | |||||
| Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |||||
| mPaint.setTextSize(DisplayUtil.sp2px(this, 16)); | |||||
| //Draw only outline (stroke) | |||||
| mPaint.setStyle(Paint.Style.STROKE); | |||||
| mPaint.setStrokeWidth(DisplayUtil.dip2px(this, 2)); | |||||
| for (int i = 0; i < recognitionObjectBeanList.size(); i++) { | for (int i = 0; i < recognitionObjectBeanList.size(); i++) { | ||||
| RecognitionObjectBean objectBean = recognitionObjectBeanList.get(i); | RecognitionObjectBean objectBean = recognitionObjectBeanList.get(i); | ||||
| StringBuilder sb = new StringBuilder(); | StringBuilder sb = new StringBuilder(); | ||||
| sb.append(objectBean.getRectID()).append("_").append(objectBean.getObjectName()).append("_").append(String.format("%.2f", (100 * objectBean.getScore())) + "%"); | sb.append(objectBean.getRectID()).append("_").append(objectBean.getObjectName()).append("_").append(String.format("%.2f", (100 * objectBean.getScore())) + "%"); | ||||
| int paintColor = COLORS[i % COLORS.length]; | |||||
| paint.setColor(paintColor); | |||||
| int paintColor = getResources().getColor(COLORS[i % COLORS.length]); | |||||
| mPaint.setColor(paintColor); | |||||
| RectF rectF = new RectF(objectBean.getLeft(), objectBean.getTop(), objectBean.getRight(), objectBean.getBottom()); | RectF rectF = new RectF(objectBean.getLeft(), objectBean.getTop(), objectBean.getRight(), objectBean.getBottom()); | ||||
| canvas.drawRect(rectF, paint); | |||||
| canvas.drawText(sb.toString(),objectBean.getLeft(), objectBean.getTop()-10,paint); | |||||
| canvas.drawRect(rectF, mPaint); | |||||
| canvas.drawText(sb.toString(), objectBean.getLeft(), objectBean.getTop() - 10, mPaint); | |||||
| } | } | ||||
| } | } | ||||
| @Override | @Override | ||||
| protected void onDestroy() { | protected void onDestroy() { | ||||
| super.onDestroy(); | super.onDestroy(); | ||||
| trackingMobile.unloadModel(); | |||||
| if (trackingMobile != null) { | |||||
| trackingMobile.unloadModel(); | |||||
| } | |||||
| BitmapUtils.recycleBitmap(originBitmap); | |||||
| } | } | ||||
| public int dip2px(float dipValue){ | |||||
| float scale = getResources().getDisplayMetrics().density; | |||||
| return (int) (dipValue*scale+0.5f); | |||||
| // Returns max width of image. | |||||
| private Integer getMaxWidthOfImage() { | |||||
| if (this.maxWidthOfImage == null) { | |||||
| if (this.isLandScape) { | |||||
| this.maxWidthOfImage = ((View) this.preview.getParent()).getHeight(); | |||||
| } else { | |||||
| this.maxWidthOfImage = ((View) this.preview.getParent()).getWidth(); | |||||
| } | |||||
| } | |||||
| return this.maxWidthOfImage; | |||||
| } | |||||
| // Returns max height of image. | |||||
| private Integer getMaxHeightOfImage() { | |||||
| if (this.maxHeightOfImage == null) { | |||||
| if (this.isLandScape) { | |||||
| this.maxHeightOfImage = ((View) this.preview.getParent()).getWidth(); | |||||
| } else { | |||||
| this.maxHeightOfImage = ((View) this.preview.getParent()).getHeight(); | |||||
| } | |||||
| } | |||||
| return this.maxHeightOfImage; | |||||
| } | |||||
| // Gets the targeted size(width / height). | |||||
| private Pair<Integer, Integer> getTargetSize() { | |||||
| Integer targetWidth; | |||||
| Integer targetHeight; | |||||
| Integer maxWidth = this.getMaxWidthOfImage(); | |||||
| Integer maxHeight = this.getMaxHeightOfImage(); | |||||
| targetWidth = this.isLandScape ? maxHeight : maxWidth; | |||||
| targetHeight = this.isLandScape ? maxWidth : maxHeight; | |||||
| Log.i(TAG, "height:" + targetHeight + ",width:" + targetWidth); | |||||
| return new Pair<>(targetWidth, targetHeight); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,13 +1,15 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||
| <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
| xmlns:tools="http://schemas.android.com/tools" | |||||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||||
| android:layout_width="match_parent" | android:layout_width="match_parent" | ||||
| android:layout_height="match_parent" | android:layout_height="match_parent" | ||||
| tools:context=".objectdetect.PhotoActivity"> | |||||
| android:fitsSystemWindows="true" | |||||
| android:keepScreenOn="true" | |||||
| android:orientation="vertical"> | |||||
| <ImageView | <ImageView | ||||
| android:scaleType="fitXY" | |||||
| android:id="@+id/img_photo" | android:id="@+id/img_photo" | ||||
| android:layout_width="match_parent" | |||||
| android:layout_height="match_parent"/> | |||||
| </androidx.constraintlayout.widget.ConstraintLayout> | |||||
| android:layout_width="wrap_content" | |||||
| android:layout_height="wrap_content" | |||||
| android:layout_centerInParent="true" | |||||
| android:scaleType="fitXY" /> | |||||
| </RelativeLayout> | |||||
| @@ -7,46 +7,76 @@ | |||||
| android:background="@color/colorPrimary" | android:background="@color/colorPrimary" | ||||
| tools:context=".SplashActivity"> | tools:context=".SplashActivity"> | ||||
| <ImageView | |||||
| <TextView | |||||
| android:id="@+id/img_logo" | android:id="@+id/img_logo" | ||||
| android:layout_width="wrap_content" | |||||
| android:layout_width="0dp" | |||||
| android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
| android:src="@mipmap/logo" | |||||
| app:layout_constraintBottom_toBottomOf="parent" | |||||
| android:layout_marginTop="68dp" | |||||
| android:drawableTop="@drawable/logo" | |||||
| android:drawablePadding="10dp" | |||||
| android:gravity="center_horizontal" | |||||
| android:maxLines="1" | |||||
| android:text="@string/app_name_title" | |||||
| android:textColor="@color/white" | |||||
| android:textSize="36sp" | |||||
| app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
| app:layout_constraintHorizontal_bias="0.0" | |||||
| app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
| app:layout_constraintTop_toTopOf="parent" /> | app:layout_constraintTop_toTopOf="parent" /> | ||||
| <Button | <Button | ||||
| android:id="@+id/btn_photo" | |||||
| android:layout_width="wrap_content" | |||||
| android:layout_height="wrap_content" | |||||
| android:layout_marginTop="52dp" | |||||
| app:layout_constraintEnd_toEndOf="parent" | |||||
| app:layout_constraintStart_toStartOf="parent" | |||||
| android:id="@+id/btn_image" | |||||
| android:layout_width="0dp" | |||||
| android:layout_height="48dp" | |||||
| android:layout_marginLeft="20dp" | |||||
| android:layout_marginTop="40dp" | |||||
| android:background="@color/gray_btn" | |||||
| android:drawableStart="@drawable/btn_image" | |||||
| android:drawablePadding="15dp" | |||||
| android:gravity="left|center_vertical" | |||||
| android:onClick="onClickPhoto" | |||||
| android:paddingLeft="15dp" | |||||
| android:text="PHOTO" | android:text="PHOTO" | ||||
| android:textAllCaps="false" | |||||
| android:textSize="12sp" | |||||
| app:layout_constraintWidth_percent="0.6" | |||||
| app:layout_constraintStart_toStartOf="parent" | |||||
| app:layout_constraintEnd_toEndOf="parent" | |||||
| app:layout_constraintTop_toBottomOf="@+id/img_logo" | app:layout_constraintTop_toBottomOf="@+id/img_logo" | ||||
| /> | |||||
| /> | |||||
| <Button | |||||
| <Button | |||||
| android:id="@+id/btn_camera" | android:id="@+id/btn_camera" | ||||
| android:layout_width="wrap_content" | |||||
| android:layout_height="wrap_content" | |||||
| android:layout_marginTop="20dp" | |||||
| android:layout_width="0dp" | |||||
| android:layout_height="48dp" | |||||
| android:layout_marginLeft="20dp" | |||||
| android:layout_marginTop="30dp" | |||||
| android:background="@color/gray_btn" | |||||
| android:drawableStart="@drawable/btn_object" | |||||
| android:drawablePadding="15dp" | |||||
| android:gravity="left|center_vertical" | |||||
| android:onClick="onClickCamera" | |||||
| android:paddingLeft="15dp" | |||||
| android:text="CAMERA" | android:text="CAMERA" | ||||
| app:layout_constraintTop_toBottomOf="@+id/btn_photo" | |||||
| android:textAllCaps="false" | |||||
| android:textSize="12sp" | |||||
| app:layout_constraintWidth_percent="0.6" | |||||
| app:layout_constraintStart_toStartOf="parent" | |||||
| app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
| app:layout_constraintStart_toStartOf="parent" /> | |||||
| app:layout_constraintTop_toBottomOf="@+id/btn_image" | |||||
| /> | |||||
| <Button | |||||
| android:visibility="gone" | |||||
| android:id="@+id/btn_deal" | |||||
| <TextView | |||||
| android:id="@+id/tv_vision" | |||||
| android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||||
| android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||||
| android:layout_marginTop="20dp" | |||||
| android:text="DEALDATA" | |||||
| app:layout_constraintTop_toBottomOf="@+id/btn_camera" | |||||
| android:layout_marginBottom="30dp" | |||||
| android:textColor="@color/white" | |||||
| android:textSize="20sp" | |||||
| app:layout_constraintBottom_toBottomOf="parent" | |||||
| app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
| app:layout_constraintStart_toStartOf="parent" /> | |||||
| app:layout_constraintStart_toStartOf="parent" | |||||
| tools:text="Version 1.0.0" /> | |||||
| </androidx.constraintlayout.widget.ConstraintLayout> | </androidx.constraintlayout.widget.ConstraintLayout> | ||||
| @@ -3,5 +3,16 @@ | |||||
| <color name="colorPrimary">#1a1b33</color> | <color name="colorPrimary">#1a1b33</color> | ||||
| <color name="colorPrimaryDark">#3700B3</color> | <color name="colorPrimaryDark">#3700B3</color> | ||||
| <color name="colorAccent">#2B2B2B</color> | <color name="colorAccent">#2B2B2B</color> | ||||
| <color name="mindspore_semi_transparent">#66000000</color> | |||||
| <color name="white">#ffffff</color> | <color name="white">#ffffff</color> | ||||
| <color name="black">#000000</color> | |||||
| <color name="gray">#A69D9D</color> | |||||
| <color name="gray_btn">#424242</color> | |||||
| <color name="text_blue">#6DA7FF</color> | |||||
| <color name="text_yellow">#F8E71C</color> | |||||
| <color name="text_orange">#FF844D</color> | |||||
| <color name="text_green">#66B50A</color> | |||||
| </resources> | </resources> | ||||
| @@ -1,5 +1,6 @@ | |||||
| <resources> | <resources> | ||||
| <string name="app_name">Detection</string> | <string name="app_name">Detection</string> | ||||
| <string name="app_name_title">MS Detection</string> | |||||
| <string name="action_settings">设置</string> | <string name="action_settings">设置</string> | ||||
| <string name="request_permission">This sample needs camera permission.</string> | <string name="request_permission">This sample needs camera permission.</string> | ||||
| @@ -8,4 +9,7 @@ | |||||
| <string name="appwidget_text">EXAMPLE</string> | <string name="appwidget_text">EXAMPLE</string> | ||||
| <string name="add_widget">Add widget</string> | <string name="add_widget">Add widget</string> | ||||
| <string name="image_invalid">The image path you selected is not valid. Please choose again</string> | |||||
| <string name="train_invalid">Sorry, there is no object identified in this picture. Try another picture</string> | |||||
| </resources> | </resources> | ||||