今天给大家分享一个好玩的项目app,该app和上一个博客的效果有点类似,不同的是在该博客中加入了目标检测部分。首先来看一下效果预览:
手掌特效app
介绍一下主要流程,首先使用yolov5训练一个识别手掌的模型,然后准备好需要播放的特效视频。获取摄像头画面进行目标检测,检测到手掌正面以后,在手掌的矩形框内播放特效视频。
使用yolov5训练模型网上教程有很多,这里不再详细叙述。使用的数据集是本人使用手机拍摄的,一共400张左右,一共分为3个类别,分别是拳头;正面;反面。数据集已经标注完成。如有需要可前往下载
数据集下载地址:
链接:
提取码:mk9o
使用的特效视频是直接在快手和抖音上面下载的。部分特效视频如下所示:
螺旋丸特效视频:
Mainactivity.java代码:
app.handfire2;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import Camera;
import CameraControl;
import CameraSelector;
import ImageAnalysis;
import ImageCapture;
import ImageProxy;
import Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
app.ActivityCompat;
ontent.ContextCompat;import android.annotation.SuppressLint;
t.pm.PackageManager;
aphics.Bitmap;
aphics.BitmapFactory;
aphics.ImageFormat;
aphics.PixelFormat;
aphics.Rect;
aphics.YuvImage;
dia.MediaPlayer;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;urrent.ListenableFuture;
app.handfire2.databinding.ActivityMainBinding;import org.jetbrains.annotations.NotNull;import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import urrent.ExecutionException;
import urrent.Executor;
import urrent.Executors;public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("native-lib");}private ActivityMainBinding binding;public static MyRenderer myRenderer;private GLSurfaceView glSurfaceView;private Spinner spinner;private Myview myview;private final String[] REQUIRED_PERMISSIONS = new String[]{"android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE"};private int REQUEST_CODE_PERMISSIONS = 1001;PreviewView pvCameraPreview;private Yolov5n Yolov5Net=new Yolov5n();private int[] texiao={R.raw.chuizi,R.raw.fire,R.raw.hunhuan,R.raw.qianniao,R.raw.wanzi,R.raw.wanzi2};@Overrideprotected void onCreate(Bundle savedInstanceState) {Create(savedInstanceState);boolean init=Yolov5Net.Init(getAssets());binding = ActivityMainBinding.inflate(getLayoutInflater());Root());myview=binding.view;spinner=binding.spin;spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {myRenderer.start(texiao[position]);}@Overridepublic void onNothingSelected(AdapterView<?> parent) {}});glSurfaceView=binding.glview;glSurfaceView.setEGLContextClientVersion(2);//背景透明glSurfaceView.setEGLConfigChooser(8,8,8,8,16,0);Holder().setFormat(PixelFormat.TRANSLUCENT);glSurfaceView.setZOrderOnTop(true);MediaPlayer = new MediaPlayer();myRenderer=new MyRenderer(this);glSurfaceView.setRenderer(myRenderer);//myRenderer.start(texiao[0]);
//
// button=binding.btn;
// button.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// //myRenderer.start("");
// Log.i("aa","click");
//
// }
// });pvCameraPreview=binding.preview;//获取权限if(allPermissionsGranted()){startCamera(); //start camera if permission has been granted by user} else{questPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);}}//获取权限函数private boolean allPermissionsGranted() {for (String permission : REQUIRED_PERMISSIONS) {if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {return false;}}return true;}/*** 开始预览*/private CameraControl cameraControl;private Executor executor = wSingleThreadExecutor();private void startCamera() {ListenableFuture<ProcessCameraProvider> cameraProviderFuture Instance(this);((ListenableFuture<?>) cameraProviderFuture).addListener(new Runnable() {@SuppressLint("RestrictedApi")@Overridepublic void run() {try {ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()//.setBackpressureStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER)//阻塞模式//.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)//.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888).build();imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {@Overridepublic void analyze(@NonNull @NotNull ImageProxy image) {//yuv图像数据转bitmapImageProxy.PlaneProxy[] planes = Planes();//cameraX 获取yuvByteBuffer yBuffer = planes[0].getBuffer();ByteBuffer uBuffer = planes[1].getBuffer();ByteBuffer vBuffer = planes[2].getBuffer();int ySize = aining();int uSize = aining();int vSize = aining();byte[] nv21 = new byte[ySize + uSize + vSize];(nv21, 0, ySize);(nv21, ySize, vSize);(nv21, ySize + vSize, uSize);//获取yuvImageYuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, Width(), Height(), null);//输出流ByteArrayOutputStream out = new ByteArrayOutputStream();//压缩写入outyuvImagepressToJpeg(new Rect(0, 0, Width(), Height()), 50, out);//转数组byte[] imageBytes = ByteArray();//生成bitmapBitmap bmp = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);// Bitmap rotateBitmap=null;Dector(bmp);image.close();}});//将相机的生命周期和activity的生命周期绑定,camerax 会自己释放ProcessCameraProvider cameraProvider = ();Preview preview = new Preview.Builder().build();//创建图片的 captureImageCapture mImageCapture = new ImageCapture.Builder().setFlashMode(ImageCapture.FLASH_MODE_OFF).build();//选择前置摄像头CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();// Unbind use cases before rebindingcameraProvider.unbindAll();// Bind use cases to camera//参数中如果有mImageCapture才能拍照,否则会报下错//Not bound to a valid Camera [ImageCapture:ImageCapture-bce6e930-b637-40ee-b9b9-Camera camera = cameraProvider.bindToLifecycle(MainActivity.this, cameraSelector, preview, imageAnalysis,mImageCapture);cameraControl = CameraControl();cameraControl.setLinearZoom(0.1f);preview.SurfaceProvider());} catch (ExecutionException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}}, MainExecutor(this));}private void setFrame() {}/*** 检测函数*/private void Dector(Bitmap bitmap) {// draw objects on bitmapBitmap rgba = py(Bitmap.Config.ARGB_8888, true);Yolov5n.Obj[] objects = Yolov5Net.Detect(rgba, false, 0.25f);float width = Width();float height = Height();myview.draws(objects,width,height,true,false);}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android=""xmlns:app=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.camera.view.PreviewViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/preview"/><android.opengl.GLSurfaceViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/glview"/>&app.handfire2.Myviewandroid:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/view"/><Spinnerandroid:layout_width="100dp"android:layout_height="wrap_content"android:layout_gravity="right"android:id="@+id/spin"android:entries="@array/texiao"android:background="@mipmap/xia"android:alpha="0.7"/></FrameLayout>
如果手机端打不开,可以使用电脑试一下。
项目地址:
app下载地址:
本文发布于:2024-01-29 01:32:29,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170646315411754.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |