Android 集成OpenCV-CSDN博客
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";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); // 你的布局文件ImageView imageView = findViewById(R.id.imageView); // 你的ImageViewtry {Bitmap bitmap1 = loadBitmapFromResource(R.drawable.image1); // 替换成你的资源IDBitmap bitmap2 = loadBitmapFromResource(R.drawable.image2); // 替换成你的资源IDif (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()
这些语句用于释放资源,防止内存泄漏。 - 类型转换:
convertBitmapToMat
和convertMatToBitmap
函数封装了 Bitmap 和 Mat 之间的转换,提高代码可读性和可维护性。 - 图像加载: 使用
loadBitmapFromResource
函数从资源加载图片,并进行错误处理。 - 高度一致性检查: 在
stitchImages
函数中,添加了对输入图像高度是否一致的检查,这是Core.hconcat
的必要条件。
使用前请注意:
- 替换
R.drawable.image1
和R.drawable.image2
为你实际的图像资源 ID。 - 确保你的项目已正确配置 OpenCV 库。
- 在你的布局文件中添加一个
ImageView
,并在代码中使用findViewById
获取其引用。
这个改进后的代码更加健壮,可以更好地避免运行时崩溃,并提供更清晰的错误信息。 即使出现错误,它也只会打印日志并停止执行,不会导致应用程序崩溃。 记住,在处理大型图像时,尤其要注意内存管理,避免内存溢出 (OOM) 错误。