diff --git a/model_zoo/official/lite/Himindspore/app/build.gradle b/model_zoo/official/lite/Himindspore/app/build.gradle index 6ff55793c1..037dc65680 100644 --- a/model_zoo/official/lite/Himindspore/app/build.gradle +++ b/model_zoo/official/lite/Himindspore/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.mindspore.himindspore" minSdkVersion 21 targetSdkVersion 30 - versionCode 4 - versionName "1.1.2" + versionCode 5 + versionName "1.1.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { diff --git a/model_zoo/official/lite/Himindspore/app/src/main/java/com/mindspore/himindspore/SplashActivity.java b/model_zoo/official/lite/Himindspore/app/src/main/java/com/mindspore/himindspore/SplashActivity.java index edc4bf7237..a004ef010d 100644 --- a/model_zoo/official/lite/Himindspore/app/src/main/java/com/mindspore/himindspore/SplashActivity.java +++ b/model_zoo/official/lite/Himindspore/app/src/main/java/com/mindspore/himindspore/SplashActivity.java @@ -292,7 +292,7 @@ public class SplashActivity extends BaseActivity implements MainC public void showUpdate(final UpdateInfoBean updateInfo) { if (now_version == updateInfo.getVersionCode()) { - Toast.makeText(this, "已经是最新版本", Toast.LENGTH_SHORT).show(); + // Toast.makeText(this, "已经是最新版本", Toast.LENGTH_SHORT).show(); Log.d(TAG + "版本号是", "onResponse: " + now_version); } else { AlertDialog.Builder builder = new AlertDialog.Builder(this); diff --git a/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/CameraDataDealListener.java b/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/CameraDataDealListener.java deleted file mode 100644 index ec359100f5..0000000000 --- a/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/CameraDataDealListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2020 Huawei Technologies Co., Ltd - *

- * 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 - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.posenet; - -import android.media.Image; -import android.view.SurfaceView; - -public interface CameraDataDealListener { - void dataDeal(Image image, SurfaceView surfaceView); -} diff --git a/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PoseNetFragment.java b/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PoseNetFragment.java index 3bba7ef56b..36437ad5e9 100644 --- a/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PoseNetFragment.java +++ b/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PoseNetFragment.java @@ -15,12 +15,17 @@ */ package com.mindspore.posenet; -import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; -import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.Rect; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; @@ -41,33 +46,54 @@ import android.view.Surface; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.app.ActivityCompat; +import androidx.core.util.Pair; import androidx.fragment.app.Fragment; +import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.List; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; +import static com.mindspore.posenet.Posenet.BodyPart.LEFT_ANKLE; +import static com.mindspore.posenet.Posenet.BodyPart.LEFT_ELBOW; +import static com.mindspore.posenet.Posenet.BodyPart.LEFT_HIP; +import static com.mindspore.posenet.Posenet.BodyPart.LEFT_KNEE; +import static com.mindspore.posenet.Posenet.BodyPart.LEFT_SHOULDER; +import static com.mindspore.posenet.Posenet.BodyPart.LEFT_WRIST; +import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_ANKLE; +import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_ELBOW; +import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_HIP; +import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_KNEE; +import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_SHOULDER; +import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_WRIST; + /** * A simple {@link Fragment} subclass. * create an instance of this fragment. */ public class PoseNetFragment extends Fragment { - private final static int REQUEST_CAMERA_PERMISSION = 1; - private String cameraId = "1"; + private final List bodyJoints = Arrays.asList( + new Pair(LEFT_WRIST, LEFT_ELBOW), new Pair(LEFT_ELBOW, LEFT_SHOULDER), + new Pair(LEFT_SHOULDER, RIGHT_SHOULDER), new Pair(RIGHT_SHOULDER, RIGHT_ELBOW), + new Pair(RIGHT_ELBOW, RIGHT_WRIST), new Pair(LEFT_SHOULDER, LEFT_HIP), + new Pair(LEFT_HIP, RIGHT_HIP), new Pair(RIGHT_HIP, RIGHT_SHOULDER), + new Pair(LEFT_HIP, LEFT_KNEE), new Pair(LEFT_KNEE, LEFT_ANKLE), + new Pair(RIGHT_HIP, RIGHT_KNEE), new Pair(RIGHT_KNEE, RIGHT_ANKLE)); + + private static final String TAG = "PoseNetFragment"; + + private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT; // 要打开的摄像头ID private SurfaceView surfaceView; private CameraCaptureSession captureSession; private CameraDevice cameraDevice; - private Size previewSize; - private int previewWidth; - private int previewHeight; - private final int PREVIEW_WIDTH = 640; - private final int PREVIEW_HEIGHT = 480; + private final static int PREVIEW_WIDTH = 640; + private final static int PREVIEW_HEIGHT = 480; + private Size previewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); private HandlerThread backgroundThread; private Handler backgroundHandler; private ImageReader imageReader; @@ -76,8 +102,18 @@ public class PoseNetFragment extends Fragment { private Semaphore cameraOpenCloseLock = new Semaphore(1);//使用信号量 Semaphore 进行多线程任务调度 private boolean flashSupported; + /** + * Model input shape for images. + */ + private final static int MODEL_WIDTH = 257; + private final static int MODEL_HEIGHT = 257; - private static final String TAG = "PoseNetFragment"; + private final double minConfidence = 0.5; + private final float circleRadius = 8.0f; + private Paint paint = new Paint(); + private Posenet posenet; + private int[] rgbBytes = new int[PREVIEW_WIDTH * PREVIEW_HEIGHT]; + private byte[][] yuvBytes = new byte[3][]; private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @@ -93,12 +129,14 @@ public class PoseNetFragment extends Fragment { public void onDisconnected(@NonNull CameraDevice cameraDevice) { cameraOpenCloseLock.release(); cameraDevice.close(); + closeCamera(); PoseNetFragment.this.cameraDevice = null; } @Override public void onError(@NonNull CameraDevice cameraDevice, int error) { onDisconnected(cameraDevice); + closeCamera(); Activity activity = getActivity(); if (activity != null) { activity.finish(); @@ -106,7 +144,6 @@ public class PoseNetFragment extends Fragment { } }; - private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureProgressed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) { @@ -119,12 +156,6 @@ public class PoseNetFragment extends Fragment { } }; - private CameraDataDealListener cameraDataDealListener; - - public void setCameraDataDealListener(CameraDataDealListener cameraDataDealListener) { - this.cameraDataDealListener = cameraDataDealListener; - } - public static PoseNetFragment newInstance() { PoseNetFragment fragment = new PoseNetFragment(); return fragment; @@ -155,86 +186,24 @@ public class PoseNetFragment extends Fragment { openCamera(); } + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + posenet = new Posenet(getActivity()); + + } + public void onPause() { this.closeCamera(); this.stopBackgroundThread(); super.onPause(); } - public void onDestroy() { - super.onDestroy(); - } - - private void requestCameraPermission() { - if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) { - Toast.makeText(getContext(), "This app needs camera permission.", Toast.LENGTH_LONG).show(); - } else { - requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (requestCode == REQUEST_CAMERA_PERMISSION) { - if (allPermissionsGranted(grantResults)) { - Toast.makeText(getContext(), "This app needs camera permission.", Toast.LENGTH_LONG).show(); - } - } else { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - } - - private boolean allPermissionsGranted(int[] grantResults) { - for (int grantResult : grantResults) { - if (grantResult == PackageManager.PERMISSION_DENIED) { - return false; - } - } - return true; - } - - /** - * Sets up member variables related to camera. - */ - private void setUpCameraOutputs() { - CameraManager manager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE); - try { - for (String cameraId : manager.getCameraIdList()) { - CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); - // We don't use a front facing camera in this sample. - Integer cameraDirection = characteristics.get(CameraCharacteristics.LENS_FACING); - if (cameraDirection != null && cameraDirection == CameraCharacteristics.LENS_FACING_FRONT) { - continue; - } - - previewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); - - imageReader = ImageReader.newInstance( - PREVIEW_WIDTH, PREVIEW_HEIGHT, - ImageFormat.YUV_420_888, /*maxImages*/ 2 - ); - - previewHeight = previewSize.getHeight(); - previewWidth = previewSize.getWidth(); - // Initialize the storage bitmaps once when the resolution is known. - - // Check if the flash is supported. - flashSupported = - characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true; - - this.cameraId = cameraId; - - // We've found a viable camera and finished setting up member variables, - // so we don't need to iterate through other available cameras. - return; - } - } catch (CameraAccessException e) { - e.printStackTrace(); - } catch (NullPointerException e) { - e.printStackTrace(); - } + public void switchCamera() { + mCameraId ^= 1; + Log.d(TAG, "switchCamera: mCameraId: " + mCameraId); + closeCamera(); + openCamera(); } /** @@ -242,17 +211,23 @@ public class PoseNetFragment extends Fragment { */ @SuppressLint("MissingPermission") private void openCamera() { - if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - this.requestCameraPermission(); - } - setUpCameraOutputs(); CameraManager manager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE); try { + CameraCharacteristics characteristics = manager.getCameraCharacteristics(Integer.toString(mCameraId)); + previewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); + imageReader = ImageReader.newInstance( + PREVIEW_WIDTH, PREVIEW_HEIGHT, + ImageFormat.YUV_420_888, /*maxImages*/ 2 + ); + imageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler); + // Check if the flash is supported. + flashSupported = + characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true; // Wait for camera to open - 2.5 seconds is sufficient if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { throw new RuntimeException("Time out waiting to lock camera opening."); } - manager.openCamera(cameraId, mStateCallback, backgroundHandler); + manager.openCamera(Integer.toString(mCameraId), mStateCallback, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } catch (InterruptedException e) { @@ -305,31 +280,48 @@ public class PoseNetFragment extends Fragment { } } - private final ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader imageReader) { - if (previewWidth != 0 && previewHeight != 0 && imageReader != null) { + if (imageReader != null) { Image image = imageReader.acquireLatestImage(); - - if (cameraDataDealListener != null) { - cameraDataDealListener.dataDeal(image, surfaceView); + if (image == null || image.getPlanes() == null) { + return; + } + fillBytes(image.getPlanes(), yuvBytes); + ImageUtils.convertYUV420ToARGB8888(yuvBytes[0], yuvBytes[1], yuvBytes[2], + PREVIEW_WIDTH, PREVIEW_HEIGHT, + image.getPlanes()[0].getRowStride(), + image.getPlanes()[1].getRowStride(), + image.getPlanes()[1].getPixelStride(), + rgbBytes); + + Bitmap imageBitmap = Bitmap.createBitmap( + rgbBytes, PREVIEW_WIDTH, PREVIEW_HEIGHT, + Bitmap.Config.ARGB_8888); + Matrix rotateMatrix = new Matrix(); + if (mCameraId == CameraCharacteristics.LENS_FACING_FRONT) { + rotateMatrix.postRotate(90.0f); + } else if (mCameraId == CameraCharacteristics.LENS_FACING_BACK) { + rotateMatrix.postRotate(270.0f); + rotateMatrix.postScale(-1.0f, 1.0f); } + + Bitmap rotatedBitmap = Bitmap.createBitmap( + imageBitmap, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT, + rotateMatrix, true + ); + processImage(rotatedBitmap); + image.close(); } } }; - /** * Creates a new [CameraCaptureSession] for camera preview. */ private void createCameraPreviewSession() { try { - // We capture images from preview in YUV format. - imageReader = ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2); - imageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler); - // This is the surface we need to record images for processing. Surface recordingSurface = imageReader.getSurface(); @@ -387,4 +379,136 @@ public class PoseNetFragment extends Fragment { } } + + /** + * Fill the yuvBytes with data from image planes. + */ + private void fillBytes(Image.Plane[] planes, byte[][] yuvBytes) { + // Row stride is the total number of bytes occupied in memory by a row of an image. + // Because of the variable row stride it's not possible to know in + // advance the actual necessary dimensions of the yuv planes + for (int i = 0; i < planes.length; ++i) { + ByteBuffer buffer = planes[i].getBuffer(); + if (yuvBytes[i] == null) { + yuvBytes[i] = new byte[buffer.capacity()]; + } + buffer.get(yuvBytes[i]); + } + } + + /** + * Crop Bitmap to maintain aspect ratio of model input. + */ + private Bitmap cropBitmap(Bitmap bitmap) { + float bitmapRatio = bitmap.getHeight() / bitmap.getWidth(); + float modelInputRatio = MODEL_HEIGHT / MODEL_WIDTH; + double maxDifference = 1.0E-5D; + float cropHeight = modelInputRatio - bitmapRatio; + + if (Math.abs(cropHeight) < maxDifference) { + return bitmap; + } else { + Bitmap croppedBitmap; + if (modelInputRatio < bitmapRatio) { + cropHeight = (float) bitmap.getHeight() - (float) bitmap.getWidth() / modelInputRatio; + croppedBitmap = Bitmap.createBitmap(bitmap, + 0, (int) (cropHeight / 2), bitmap.getWidth(), (int) (bitmap.getHeight() - cropHeight)); + } else { + cropHeight = (float) bitmap.getWidth() - (float) bitmap.getHeight() * modelInputRatio; + croppedBitmap = Bitmap.createBitmap(bitmap, + (int) (cropHeight / 2), 0, (int) (bitmap.getWidth() - cropHeight), bitmap.getHeight()); + } + return croppedBitmap; + } + } + + /** + * Set the paint color and size. + */ + private void setPaint() { + paint.setColor(getResources().getColor(R.color.posenet_text_blue)); + paint.setTextSize(80.0f); + paint.setStrokeWidth(8.0f); + } + + /** + * Draw bitmap on Canvas. + */ + private void draw(Canvas canvas, Posenet.Person person, Bitmap bitmap) { + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + // Draw `bitmap` and `person` in square canvas. + int screenWidth, screenHeight; + int left, right, top, bottom; + if (canvas.getHeight() > canvas.getWidth()) { + screenWidth = canvas.getWidth(); + screenHeight = canvas.getWidth(); + left = 0; + top = (canvas.getHeight() - canvas.getWidth()) / 2; + } else { + screenWidth = canvas.getHeight(); + screenHeight = canvas.getHeight(); + left = (canvas.getWidth() - canvas.getHeight()) / 2; + top = 0; + } + right = left + screenWidth; + bottom = top + screenHeight; + + setPaint(); + canvas.drawBitmap( + bitmap, + new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), + new Rect(left, top, right, bottom), paint); + + float widthRatio = (float) screenWidth / MODEL_WIDTH; + float heightRatio = (float) screenHeight / MODEL_HEIGHT; + + for (Posenet.KeyPoint keyPoint : person.keyPoints) { + if (keyPoint.score > minConfidence) { + Posenet.Position position = keyPoint.position; + float adjustedX = position.x * widthRatio + left; + float adjustedY = position.y * heightRatio + top; + canvas.drawCircle(adjustedX, adjustedY, circleRadius, paint); + } + } + + for (int i = 0; i < bodyJoints.size(); i++) { + Pair line = (Pair) bodyJoints.get(i); + Posenet.BodyPart first = (Posenet.BodyPart) line.first; + Posenet.BodyPart second = (Posenet.BodyPart) line.second; + + if (person.keyPoints.get(first.ordinal()).score > minConfidence & + person.keyPoints.get(second.ordinal()).score > minConfidence) { + canvas.drawLine( + person.keyPoints.get(first.ordinal()).position.x * widthRatio + left, + person.keyPoints.get(first.ordinal()).position.y * heightRatio + top, + person.keyPoints.get(second.ordinal()).position.x * widthRatio + left, + person.keyPoints.get(second.ordinal()).position.y * heightRatio + top, paint); + } + } + + canvas.drawText(String.format("Score: %.2f", person.score), + (15.0f * widthRatio), (30.0f * heightRatio + bottom), paint); + canvas.drawText(String.format("Time: %.2f ms", posenet.lastInferenceTimeNanos * 1.0f / 1_000_000), + (15.0f * widthRatio), (50.0f * heightRatio + bottom), paint + ); + + // Draw! + surfaceView.getHolder().unlockCanvasAndPost(canvas); + } + + /** + * Process image using Posenet library. + */ + private void processImage(Bitmap bitmap) { + // Crop bitmap. + Bitmap croppedBitmap = cropBitmap(bitmap); + // Created scaled version of bitmap for model input. + Bitmap scaledBitmap = Bitmap.createScaledBitmap(croppedBitmap, MODEL_WIDTH, MODEL_HEIGHT, true); + // Perform inference. + Posenet.Person person = posenet.estimateSinglePose(scaledBitmap); + Canvas canvas = surfaceView.getHolder().lockCanvas(); + draw(canvas, person, scaledBitmap); + } + + } \ No newline at end of file diff --git a/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PosenetMainActivity.java b/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PosenetMainActivity.java index cd3f867aa7..0fc8efb5f7 100644 --- a/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PosenetMainActivity.java +++ b/model_zoo/official/lite/Himindspore/posenet/src/main/java/com/mindspore/posenet/PosenetMainActivity.java @@ -15,6 +15,10 @@ */ package com.mindspore.posenet; +import android.Manifest; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -24,10 +28,19 @@ import android.graphics.PorterDuff; import android.graphics.Rect; import android.hardware.camera2.CameraCharacteristics; import android.media.Image; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import android.view.SurfaceView; +import android.view.View; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import androidx.core.util.Pair; import com.alibaba.android.arouter.facade.annotation.Route; @@ -50,213 +63,114 @@ import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_SHOULDER; import static com.mindspore.posenet.Posenet.BodyPart.RIGHT_WRIST; @Route(path = "/posenet/PosenetMainActivity") -public class PosenetMainActivity extends AppCompatActivity implements CameraDataDealListener { +public class PosenetMainActivity extends AppCompatActivity { - private final List bodyJoints = Arrays.asList( - new Pair(LEFT_WRIST, LEFT_ELBOW), new Pair(LEFT_ELBOW, LEFT_SHOULDER), - new Pair(LEFT_SHOULDER, RIGHT_SHOULDER), new Pair(RIGHT_SHOULDER, RIGHT_ELBOW), - new Pair(RIGHT_ELBOW, RIGHT_WRIST), new Pair(LEFT_SHOULDER, LEFT_HIP), - new Pair(LEFT_HIP, RIGHT_HIP), new Pair(RIGHT_HIP, RIGHT_SHOULDER), - new Pair(LEFT_HIP, LEFT_KNEE), new Pair(LEFT_KNEE, LEFT_ANKLE), - new Pair(RIGHT_HIP, RIGHT_KNEE), new Pair(RIGHT_KNEE, RIGHT_ANKLE)); - ; + 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 REQUEST_PERMISSION_AGAIN = 2; + private boolean isAllGranted; - - /** - * Model input shape for images. - */ - private final static int MODEL_WIDTH = 257; - private final static int MODEL_HEIGHT = 257; - - private final double minConfidence = 0.5; - private final float circleRadius = 8.0f; - private Paint paint = new Paint(); - private final int PREVIEW_WIDTH = 640; - private final int PREVIEW_HEIGHT = 480; - private Posenet posenet; - private int[] rgbBytes = new int[PREVIEW_WIDTH * PREVIEW_HEIGHT]; - private byte[][] yuvBytes = new byte[3][]; - private SurfaceView surfaceView; - - private int lensFacing = CameraCharacteristics.LENS_FACING_BACK; private PoseNetFragment poseNetFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.posenet_activity_main); - addCameraFragment(); + requestPermissions(); } - private void addCameraFragment() { - posenet = new Posenet(this); - - poseNetFragment = PoseNetFragment.newInstance(); - poseNetFragment.setCameraDataDealListener(this); - // poseNetFragment.setFacingCamera(lensFacing); - getSupportFragmentManager().popBackStack(); - getSupportFragmentManager().beginTransaction() - .replace(R.id.container, poseNetFragment) - .commitAllowingStateLoss(); - } - @Override - public void dataDeal(Image image, SurfaceView surfaceView) { - if (image == null || image.getPlanes() == null) { - return; + private void requestPermissions() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + isAllGranted = checkPermissionAllGranted(PERMISSIONS); + if (!isAllGranted) { + ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSION); + } else { + addCameraFragment(); + } + } else { + isAllGranted = true; + addCameraFragment(); } - this.surfaceView = surfaceView; - fillBytes(image.getPlanes(), yuvBytes); - ImageUtils.convertYUV420ToARGB8888(yuvBytes[0], yuvBytes[1], yuvBytes[2], - PREVIEW_WIDTH, PREVIEW_HEIGHT, - image.getPlanes()[0].getRowStride(), - image.getPlanes()[1].getRowStride(), - image.getPlanes()[1].getPixelStride(), - rgbBytes); - - Bitmap imageBitmap = Bitmap.createBitmap( - rgbBytes, PREVIEW_WIDTH, PREVIEW_HEIGHT, - Bitmap.Config.ARGB_8888); - Matrix rotateMatrix = new Matrix(); - rotateMatrix.postRotate(90.0f); - - Bitmap rotatedBitmap = Bitmap.createBitmap( - imageBitmap, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT, - rotateMatrix, true - ); - image.close(); - processImage(rotatedBitmap); } - /** - * Fill the yuvBytes with data from image planes. - */ - private void fillBytes(Image.Plane[] planes, byte[][] yuvBytes) { - // Row stride is the total number of bytes occupied in memory by a row of an image. - // Because of the variable row stride it's not possible to know in - // advance the actual necessary dimensions of the yuv planes - for (int i = 0; i < planes.length; ++i) { - ByteBuffer buffer = planes[i].getBuffer(); - if (yuvBytes[i] == null) { - yuvBytes[i] = new byte[buffer.capacity()]; + private boolean checkPermissionAllGranted(String[] permissions) { + for (String permission : permissions) { + if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { + return false; } - buffer.get(yuvBytes[i]); } + return true; } /** - * Crop Bitmap to maintain aspect ratio of model input. + * Authority application result callback */ - private Bitmap cropBitmap(Bitmap bitmap) { - float bitmapRatio = bitmap.getHeight() / bitmap.getWidth(); - float modelInputRatio = MODEL_HEIGHT / MODEL_WIDTH; - double maxDifference = 1.0E-5D; - float cropHeight = modelInputRatio - bitmapRatio; - - if (Math.abs(cropHeight) < maxDifference) { - return bitmap; - } else { - Bitmap croppedBitmap; - if (modelInputRatio < bitmapRatio) { - cropHeight = (float) bitmap.getHeight() - (float) bitmap.getWidth() / modelInputRatio; - croppedBitmap = Bitmap.createBitmap(bitmap, - 0, (int) (cropHeight / 2), bitmap.getWidth(), (int) (bitmap.getHeight() - cropHeight)); + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (REQUEST_PERMISSION == requestCode) { + isAllGranted = true; + + for (int grant : grantResults) { + if (grant != PackageManager.PERMISSION_GRANTED) { + isAllGranted = false; + break; + } + } + if (!isAllGranted) { + openAppDetails(); } else { - cropHeight = (float) bitmap.getWidth() - (float) bitmap.getHeight() * modelInputRatio; - croppedBitmap = Bitmap.createBitmap(bitmap, - (int) (cropHeight / 2), 0, (int) (bitmap.getWidth() - cropHeight), bitmap.getHeight()); + addCameraFragment(); } - return croppedBitmap; } } - /** - * Set the paint color and size. - */ - private void setPaint() { - paint.setColor(getResources().getColor(R.color.posenet_text_blue)); - paint.setTextSize(80.0f); - paint.setStrokeWidth(8.0f); - } - - /** - * Draw bitmap on Canvas. - */ - private void draw(Canvas canvas, Posenet.Person person, Bitmap bitmap) { - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - // Draw `bitmap` and `person` in square canvas. - int screenWidth, screenHeight; - int left, right, top, bottom; - if (canvas.getHeight() > canvas.getWidth()) { - screenWidth = canvas.getWidth(); - screenHeight = canvas.getWidth(); - left = 0; - top = (canvas.getHeight() - canvas.getWidth()) / 2; - } else { - screenWidth = canvas.getHeight(); - screenHeight = canvas.getHeight(); - left = (canvas.getWidth() - canvas.getHeight()) / 2; - top = 0; - } - right = left + screenWidth; - bottom = top + screenHeight; - - setPaint(); - canvas.drawBitmap( - bitmap, - new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), - new Rect(left, top, right, bottom), paint); - - float widthRatio = (float) screenWidth / MODEL_WIDTH; - float heightRatio = (float) screenHeight / MODEL_HEIGHT; - - for (Posenet.KeyPoint keyPoint : person.keyPoints) { - if (keyPoint.score > minConfidence) { - Posenet.Position position = keyPoint.position; - float adjustedX = position.x * widthRatio + left; - float adjustedY = position.y * heightRatio + top; - canvas.drawCircle(adjustedX, adjustedY, circleRadius, paint); + private void openAppDetails() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage("PoseNet 需要访问 “相机” 和 “外部存储器”,请到 “应用信息 -> 权限” 中授予!"); + 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); + startActivityForResult(intent, REQUEST_PERMISSION_AGAIN); } - } - - for (int i = 0; i < bodyJoints.size(); i++) { - Pair line = (Pair) bodyJoints.get(i); - Posenet.BodyPart first = (Posenet.BodyPart) line.first; - Posenet.BodyPart second = (Posenet.BodyPart) line.second; - - if (person.keyPoints.get(first.ordinal()).score > minConfidence & - person.keyPoints.get(second.ordinal()).score > minConfidence) { - canvas.drawLine( - person.keyPoints.get(first.ordinal()).position.x * widthRatio + left, - person.keyPoints.get(first.ordinal()).position.y * heightRatio + top, - person.keyPoints.get(second.ordinal()).position.x * widthRatio + left, - person.keyPoints.get(second.ordinal()).position.y * heightRatio + top, paint); + }); + builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); } - } + }); + builder.show(); + } - canvas.drawText(String.format("Score: %.2f", person.score), - (15.0f * widthRatio), (30.0f * heightRatio + bottom), paint); - canvas.drawText(String.format("Time: %.2f ms", posenet.lastInferenceTimeNanos * 1.0f / 1_000_000), - (15.0f * widthRatio), (50.0f * heightRatio + bottom), paint - ); + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (REQUEST_PERMISSION_AGAIN == requestCode) { + requestPermissions(); + } + } - // Draw! - surfaceView.getHolder().unlockCanvasAndPost(canvas); + private void addCameraFragment() { + poseNetFragment = PoseNetFragment.newInstance(); + getSupportFragmentManager().popBackStack(); + getSupportFragmentManager().beginTransaction() + .replace(R.id.container, poseNetFragment) + .commitAllowingStateLoss(); } - /** - * Process image using Posenet library. - */ - private void processImage(Bitmap bitmap) { - // Crop bitmap. - Bitmap croppedBitmap = cropBitmap(bitmap); - // Created scaled version of bitmap for model input. - Bitmap scaledBitmap = Bitmap.createScaledBitmap(croppedBitmap, MODEL_WIDTH, MODEL_HEIGHT, true); - // Perform inference. - Posenet.Person person = posenet.estimateSinglePose(scaledBitmap); - Canvas canvas = surfaceView.getHolder().lockCanvas(); - draw(canvas, person, scaledBitmap); + public void onClickSwitch(View view) { + poseNetFragment.switchCamera(); } + } \ No newline at end of file diff --git a/model_zoo/official/lite/Himindspore/posenet/src/main/res/drawable-xxhdpi/ic_camera_switch.png b/model_zoo/official/lite/Himindspore/posenet/src/main/res/drawable-xxhdpi/ic_camera_switch.png new file mode 100644 index 0000000000..8900137c88 Binary files /dev/null and b/model_zoo/official/lite/Himindspore/posenet/src/main/res/drawable-xxhdpi/ic_camera_switch.png differ diff --git a/model_zoo/official/lite/Himindspore/posenet/src/main/res/layout/posenet_activity_main.xml b/model_zoo/official/lite/Himindspore/posenet/src/main/res/layout/posenet_activity_main.xml index b5f2a15a58..7246133839 100644 --- a/model_zoo/official/lite/Himindspore/posenet/src/main/res/layout/posenet_activity_main.xml +++ b/model_zoo/official/lite/Himindspore/posenet/src/main/res/layout/posenet_activity_main.xml @@ -27,5 +27,14 @@ android:text="MindSpore PoseNet" android:textColor="#ffffff" android:textSize="20sp" /> + + \ No newline at end of file diff --git a/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/CameraDataDealListener.java b/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/CameraDataDealListener.java deleted file mode 100644 index e3d0b1e399..0000000000 --- a/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/CameraDataDealListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2020 Huawei Technologies Co., Ltd - *

- * 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 - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.posenetdemo; - -import android.media.Image; -import android.view.SurfaceView; - -public interface CameraDataDealListener { - void dataDeal(Image image, SurfaceView surfaceView); -} diff --git a/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/MainActivity.java b/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/MainActivity.java index d12bf6fcfc..519778dce5 100644 --- a/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/MainActivity.java +++ b/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/MainActivity.java @@ -19,20 +19,11 @@ import android.Manifest; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.hardware.camera2.CameraCharacteristics; -import android.media.Image; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; -import android.view.SurfaceView; +import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,34 +31,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; -import androidx.core.util.Pair; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_ANKLE; -import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_ELBOW; -import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_HIP; -import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_KNEE; -import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_SHOULDER; -import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_WRIST; -import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_ANKLE; -import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_ELBOW; -import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_HIP; -import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_KNEE; -import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_SHOULDER; -import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_WRIST; - -public class MainActivity extends AppCompatActivity implements CameraDataDealListener { - - private final List bodyJoints = Arrays.asList( - new Pair(LEFT_WRIST, LEFT_ELBOW), new Pair(LEFT_ELBOW, LEFT_SHOULDER), - new Pair(LEFT_SHOULDER, RIGHT_SHOULDER), new Pair(RIGHT_SHOULDER, RIGHT_ELBOW), - new Pair(RIGHT_ELBOW, RIGHT_WRIST), new Pair(LEFT_SHOULDER, LEFT_HIP), - new Pair(LEFT_HIP, RIGHT_HIP), new Pair(RIGHT_HIP, RIGHT_SHOULDER), - new Pair(LEFT_HIP, LEFT_KNEE), new Pair(LEFT_KNEE, LEFT_ANKLE), - new Pair(RIGHT_HIP, RIGHT_KNEE), new Pair(RIGHT_KNEE, RIGHT_ANKLE)); +public class MainActivity 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}; @@ -75,23 +40,6 @@ public class MainActivity extends AppCompatActivity implements CameraDataDealLis private static final int REQUEST_PERMISSION_AGAIN = 2; private boolean isAllGranted; - /** - * Model input shape for images. - */ - private final static int MODEL_WIDTH = 257; - private final static int MODEL_HEIGHT = 257; - - private final double minConfidence = 0.5; - private final float circleRadius = 8.0f; - private Paint paint = new Paint(); - private final int PREVIEW_WIDTH = 640; - private final int PREVIEW_HEIGHT = 480; - private Posenet posenet; - private int[] rgbBytes = new int[PREVIEW_WIDTH * PREVIEW_HEIGHT]; - private byte[][] yuvBytes = new byte[3][]; - private SurfaceView surfaceView; - - private int lensFacing = CameraCharacteristics.LENS_FACING_BACK; private PoseNetFragment poseNetFragment; @Override @@ -182,173 +130,16 @@ public class MainActivity extends AppCompatActivity implements CameraDataDealLis } private void addCameraFragment() { - posenet = new Posenet(this); poseNetFragment = PoseNetFragment.newInstance(); - poseNetFragment.setCameraDataDealListener(this); - // poseNetFragment.setFacingCamera(lensFacing); getSupportFragmentManager().popBackStack(); getSupportFragmentManager().beginTransaction() .replace(R.id.container, poseNetFragment) .commitAllowingStateLoss(); } - @Override - public void dataDeal(Image image, SurfaceView surfaceView) { - if (image == null || image.getPlanes() == null) { - return; - } - this.surfaceView = surfaceView; - fillBytes(image.getPlanes(), yuvBytes); - ImageUtils.convertYUV420ToARGB8888(yuvBytes[0], yuvBytes[1], yuvBytes[2], - PREVIEW_WIDTH, PREVIEW_HEIGHT, - image.getPlanes()[0].getRowStride(), - image.getPlanes()[1].getRowStride(), - image.getPlanes()[1].getPixelStride(), - rgbBytes); - - Bitmap imageBitmap = Bitmap.createBitmap( - rgbBytes, PREVIEW_WIDTH, PREVIEW_HEIGHT, - Bitmap.Config.ARGB_8888); - Matrix rotateMatrix = new Matrix(); - rotateMatrix.postRotate(90.0f); - - Bitmap rotatedBitmap = Bitmap.createBitmap( - imageBitmap, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT, - rotateMatrix, true - ); - image.close(); - processImage(rotatedBitmap); - } - - - /** - * Fill the yuvBytes with data from image planes. - */ - private void fillBytes(Image.Plane[] planes, byte[][] yuvBytes) { - // Row stride is the total number of bytes occupied in memory by a row of an image. - // Because of the variable row stride it's not possible to know in - // advance the actual necessary dimensions of the yuv planes - for (int i = 0; i < planes.length; ++i) { - ByteBuffer buffer = planes[i].getBuffer(); - if (yuvBytes[i] == null) { - yuvBytes[i] = new byte[buffer.capacity()]; - } - buffer.get(yuvBytes[i]); - } + public void onClickSwitch(View view) { + poseNetFragment.switchCamera(); } - /** - * Crop Bitmap to maintain aspect ratio of model input. - */ - private Bitmap cropBitmap(Bitmap bitmap) { - float bitmapRatio = bitmap.getHeight() / bitmap.getWidth(); - float modelInputRatio = MODEL_HEIGHT / MODEL_WIDTH; - double maxDifference = 1.0E-5D; - float cropHeight = modelInputRatio - bitmapRatio; - - if (Math.abs(cropHeight) < maxDifference) { - return bitmap; - } else { - Bitmap croppedBitmap; - if (modelInputRatio < bitmapRatio) { - cropHeight = (float) bitmap.getHeight() - (float) bitmap.getWidth() / modelInputRatio; - croppedBitmap = Bitmap.createBitmap(bitmap, - 0, (int) (cropHeight / 2), bitmap.getWidth(), (int) (bitmap.getHeight() - cropHeight)); - } else { - cropHeight = (float) bitmap.getWidth() - (float) bitmap.getHeight() * modelInputRatio; - croppedBitmap = Bitmap.createBitmap(bitmap, - (int) (cropHeight / 2), 0, (int) (bitmap.getWidth() - cropHeight), bitmap.getHeight()); - } - return croppedBitmap; - } - } - - /** - * Set the paint color and size. - */ - private void setPaint() { - paint.setColor(getResources().getColor(R.color.text_blue)); - paint.setTextSize(80.0f); - paint.setStrokeWidth(8.0f); - } - - /** - * Draw bitmap on Canvas. - */ - private void draw(Canvas canvas, Posenet.Person person, Bitmap bitmap) { - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - // Draw `bitmap` and `person` in square canvas. - int screenWidth, screenHeight; - int left, right, top, bottom; - if (canvas.getHeight() > canvas.getWidth()) { - screenWidth = canvas.getWidth(); - screenHeight = canvas.getWidth(); - left = 0; - top = (canvas.getHeight() - canvas.getWidth()) / 2; - } else { - screenWidth = canvas.getHeight(); - screenHeight = canvas.getHeight(); - left = (canvas.getWidth() - canvas.getHeight()) / 2; - top = 0; - } - right = left + screenWidth; - bottom = top + screenHeight; - - setPaint(); - canvas.drawBitmap( - bitmap, - new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), - new Rect(left, top, right, bottom), paint); - - float widthRatio = (float) screenWidth / MODEL_WIDTH; - float heightRatio = (float) screenHeight / MODEL_HEIGHT; - - for (Posenet.KeyPoint keyPoint : person.keyPoints) { - if (keyPoint.score > minConfidence) { - Posenet.Position position = keyPoint.position; - float adjustedX = position.x * widthRatio + left; - float adjustedY = position.y * heightRatio + top; - canvas.drawCircle(adjustedX, adjustedY, circleRadius, paint); - } - } - - for (int i = 0; i < bodyJoints.size(); i++) { - Pair line = (Pair) bodyJoints.get(i); - Posenet.BodyPart first = (Posenet.BodyPart) line.first; - Posenet.BodyPart second = (Posenet.BodyPart) line.second; - - if (person.keyPoints.get(first.ordinal()).score > minConfidence & - person.keyPoints.get(second.ordinal()).score > minConfidence) { - canvas.drawLine( - person.keyPoints.get(first.ordinal()).position.x * widthRatio + left, - person.keyPoints.get(first.ordinal()).position.y * heightRatio + top, - person.keyPoints.get(second.ordinal()).position.x * widthRatio + left, - person.keyPoints.get(second.ordinal()).position.y * heightRatio + top, paint); - } - } - - canvas.drawText(String.format("Score: %.2f", person.score), - (15.0f * widthRatio), (30.0f * heightRatio + bottom), paint); - canvas.drawText(String.format("Time: %.2f ms", posenet.lastInferenceTimeNanos * 1.0f / 1_000_000), - (15.0f * widthRatio), (50.0f * heightRatio + bottom), paint - ); - - // Draw! - surfaceView.getHolder().unlockCanvasAndPost(canvas); - } - - /** - * Process image using Posenet library. - */ - private void processImage(Bitmap bitmap) { - // Crop bitmap. - Bitmap croppedBitmap = cropBitmap(bitmap); - // Created scaled version of bitmap for model input. - Bitmap scaledBitmap = Bitmap.createScaledBitmap(croppedBitmap, MODEL_WIDTH, MODEL_HEIGHT, true); - // Perform inference. - Posenet.Person person = posenet.estimateSinglePose(scaledBitmap); - Canvas canvas = surfaceView.getHolder().lockCanvas(); - draw(canvas, person, scaledBitmap); - } } \ No newline at end of file diff --git a/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/PoseNetFragment.java b/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/PoseNetFragment.java index 9b36f20813..32de03882a 100644 --- a/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/PoseNetFragment.java +++ b/model_zoo/official/lite/posenet/app/src/main/java/com/mindspore/posenetdemo/PoseNetFragment.java @@ -18,7 +18,14 @@ package com.mindspore.posenetdemo; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.Rect; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; @@ -42,29 +49,51 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.util.Pair; import androidx.fragment.app.Fragment; +import java.nio.ByteBuffer; import java.util.Arrays; +import java.util.List; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; +import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_ANKLE; +import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_ELBOW; +import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_HIP; +import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_KNEE; +import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_SHOULDER; +import static com.mindspore.posenetdemo.Posenet.BodyPart.LEFT_WRIST; +import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_ANKLE; +import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_ELBOW; +import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_HIP; +import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_KNEE; +import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_SHOULDER; +import static com.mindspore.posenetdemo.Posenet.BodyPart.RIGHT_WRIST; + /** * A simple {@link Fragment} subclass. * create an instance of this fragment. */ public class PoseNetFragment extends Fragment { + private final List bodyJoints = Arrays.asList( + new Pair(LEFT_WRIST, LEFT_ELBOW), new Pair(LEFT_ELBOW, LEFT_SHOULDER), + new Pair(LEFT_SHOULDER, RIGHT_SHOULDER), new Pair(RIGHT_SHOULDER, RIGHT_ELBOW), + new Pair(RIGHT_ELBOW, RIGHT_WRIST), new Pair(LEFT_SHOULDER, LEFT_HIP), + new Pair(LEFT_HIP, RIGHT_HIP), new Pair(RIGHT_HIP, RIGHT_SHOULDER), + new Pair(LEFT_HIP, LEFT_KNEE), new Pair(LEFT_KNEE, LEFT_ANKLE), + new Pair(RIGHT_HIP, RIGHT_KNEE), new Pair(RIGHT_KNEE, RIGHT_ANKLE)); + private static final String TAG = "PoseNetFragment"; - private String cameraId = "1"; + private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT; // 要打开的摄像头ID private SurfaceView surfaceView; private CameraCaptureSession captureSession; private CameraDevice cameraDevice; - private Size previewSize; - private int previewWidth; - private int previewHeight; - private final int PREVIEW_WIDTH = 640; - private final int PREVIEW_HEIGHT = 480; + private final static int PREVIEW_WIDTH = 640; + private final static int PREVIEW_HEIGHT = 480; + private Size previewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); private HandlerThread backgroundThread; private Handler backgroundHandler; private ImageReader imageReader; @@ -73,6 +102,19 @@ public class PoseNetFragment extends Fragment { private Semaphore cameraOpenCloseLock = new Semaphore(1);//使用信号量 Semaphore 进行多线程任务调度 private boolean flashSupported; + /** + * Model input shape for images. + */ + private final static int MODEL_WIDTH = 257; + private final static int MODEL_HEIGHT = 257; + + private final double minConfidence = 0.5; + private final float circleRadius = 8.0f; + private Paint paint = new Paint(); + private Posenet posenet; + private int[] rgbBytes = new int[PREVIEW_WIDTH * PREVIEW_HEIGHT]; + private byte[][] yuvBytes = new byte[3][]; + private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override @@ -87,12 +129,14 @@ public class PoseNetFragment extends Fragment { public void onDisconnected(@NonNull CameraDevice cameraDevice) { cameraOpenCloseLock.release(); cameraDevice.close(); + closeCamera(); PoseNetFragment.this.cameraDevice = null; } @Override public void onError(@NonNull CameraDevice cameraDevice, int error) { onDisconnected(cameraDevice); + closeCamera(); Activity activity = getActivity(); if (activity != null) { activity.finish(); @@ -112,12 +156,6 @@ public class PoseNetFragment extends Fragment { } }; - private CameraDataDealListener cameraDataDealListener; - - public void setCameraDataDealListener(CameraDataDealListener cameraDataDealListener) { - this.cameraDataDealListener = cameraDataDealListener; - } - public static PoseNetFragment newInstance() { PoseNetFragment fragment = new PoseNetFragment(); return fragment; @@ -148,57 +186,24 @@ public class PoseNetFragment extends Fragment { openCamera(); } + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + posenet = new Posenet(getActivity()); + + } + public void onPause() { this.closeCamera(); this.stopBackgroundThread(); super.onPause(); } - public void onDestroy() { - super.onDestroy(); - } - - - - /** - * Sets up member variables related to camera. - */ - private void setUpCameraOutputs() { - CameraManager manager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE); - try { - for (String cameraId : manager.getCameraIdList()) { - CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); - // We don't use a front facing camera in this sample. - Integer cameraDirection = characteristics.get(CameraCharacteristics.LENS_FACING); - if (cameraDirection != null && cameraDirection == CameraCharacteristics.LENS_FACING_FRONT) { - continue; - } - - previewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); - - imageReader = ImageReader.newInstance( - PREVIEW_WIDTH, PREVIEW_HEIGHT, - ImageFormat.YUV_420_888, /*maxImages*/ 2 - ); - - previewHeight = previewSize.getHeight(); - previewWidth = previewSize.getWidth(); - // Initialize the storage bitmaps once when the resolution is known. - - // Check if the flash is supported. - flashSupported = - characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true; - - this.cameraId = cameraId; - - // We've found a viable camera and finished setting up member variables, - // so we don't need to iterate through other available cameras. - } - } catch (CameraAccessException e) { - e.printStackTrace(); - } catch (NullPointerException e) { - e.printStackTrace(); - } + public void switchCamera() { + mCameraId ^= 1; + Log.d(TAG, "switchCamera: mCameraId: " + mCameraId); + closeCamera(); + openCamera(); } /** @@ -206,14 +211,23 @@ public class PoseNetFragment extends Fragment { */ @SuppressLint("MissingPermission") private void openCamera() { - setUpCameraOutputs(); CameraManager manager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE); try { + CameraCharacteristics characteristics = manager.getCameraCharacteristics(Integer.toString(mCameraId)); + previewSize = new Size(PREVIEW_WIDTH, PREVIEW_HEIGHT); + imageReader = ImageReader.newInstance( + PREVIEW_WIDTH, PREVIEW_HEIGHT, + ImageFormat.YUV_420_888, /*maxImages*/ 2 + ); + imageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler); + // Check if the flash is supported. + flashSupported = + characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true; // Wait for camera to open - 2.5 seconds is sufficient if (!cameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { throw new RuntimeException("Time out waiting to lock camera opening."); } - manager.openCamera(cameraId, mStateCallback, backgroundHandler); + manager.openCamera(Integer.toString(mCameraId), mStateCallback, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } catch (InterruptedException e) { @@ -266,31 +280,48 @@ public class PoseNetFragment extends Fragment { } } - private final ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader imageReader) { - if (previewWidth != 0 && previewHeight != 0 && imageReader != null) { + if (imageReader != null) { Image image = imageReader.acquireLatestImage(); - - if (cameraDataDealListener != null) { - cameraDataDealListener.dataDeal(image, surfaceView); + if (image == null || image.getPlanes() == null) { + return; + } + fillBytes(image.getPlanes(), yuvBytes); + ImageUtils.convertYUV420ToARGB8888(yuvBytes[0], yuvBytes[1], yuvBytes[2], + PREVIEW_WIDTH, PREVIEW_HEIGHT, + image.getPlanes()[0].getRowStride(), + image.getPlanes()[1].getRowStride(), + image.getPlanes()[1].getPixelStride(), + rgbBytes); + + Bitmap imageBitmap = Bitmap.createBitmap( + rgbBytes, PREVIEW_WIDTH, PREVIEW_HEIGHT, + Bitmap.Config.ARGB_8888); + Matrix rotateMatrix = new Matrix(); + if (mCameraId == CameraCharacteristics.LENS_FACING_FRONT) { + rotateMatrix.postRotate(90.0f); + } else if (mCameraId == CameraCharacteristics.LENS_FACING_BACK) { + rotateMatrix.postRotate(270.0f); + rotateMatrix.postScale(-1.0f, 1.0f); } + + Bitmap rotatedBitmap = Bitmap.createBitmap( + imageBitmap, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT, + rotateMatrix, true + ); + processImage(rotatedBitmap); + image.close(); } } }; - /** * Creates a new [CameraCaptureSession] for camera preview. */ private void createCameraPreviewSession() { try { - // We capture images from preview in YUV format. - imageReader = ImageReader.newInstance( - previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2); - imageReader.setOnImageAvailableListener(imageAvailableListener, backgroundHandler); - // This is the surface we need to record images for processing. Surface recordingSurface = imageReader.getSurface(); @@ -348,4 +379,136 @@ public class PoseNetFragment extends Fragment { } } + + /** + * Fill the yuvBytes with data from image planes. + */ + private void fillBytes(Image.Plane[] planes, byte[][] yuvBytes) { + // Row stride is the total number of bytes occupied in memory by a row of an image. + // Because of the variable row stride it's not possible to know in + // advance the actual necessary dimensions of the yuv planes + for (int i = 0; i < planes.length; ++i) { + ByteBuffer buffer = planes[i].getBuffer(); + if (yuvBytes[i] == null) { + yuvBytes[i] = new byte[buffer.capacity()]; + } + buffer.get(yuvBytes[i]); + } + } + + /** + * Crop Bitmap to maintain aspect ratio of model input. + */ + private Bitmap cropBitmap(Bitmap bitmap) { + float bitmapRatio = bitmap.getHeight() / bitmap.getWidth(); + float modelInputRatio = MODEL_HEIGHT / MODEL_WIDTH; + double maxDifference = 1.0E-5D; + float cropHeight = modelInputRatio - bitmapRatio; + + if (Math.abs(cropHeight) < maxDifference) { + return bitmap; + } else { + Bitmap croppedBitmap; + if (modelInputRatio < bitmapRatio) { + cropHeight = (float) bitmap.getHeight() - (float) bitmap.getWidth() / modelInputRatio; + croppedBitmap = Bitmap.createBitmap(bitmap, + 0, (int) (cropHeight / 2), bitmap.getWidth(), (int) (bitmap.getHeight() - cropHeight)); + } else { + cropHeight = (float) bitmap.getWidth() - (float) bitmap.getHeight() * modelInputRatio; + croppedBitmap = Bitmap.createBitmap(bitmap, + (int) (cropHeight / 2), 0, (int) (bitmap.getWidth() - cropHeight), bitmap.getHeight()); + } + return croppedBitmap; + } + } + + /** + * Set the paint color and size. + */ + private void setPaint() { + paint.setColor(getResources().getColor(R.color.text_blue)); + paint.setTextSize(80.0f); + paint.setStrokeWidth(8.0f); + } + + /** + * Draw bitmap on Canvas. + */ + private void draw(Canvas canvas, Posenet.Person person, Bitmap bitmap) { + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + // Draw `bitmap` and `person` in square canvas. + int screenWidth, screenHeight; + int left, right, top, bottom; + if (canvas.getHeight() > canvas.getWidth()) { + screenWidth = canvas.getWidth(); + screenHeight = canvas.getWidth(); + left = 0; + top = (canvas.getHeight() - canvas.getWidth()) / 2; + } else { + screenWidth = canvas.getHeight(); + screenHeight = canvas.getHeight(); + left = (canvas.getWidth() - canvas.getHeight()) / 2; + top = 0; + } + right = left + screenWidth; + bottom = top + screenHeight; + + setPaint(); + canvas.drawBitmap( + bitmap, + new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), + new Rect(left, top, right, bottom), paint); + + float widthRatio = (float) screenWidth / MODEL_WIDTH; + float heightRatio = (float) screenHeight / MODEL_HEIGHT; + + for (Posenet.KeyPoint keyPoint : person.keyPoints) { + if (keyPoint.score > minConfidence) { + Posenet.Position position = keyPoint.position; + float adjustedX = position.x * widthRatio + left; + float adjustedY = position.y * heightRatio + top; + canvas.drawCircle(adjustedX, adjustedY, circleRadius, paint); + } + } + + for (int i = 0; i < bodyJoints.size(); i++) { + Pair line = (Pair) bodyJoints.get(i); + Posenet.BodyPart first = (Posenet.BodyPart) line.first; + Posenet.BodyPart second = (Posenet.BodyPart) line.second; + + if (person.keyPoints.get(first.ordinal()).score > minConfidence & + person.keyPoints.get(second.ordinal()).score > minConfidence) { + canvas.drawLine( + person.keyPoints.get(first.ordinal()).position.x * widthRatio + left, + person.keyPoints.get(first.ordinal()).position.y * heightRatio + top, + person.keyPoints.get(second.ordinal()).position.x * widthRatio + left, + person.keyPoints.get(second.ordinal()).position.y * heightRatio + top, paint); + } + } + + canvas.drawText(String.format("Score: %.2f", person.score), + (15.0f * widthRatio), (30.0f * heightRatio + bottom), paint); + canvas.drawText(String.format("Time: %.2f ms", posenet.lastInferenceTimeNanos * 1.0f / 1_000_000), + (15.0f * widthRatio), (50.0f * heightRatio + bottom), paint + ); + + // Draw! + surfaceView.getHolder().unlockCanvasAndPost(canvas); + } + + /** + * Process image using Posenet library. + */ + private void processImage(Bitmap bitmap) { + // Crop bitmap. + Bitmap croppedBitmap = cropBitmap(bitmap); + // Created scaled version of bitmap for model input. + Bitmap scaledBitmap = Bitmap.createScaledBitmap(croppedBitmap, MODEL_WIDTH, MODEL_HEIGHT, true); + // Perform inference. + Posenet.Person person = posenet.estimateSinglePose(scaledBitmap); + Canvas canvas = surfaceView.getHolder().lockCanvas(); + draw(canvas, person, scaledBitmap); + } + + } \ No newline at end of file diff --git a/model_zoo/official/lite/posenet/app/src/main/res/drawable-xxhdpi/ic_camera_switch.png b/model_zoo/official/lite/posenet/app/src/main/res/drawable-xxhdpi/ic_camera_switch.png new file mode 100644 index 0000000000..8900137c88 Binary files /dev/null and b/model_zoo/official/lite/posenet/app/src/main/res/drawable-xxhdpi/ic_camera_switch.png differ diff --git a/model_zoo/official/lite/posenet/app/src/main/res/layout/activity_main.xml b/model_zoo/official/lite/posenet/app/src/main/res/layout/activity_main.xml index c91bccecd6..45b67bfbd9 100644 --- a/model_zoo/official/lite/posenet/app/src/main/res/layout/activity_main.xml +++ b/model_zoo/official/lite/posenet/app/src/main/res/layout/activity_main.xml @@ -19,7 +19,7 @@ android:background="#66000000"> + + \ No newline at end of file diff --git a/model_zoo/official/lite/style_transfer/app/src/main/AndroidManifest.xml b/model_zoo/official/lite/style_transfer/app/src/main/AndroidManifest.xml index ae1416f3e8..4085322423 100644 --- a/model_zoo/official/lite/style_transfer/app/src/main/AndroidManifest.xml +++ b/model_zoo/official/lite/style_transfer/app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -34,6 +35,18 @@ + + + + \ No newline at end of file diff --git a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/BitmapUtils.java b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/BitmapUtils.java index c8b2e3384c..1860a3a155 100644 --- a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/BitmapUtils.java +++ b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/BitmapUtils.java @@ -89,7 +89,7 @@ public class BitmapUtils { } // Scale pictures to screen width. - private static Bitmap zoomImage(Bitmap imageBitmap, int targetWidth, int maxHeight) { + public static Bitmap zoomImage(Bitmap imageBitmap, int targetWidth, int maxHeight) { float scaleFactor = Math.max( (float) imageBitmap.getWidth() / (float) targetWidth, @@ -104,6 +104,26 @@ public class BitmapUtils { return resizedBitmap; } + public static Bitmap changeBitmapSize(Bitmap bitmap, int targetWidth, int targetHeight) { + int width = bitmap.getWidth(); + int height = bitmap.getHeight(); + Log.e("width", "width:" + width); + Log.e("height", "height:" + height); + + float scaleWidth = ((float) targetWidth) / width; + float scaleHeight = ((float) targetHeight) / height; + + Matrix matrix = new Matrix(); + matrix.postScale(scaleWidth, scaleHeight); + + bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); + bitmap.getWidth(); + bitmap.getHeight(); + Log.e("newWidth", "newWidth" + bitmap.getWidth()); + Log.e("newHeight", "newHeight" + bitmap.getHeight()); + return bitmap; + } + /** * Get the rotation angle of the photo. * diff --git a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/ImageUtils.java b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/ImageUtils.java index 6bffde0db0..ce651d7522 100644 --- a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/ImageUtils.java +++ b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/ImageUtils.java @@ -16,16 +16,24 @@ package com.mindspore.styletransferdemo; import android.content.Context; +import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.RectF; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.util.Log; import androidx.annotation.NonNull; import androidx.exifinterface.media.ExifInterface; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; @@ -33,6 +41,8 @@ import java.nio.ByteOrder; public class ImageUtils { + private static final String TAG = "ImageUtils"; + private static Matrix decodeExifOrientation(int orientation) { Matrix matrix = new Matrix(); @@ -198,4 +208,59 @@ public class ImageUtils { } return ret; } + + // Save the picture to the system album and refresh it. + public static void saveToAlbum(final Context context, Bitmap bitmap) { + File file = null; + String fileName = System.currentTimeMillis() + ".jpg"; + File root = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), context.getPackageName()); + File dir = new File(root, "image"); + if (dir.mkdirs() || dir.isDirectory()) { + file = new File(dir, fileName); + } + FileOutputStream os = null; + try { + os = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os); + os.flush(); + + } catch (FileNotFoundException e) { + Log.e(TAG, e.getMessage()); + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } finally { + try { + if (os != null) { + os.close(); + } + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + } + if (file == null) { + return; + } + // Gallery refresh. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + String path = null; + try { + path = file.getCanonicalPath(); + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + MediaScannerConnection.scanFile(context, new String[]{path}, null, + new MediaScannerConnection.OnScanCompletedListener() { + @Override + public void onScanCompleted(String path, Uri uri) { + Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + mediaScanIntent.setData(uri); + context.sendBroadcast(mediaScanIntent); + } + }); + } else { + String relationDir = file.getParent(); + File file1 = new File(relationDir); + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.fromFile(file1.getAbsoluteFile()))); + } + } } \ No newline at end of file diff --git a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/MainActivity.java b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/MainActivity.java index 9156890a7e..c5b828cef0 100644 --- a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/MainActivity.java +++ b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/MainActivity.java @@ -16,50 +16,74 @@ package com.mindspore.styletransferdemo; import android.Manifest; +import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.provider.MediaStore; -import android.text.TextUtils; +import android.provider.Settings; import android.util.Log; import android.util.Pair; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; +import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; -public class MainActivity extends AppCompatActivity implements View.OnClickListener, StyleFragment.OnListFragmentInteractionListener { +import java.io.File; +import java.io.FileNotFoundException; + +public class MainActivity extends AppCompatActivity implements OnBackgroundImageListener { private static final String TAG = "MainActivity"; + private static final int[] IMAGES = {R.drawable.style0, R.drawable.style1, R.drawable.style2, R.drawable.style3, R.drawable.style4, + R.drawable.style5, R.drawable.style6, R.drawable.style7, R.drawable.style8, R.drawable.style9, + R.drawable.style10, R.drawable.style11, R.drawable.style12, R.drawable.style13, R.drawable.style14, + R.drawable.style15, R.drawable.style16, R.drawable.style17, R.drawable.style18, R.drawable.style19, R.drawable.add}; + + 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 = 2; + private static final int RC_CHOOSE_PHOTO_FOR_BACKGROUND = 3; + private static final int RC_CHOOSE_CAMERA = 4; + private boolean isAllGranted; private StyleTransferModelExecutor transferModelExecutor; - private boolean isHasPermssion; private boolean isRunningModel; - private ImageView imgOrigin, imgStyle, imgResult; - private ProgressBar progressResult; + private ImageView imgPreview; private Uri imageUri; + private TextView textOriginImage; + private ProgressBar progressBar; + + private RecyclerView recyclerView; private Integer maxWidthOfImage; private Integer maxHeightOfImage; private boolean isLandScape; - private Bitmap originBitmap, styleBitmap; - private StyleFragment styleFragment; - private String selectedStyle; + private Bitmap originBitmap, styleBitmap, resultBitmap; @Override protected void onCreate(Bundle savedInstanceState) { @@ -71,23 +95,35 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe } private void init() { - imgOrigin = findViewById(R.id.img_origin); - imgStyle = findViewById(R.id.img_style); - imgResult = findViewById(R.id.img_result); - progressResult = findViewById(R.id.progress_circular); - - imgOrigin.setOnClickListener(this); - imgStyle.setOnClickListener(this); - imgResult.setOnClickListener(this); + imgPreview = findViewById(R.id.img_origin); + textOriginImage = findViewById(R.id.tv_image); + progressBar = findViewById(R.id.progress); + recyclerView = findViewById(R.id.recyclerview); - styleFragment = StyleFragment.newInstance(); + recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); + recyclerView.setAdapter(new StyleRecyclerViewAdapter(this, IMAGES, this)); transferModelExecutor = new StyleTransferModelExecutor(this, false); } private void requestPermissions() { - ActivityCompat.requestPermissions(this, - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.READ_PHONE_STATE, Manifest.permission.CAMERA}, REQUEST_PERMISSION); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + isAllGranted = checkPermissionAllGranted(PERMISSIONS); + if (!isAllGranted) { + ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSION); + } + } else { + isAllGranted = true; + } + } + + + private boolean checkPermissionAllGranted(String[] permissions) { + for (String permission : permissions) { + if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + return true; } /** @@ -96,43 +132,115 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (REQUEST_PERMISSION == requestCode) { - isHasPermssion = true; + isAllGranted = true; + + for (int grant : grantResults) { + if (grant != PackageManager.PERMISSION_GRANTED) { + isAllGranted = false; + break; + } + } + if (!isAllGranted) { + openAppDetails(); + } } } - - @Override - public void onClick(View view) { - if (view.getId() == R.id.img_origin) { - if (isHasPermssion) { - openGallay(); - } else { - requestPermissions(); - } - } else if (view.getId() == R.id.img_style) { - if (!isRunningModel) { - styleFragment.show(getSupportFragmentManager(), TAG); + 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(); + } + + + public void onClickPhoto(View view) { + if (isAllGranted) { + openGallay(RC_CHOOSE_PHOTO); + textOriginImage.setVisibility(View.GONE); + } else { + requestPermissions(); + } + } + + public void onClickCamera(View view) { + if (isAllGranted) { + openCamera(); + textOriginImage.setVisibility(View.GONE); + } else { + requestPermissions(); + } + } + + public void onClickRecovery(View view) { + if (originBitmap != null) { + Glide.with(this).load(originBitmap).into(imgPreview); + } else { + Toast.makeText(this, "Please select an original picture first", Toast.LENGTH_SHORT).show(); } } - private void openGallay() { + public void onClickSave(View view) { + if (this.resultBitmap == null) { + Log.e(TAG, "null processed image"); + Toast.makeText(this.getApplicationContext(), R.string.no_pic_neededSave, Toast.LENGTH_SHORT).show(); + } else { + ImageUtils.saveToAlbum(getApplicationContext(), this.resultBitmap); + Toast.makeText(this.getApplicationContext(), R.string.save_success, Toast.LENGTH_SHORT).show(); + } + } + + private void openGallay(int request) { Intent intentToPickPic = new Intent(Intent.ACTION_PICK, null); intentToPickPic.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); - startActivityForResult(intentToPickPic, RC_CHOOSE_PHOTO); + startActivityForResult(intentToPickPic, request); + } + + private void openCamera() { + if (isAllGranted) { + Intent intentToTakePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + String mTempPhotoPath = Environment.getExternalStorageDirectory() + File.separator + "photo.jpeg"; + imageUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".fileprovider", new File(mTempPhotoPath)); + intentToTakePhoto.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); + startActivityForResult(intentToTakePhoto, RC_CHOOSE_CAMERA); + } else { + requestPermissions(); + } } @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) { - this.imageUri = data.getData(); - showOriginImage(); + if (resultCode == RESULT_OK) { + if (RC_CHOOSE_PHOTO == requestCode) { + if (null != data && null != data.getData()) { + this.imageUri = data.getData(); + showOriginImage(); + } else { + finish(); + } + } else if (RC_CHOOSE_PHOTO_FOR_BACKGROUND == requestCode) { + if (null != data && null != data.getData()) { + showCustomBack(data.getData()); + } else { + finish(); + } + } else if (RC_CHOOSE_CAMERA == requestCode) { + showOriginCamera(); } - } else { - finish(); } } @@ -140,56 +248,81 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe Pair targetedSize = this.getTargetSize(); int targetWidth = targetedSize.first; int maxHeight = targetedSize.second; - originBitmap = BitmapUtils.loadFromPath(MainActivity.this, imageUri, targetWidth, maxHeight); + 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()); + Log.e(TAG, "resized image size width:" + originBitmap.getWidth() + ",height: " + originBitmap.getHeight()); + if (originBitmap != null) { + Glide.with(this).load(originBitmap).into(imgPreview); + } + } + private void showOriginCamera() { + try { + Pair targetedSize = this.getTargetSize(); + int targetWidth = targetedSize.first; + int maxHeight = targetedSize.second; + Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri)); + originBitmap = BitmapUtils.zoomImage(bitmap, targetWidth, maxHeight); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + // Determine how much to scale down the image. + Log.e(TAG, "resized image size width:" + originBitmap.getWidth() + ",height: " + originBitmap.getHeight()); if (originBitmap != null) { - Glide.with(this).load(originBitmap).into(imgOrigin); + Glide.with(this).load(originBitmap).into(imgPreview); } } + private void showCustomBack(Uri imageUri) { + Pair targetedSize = this.getTargetSize(); + int targetWidth = targetedSize.first; + int maxHeight = targetedSize.second; + styleBitmap = BitmapUtils.loadFromPath(this, imageUri, targetWidth, maxHeight); + startRunningModel(styleBitmap); + } + + @Override + public void onBackImageSelected(int position) { + styleBitmap = BitmapFactory.decodeResource(getResources(), IMAGES[position]); + startRunningModel(styleBitmap); + } @Override - public void onListFragmentInteraction(String item) { - this.selectedStyle = item; - styleFragment.dismiss(); - startRunningModel(); - } - - private void startRunningModel() { - if (!isRunningModel && !TextUtils.isEmpty(selectedStyle)) { - styleBitmap = ImageUtils.loadBitmapFromResources(this, getUriFromAssetThumb(selectedStyle)); - Glide.with(this) - .load(styleBitmap) - .into(imgStyle); - - if (originBitmap == null) { - Toast.makeText(this, "Please select an original picture first", Toast.LENGTH_SHORT).show(); - return; - } - progressResult.setVisibility(View.VISIBLE); + public void onImageAdd(View view) { + openGallay(RC_CHOOSE_PHOTO_FOR_BACKGROUND); + } + + private void startRunningModel(Bitmap styleBitmap) { + if (originBitmap == null) { + Toast.makeText(this, "Please select an original picture first", Toast.LENGTH_SHORT).show(); + return; + } + + if (!isRunningModel) { isRunningModel = true; + progressBar.setVisibility(View.VISIBLE); ModelExecutionResult result = transferModelExecutor.execute(originBitmap, styleBitmap); - Glide.with(this).load(result.getStyledImage()).into(imgResult); - progressResult.setVisibility(View.GONE); + if (null != result && null != result.getStyledImage()) { + resultBitmap = BitmapUtils.changeBitmapSize(result.getStyledImage(), originBitmap.getWidth(), originBitmap.getHeight()); + Log.e("AAA", "w>>" + resultBitmap.getWidth() + ">>>h>>" + resultBitmap.getHeight()); + Glide.with(this).load(resultBitmap).override(resultBitmap.getWidth(), resultBitmap.getHeight()).into(imgPreview); + } else { + Toast.makeText(this, "ModelExecute failed", Toast.LENGTH_SHORT).show(); + } isRunningModel = false; + progressBar.setVisibility(View.INVISIBLE); } else { Toast.makeText(this, "Previous Model still running", Toast.LENGTH_SHORT).show(); } } - private String getUriFromAssetThumb(String thumb) { - return "thumbnails/" + thumb; - } - // Returns max width of image. private Integer getMaxWidthOfImage() { if (this.maxWidthOfImage == null) { if (this.isLandScape) { - this.maxWidthOfImage = ((View) this.imgOrigin.getParent()).getHeight(); + this.maxWidthOfImage = ((View) this.imgPreview.getParent()).getHeight(); } else { - this.maxWidthOfImage = ((View) this.imgOrigin.getParent()).getWidth(); + this.maxWidthOfImage = ((View) this.imgPreview.getParent()).getWidth(); } } return this.maxWidthOfImage; @@ -199,9 +332,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe private Integer getMaxHeightOfImage() { if (this.maxHeightOfImage == null) { if (this.isLandScape) { - this.maxHeightOfImage = ((View) this.imgOrigin.getParent()).getWidth(); + this.maxHeightOfImage = ((View) this.imgPreview.getParent()).getWidth(); } else { - this.maxHeightOfImage = ((View) this.imgOrigin.getParent()).getHeight(); + this.maxHeightOfImage = ((View) this.imgPreview.getParent()).getHeight(); } } return this.maxHeightOfImage; @@ -219,5 +352,4 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe return new Pair<>(targetWidth, targetHeight); } - } \ No newline at end of file diff --git a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/OnBackgroundImageListener.java b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/OnBackgroundImageListener.java new file mode 100644 index 0000000000..b9cdfb912a --- /dev/null +++ b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/OnBackgroundImageListener.java @@ -0,0 +1,9 @@ +package com.mindspore.styletransferdemo; + +import android.view.View; + +public interface OnBackgroundImageListener { + void onBackImageSelected(int position); + + void onImageAdd(View view); +} diff --git a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleFragment.java b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleFragment.java deleted file mode 100644 index 5171d14c05..0000000000 --- a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleFragment.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright 2020 Huawei Technologies Co., Ltd - *

- * 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 - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.styletransferdemo; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * A simple {@link Fragment} subclass. - * Use the {@link StyleFragment#newInstance} factory method to - * create an instance of this fragment. - */ -public class StyleFragment extends DialogFragment { - - private OnListFragmentInteractionListener listener; - - public StyleFragment() { - // Required empty public constructor - } - - - public static StyleFragment newInstance() { - StyleFragment fragment = new StyleFragment(); - return fragment; - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_style, container, false); - List styles = new ArrayList<>(); - try { - styles.addAll(Arrays.asList(getActivity().getAssets().list("thumbnails"))); - } catch (IOException e) { - e.printStackTrace(); - } - - if (view instanceof RecyclerView) { - GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 3); - ((RecyclerView) view).setLayoutManager(gridLayoutManager); - ((RecyclerView) view).setAdapter(new StyleRecyclerViewAdapter(getActivity(), styles, listener)); - } - - return view; - } - - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - if (context instanceof OnListFragmentInteractionListener) { - this.listener = (StyleFragment.OnListFragmentInteractionListener) context; - } - } - - public void onDetach() { - super.onDetach(); - this.listener = null; - } - - public interface OnListFragmentInteractionListener { - void onListFragmentInteraction(String item); - } -} \ No newline at end of file diff --git a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleRecyclerViewAdapter.java b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleRecyclerViewAdapter.java index 523be83177..4417828528 100644 --- a/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleRecyclerViewAdapter.java +++ b/model_zoo/official/lite/style_transfer/app/src/main/java/com/mindspore/styletransferdemo/StyleRecyclerViewAdapter.java @@ -16,7 +16,6 @@ package com.mindspore.styletransferdemo; import android.content.Context; -import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,35 +26,16 @@ import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.Glide; -import java.util.List; - public class StyleRecyclerViewAdapter extends RecyclerView.Adapter { - private View.OnClickListener mOnClickListener; - private List stylesList; - private Context context; - private StyleFragment.OnListFragmentInteractionListener mListener; + private final int[] IMAGES; + private final Context context; + private final OnBackgroundImageListener mListener; - public StyleRecyclerViewAdapter(Context context, List stylesList, StyleFragment.OnListFragmentInteractionListener mListener) { - this.stylesList = stylesList; + public StyleRecyclerViewAdapter(Context context, int[] IMAGES, OnBackgroundImageListener mListener) { + this.IMAGES = IMAGES; this.context = context; this.mListener = mListener; - - this.mOnClickListener = new View.OnClickListener() { - @Override - public void onClick(View view) { - - } - }; - - this.mOnClickListener = (View.OnClickListener) (new View.OnClickListener() { - public final void onClick(View v) { - - if (v.getTag() != null && v.getTag() instanceof String) { - mListener.onListFragmentInteraction(String.valueOf(v.getTag())); - } - } - }); } @NonNull @@ -68,21 +48,27 @@ public class StyleRecyclerViewAdapter extends RecyclerView.Adapter { + if (mListener != null) { + if (IMAGES.length - 1 == position) { + mListener.onImageAdd(holder.getImageView()); + } else { + mListener.onBackImageSelected(position); + } + } + }); } @Override public int getItemCount() { - return stylesList == null ? 0 : stylesList.size(); + return IMAGES == null ? 0 : IMAGES.length; } diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/add.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/add.jpg new file mode 100644 index 0000000000..bdfe6d7518 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/add.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style0.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style0.jpg new file mode 100644 index 0000000000..8d0cab6a99 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style0.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style1.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style1.jpg new file mode 100644 index 0000000000..5337b50dad Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style1.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style10.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style10.jpg new file mode 100644 index 0000000000..d84b9fe27a Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style10.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style11.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style11.jpg new file mode 100644 index 0000000000..017dfe27b5 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style11.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style12.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style12.jpg new file mode 100644 index 0000000000..4f5b90cea7 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style12.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style13.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style13.jpg new file mode 100644 index 0000000000..2411f78fd9 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style13.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style14.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style14.jpg new file mode 100644 index 0000000000..2665943019 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style14.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style15.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style15.jpg new file mode 100644 index 0000000000..6256956784 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style15.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style16.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style16.jpg new file mode 100644 index 0000000000..7356c927c4 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style16.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style17.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style17.jpg new file mode 100644 index 0000000000..f1194aa62f Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style17.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style18.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style18.jpg new file mode 100644 index 0000000000..519b9e7fbe Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style18.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style19.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style19.jpg new file mode 100644 index 0000000000..23849a8b65 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style19.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style2.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style2.jpg new file mode 100644 index 0000000000..e28061a2ba Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style2.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style20.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style20.jpg new file mode 100644 index 0000000000..38dc18b0ee Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style20.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style3.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style3.jpg new file mode 100644 index 0000000000..d4279dc7d0 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style3.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style4.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style4.jpg new file mode 100644 index 0000000000..3a1ef03747 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style4.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style5.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style5.jpg new file mode 100644 index 0000000000..a9d1051944 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style5.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style6.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style6.jpg new file mode 100644 index 0000000000..fc02154c1c Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style6.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style7.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style7.jpg new file mode 100644 index 0000000000..74b046d50b Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style7.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style8.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style8.jpg new file mode 100644 index 0000000000..3a5c7fdcc8 Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style8.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style9.jpg b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style9.jpg new file mode 100644 index 0000000000..2c3ae1708b Binary files /dev/null and b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable-xxhdpi/style9.jpg differ diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/drawable/progressbar.xml b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable/progressbar.xml new file mode 100644 index 0000000000..d48a929d88 --- /dev/null +++ b/model_zoo/official/lite/style_transfer/app/src/main/res/drawable/progressbar.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/model_zoo/official/lite/style_transfer/app/src/main/res/layout/activity_main.xml b/model_zoo/official/lite/style_transfer/app/src/main/res/layout/activity_main.xml index 1fb47efc49..3f7dc5cb3d 100644 --- a/model_zoo/official/lite/style_transfer/app/src/main/res/layout/activity_main.xml +++ b/model_zoo/official/lite/style_transfer/app/src/main/res/layout/activity_main.xml @@ -1,11 +1,9 @@ + android:background="@color/colorPrimary" + android:orientation="vertical"> - + android:layout_height="300dp"> - + android:layout_gravity="center" + android:layout_margin="10dp" + android:scaleType="fitXY" /> - + - - + + - - + - +