You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android内置相机拍摄图片的Java视觉识别服务分类步骤及源码咨询

嘿,我之前做过类似的Android图像分类项目,给你梳理下完整的实现步骤和关键代码片段,应该能帮到你:

一、前期准备
  • 选择视觉识别方案:根据需求选合适的服务,推荐两种主流选项:
    • 本地处理:TensorFlow Lite 轻量图像分类模型(无需网络,响应快)或 Google ML Kit 本地图像分类
    • 云端处理:Google Cloud Vision API、AWS Rekognition 等(准确率高,但需网络和API密钥)
  • 配置Android项目:
    1. 申请权限:在AndroidManifest.xml中添加相机、存储权限:
      <uses-permission android:name="android.permission.CAMERA" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-feature android:name="android.hardware.camera.any" />
      
    2. 添加依赖:比如用CameraX(官方推荐相机库)和TensorFlow Lite,在app/build.gradle中添加:
      // CameraX核心依赖
      implementation "androidx.camera:camera-core:1.2.3"
      implementation "androidx.camera:camera-camera2:1.2.3"
      implementation "androidx.camera:camera-lifecycle:1.2.3"
      implementation "androidx.camera:camera-view:1.2.3"
      // TensorFlow Lite图像分类
      implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.4'
      
二、实现Android相机拍照功能

用CameraX实现拍照非常简洁,核心代码如下:

  1. 在布局中添加CameraX的PreviewView:
    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
  2. 初始化CameraX并实现拍照逻辑(Java代码):
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private ImageCapture imageCapture;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        // 动态申请相机权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 100);
            return;
        }
    
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindCameraPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
        }, ContextCompat.getMainExecutor(this));
    }
    
    private void bindCameraPreview(ProcessCameraProvider cameraProvider) {
        PreviewView previewView = findViewById(R.id.previewView);
        Preview preview = new Preview.Builder().build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());
    
        // 配置拍照参数
        imageCapture = new ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build();
    
        // 绑定相机生命周期
        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();
    
        cameraProvider.unbindAll();
        cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
    }
    
    // 拍照按钮点击事件
    public void takePhoto(View view) {
        File photoFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                System.currentTimeMillis() + ".jpg");
        ImageCapture.OutputFileOptions outputOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build();
    
        imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(this),
                new ImageCapture.OnImageSavedCallback() {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        // 拍照成功,获取图片文件路径
                        String photoPath = photoFile.getAbsolutePath();
                        // 调用图像分类方法
                        classifyImage(photoPath);
                    }
    
                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        exception.printStackTrace();
                    }
                });
    }
    
三、集成视觉识别进行图像分类

这里以TensorFlow Lite本地图像分类为例,代码如下:

private ImageClassifier imageClassifier;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ... 之前的初始化代码
    // 初始化图像分类器
    try {
        imageClassifier = ImageClassifier.createFromFile(this, "mobilenet_v1_1.0_224.tflite");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void classifyImage(String imagePath) {
    // 后台线程处理,避免UI卡顿
    new Thread(() -> {
        try {
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            // 图片预处理:缩放至模型要求的尺寸(比如224x224)
            Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true);
            // 执行分类
            List<Classifications> results = imageClassifier.classify(resizedBitmap);
            // 解析分类结果
            StringBuilder resultText = new StringBuilder();
            for (Classifications classifications : results) {
                for (Category category : classifications.getCategories()) {
                    resultText.append(category.getLabel())
                            .append(": ")
                            .append(String.format("%.2f", category.getScore() * 100))
                            .append("%\n");
                }
            }
            // 回到UI线程更新结果
            runOnUiThread(() -> {
                // 比如用TextView显示结果
                TextView resultTv = findViewById(R.id.resultTv);
                resultTv.setText(resultText.toString());
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }).start();
}
四、实用建议
  • 图片预处理:不同模型对输入尺寸、颜色格式(比如RGB/BGR)要求不同,一定要按照模型文档调整,否则分类结果会不准确
  • 性能优化:图像分类属于耗时操作,必须放在后台线程执行;可以考虑用ExecutorService管理线程池,提升复用性
  • 模型选择:移动端优先选轻量模型,比如MobileNet、EfficientNet-Lite系列,平衡准确率和速度
  • 权限处理:一定要处理动态权限申请的回调,确保用户授予权限后再初始化相机
  • 云端服务注意点:如果用云端视觉服务,要注意API调用次数限制、网络稳定性,并且不要把API密钥硬编码在代码里(可以用Android Keystore或者远程配置)

内容的提问来源于stack exchange,提问作者David Lawal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:52:06