Android opencv使用Core.hconcat 进行图像拼接

Android 集成OpenCV-CSDN博客

java 复制代码
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ImageView;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class ImageStitchingActivity extends AppCompatActivity {

    private static final String TAG = "ImageStitchingActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); // 你的布局文件

        ImageView imageView = findViewById(R.id.imageView); // 你的ImageView

        try {
            Bitmap bitmap1 = loadBitmapFromResource(R.drawable.image1); // 替换成你的资源ID
            Bitmap bitmap2 = loadBitmapFromResource(R.drawable.image2); // 替换成你的资源ID

            if (bitmap1 == null || bitmap2 == null) {
                Log.e(TAG, "图像加载失败");
                return;
            }

            Mat mat1 = convertBitmapToMat(bitmap1);
            Mat mat2 = convertBitmapToMat(bitmap2);

            if (mat1 == null || mat2 == null) {
                Log.e(TAG, "Bitmap 转 Mat 失败");
                return;
            }

            Mat stitchedMat = stitchImages(mat1, mat2);

            if (stitchedMat == null) {
                Log.e(TAG, "图像拼接失败");
                return;
            }

            Bitmap stitchedBitmap = convertMatToBitmap(stitchedMat);

            if (stitchedBitmap == null) {
                Log.e(TAG, "Mat 转 Bitmap 失败");
                return;
            }

            imageView.setImageBitmap(stitchedBitmap);


            // 释放资源
            mat1.release();
            mat2.release();
            stitchedMat.release();
            bitmap1.recycle();
            bitmap2.recycle();


        } catch (Exception e) {
            Log.e(TAG, "拼接过程中出现错误: " + e.getMessage());
            // 处理异常,例如显示错误消息
        }
    }

    private Bitmap loadBitmapFromResource(int resourceId) {
        InputStream inputStream = getResources().openRawResource(resourceId);
        try {
            return BitmapFactory.decodeStream(inputStream);
        } catch (Exception e) {
            Log.e(TAG, "资源加载失败", e);
            return null;
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                Log.e(TAG, "流关闭失败", e);
            }
        }
    }


    private Mat convertBitmapToMat(Bitmap bitmap) {
        Mat mat = new Mat();
        Utils.bitmapToMat(bitmap, mat);
        return mat;
    }

    private Bitmap convertMatToBitmap(Mat mat) {
        Bitmap bitmap = Bitmap.createBitmap(mat.cols(), mat.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(mat, bitmap);
        return bitmap;
    }

    private Mat stitchImages(Mat mat1, Mat mat2) {
        if (mat1.rows() != mat2.rows()) {
            Log.e(TAG, "图像高度不一致,无法拼接");
            return null;
        }
        List<Mat> mats = new ArrayList<>();
        mats.add(mat1);
        mats.add(mat2);
        Mat stitchedMat = new Mat();
        Core.hconcat(mats, stitchedMat);
        return stitchedMat;
    }
}

代码说明:

  • 错误处理: 代码中加入了大量的错误检查,例如图像加载失败、Bitmap 到 Mat 的转换失败、图像高度不一致等情况,并在发生错误时打印日志信息并返回,避免程序崩溃。
  • 资源释放: mat1.release(), mat2.release(), stitchedMat.release(), bitmap1.recycle(), bitmap2.recycle() 这些语句用于释放资源,防止内存泄漏。
  • 类型转换: convertBitmapToMatconvertMatToBitmap 函数封装了 Bitmap 和 Mat 之间的转换,提高代码可读性和可维护性。
  • 图像加载: 使用 loadBitmapFromResource 函数从资源加载图片,并进行错误处理。
  • 高度一致性检查:stitchImages 函数中,添加了对输入图像高度是否一致的检查,这是 Core.hconcat 的必要条件。

使用前请注意:

  • 替换 R.drawable.image1R.drawable.image2 为你实际的图像资源 ID。
  • 确保你的项目已正确配置 OpenCV 库。
  • 在你的布局文件中添加一个 ImageView,并在代码中使用 findViewById 获取其引用。

这个改进后的代码更加健壮,可以更好地避免运行时崩溃,并提供更清晰的错误信息。 即使出现错误,它也只会打印日志并停止执行,不会导致应用程序崩溃。 记住,在处理大型图像时,尤其要注意内存管理,避免内存溢出 (OOM) 错误。

相关推荐
愚者游世4 分钟前
Opencv知识点大纲
人工智能·opencv·计算机视觉
言之。16 分钟前
Kotlin快速入门
android·开发语言·kotlin
符哥200841 分钟前
Android 权限分类说明
android
大模型玩家七七1 小时前
安全对齐不是消灭风险,而是重新分配风险
android·java·数据库·人工智能·深度学习·安全
李少兄1 小时前
MySQL 中为时间字段设置默认当前时间
android·数据库·mysql
格林威1 小时前
Baumer相机电池极耳对齐度检测:提升叠片工艺精度的 5 个实用方案,附 OpenCV+Halcon 实战代码!
人工智能·opencv·机器学习·计算机视觉·视觉检测·工业相机·堡盟相机
俩个逗号。。1 小时前
修改Android resource dimens大小之后不生效
android
403240731 小时前
【Jetson开发避坑】虚拟环境(Conda/Venv)调用系统底层OpenCV与TensorRT的终极指南
人工智能·opencv·conda
2501_915918412 小时前
在 iOS 环境下查看 App 详细信息与文件目录
android·ios·小程序·https·uni-app·iphone·webview
落羽的落羽2 小时前
【Linux系统】从零实现一个简易的shell!
android·java·linux·服务器·c++·人工智能·机器学习