在Android上玩转Opencv 系列:15.基础知识 图像修补方法inpaint使用

372 阅读3分钟

Android OpenCV inpaint() (已经不能用这个方法了) 图像修补方法使用详解

OpenCV for Android 中,Imgproc.inpaint() 方法用于图像修补(Image Inpainting),主要用于 去除图像中的不需要部分(如水印、噪点、污渍、划痕等)。该方法通过使用周围区域的信息来填补受损区域,使图像恢复更自然。

1. inpaint() 方法简介

(1) 方法签名

Imgproc.inpaint(Mat src, Mat mask, Mat dst, double inpaintRadius, int flags);

(2) 参数说明

参数作用
src输入图像(原始图像) ,必须是 8-bit 3 通道(彩色)或单通道(灰度) 图像
mask掩码(Mask) ,标记需要修复的区域,必须是 8-bit 单通道,其中 白色(255) 代表需要修复的区域,黑色(0)代表保持不变
dst输出图像(修复后的图像)
inpaintRadius修复半径,决定算法在修复时考虑的周围区域的大小
flags修复算法,可选值: - INPAINT_NS:Navier-Stokes 修复方法(基于 PDE 方程的流体力学方法) - INPAINT_TELEA:基于快速行进法(Telea’s Method),通常更快,效果更好

2. Android OpenCV inpaint() 示例

示例需求

我们希望去除图像中的 污渍/划痕,首先:

  1. 加载原始图像

  2. 创建掩码(Mask) 标记需要修补的区域。

  3. 使用 inpaint() 进行图像修补

  4. 显示修补后的图像

完整代码示例

import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

public class InpaintActivity extends AppCompatActivity {

    static {
        OpenCVLoader.initDebug(); // 初始化 OpenCV
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取 ImageView 组件
        ImageView imageView = findViewById(R.id.imageView);

        // 加载原始图像
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_image);
        Mat src = new Mat();
        Utils.bitmapToMat(bitmap, src);

        // 转换为灰度图像
        Mat gray = new Mat();
        Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);

        // 创建掩码(mask),必须是 8-bit 单通道
        Mat mask = new Mat(gray.size(), CvType.CV_8UC1);
        Imgproc.threshold(gray, mask, 200, 255, Imgproc.THRESH_BINARY); // 二值化,提取损坏区域

        // 进行 inpaint 修补
        Mat dst = new Mat();
        Imgproc.inpaint(src, mask, dst, 5, Imgproc.INPAINT_TELEA); // 使用 Telea 方法修复

        // 转换回 Bitmap 并显示结果
        Bitmap resultBitmap = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(dst, resultBitmap);
        imageView.setImageBitmap(resultBitmap);
    }
}

3. 代码解析

(1) 初始化 OpenCV

static {
    OpenCVLoader.initDebug();
}

在 Android 中,使用 OpenCV 前必须初始化。

(2) 读取原始图像并转换为 Mat

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sample_image);
Mat src = new Mat();
Utils.bitmapToMat(bitmap, src);

BitmapFactory.decodeResource() 加载图片资源。

Utils.bitmapToMat() 将 Bitmap 转换为 OpenCV Mat 格式。

(3) 生成掩码 mask

Mat gray = new Mat();
Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);

转换为灰度图,便于检测污渍/划痕区域。

Mat mask = new Mat(gray.size(), CvType.CV_8UC1);
Imgproc.threshold(gray, mask, 200, 255, Imgproc.THRESH_BINARY);

Imgproc.threshold() 进行二值化

阈值 200 以上的区域设为 255(白色,需要修补)

阈值 200 以下的区域设为 0(黑色,不修补)

• mask 必须是 8-bit 单通道(CV_8UC1)。

(4) 进行 inpaint() 修补

Mat dst = new Mat();
Imgproc.inpaint(src, mask, dst, 5, Imgproc.INPAINT_TELEA);

• inpaintRadius = 5:修复半径,数值越大,修补区域参考的周围像素越多。

• Imgproc.INPAINT_TELEA:使用 Telea’s Method(基于快速行进算法)。

(5) 显示修补后的图像

Bitmap resultBitmap = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dst, resultBitmap);
imageView.setImageBitmap(resultBitmap);

Utils.matToBitmap() 将修补后的 Mat 转换回 Bitmap 以供显示。

4. INPAINT_NS vs INPAINT_TELEA 对比

方法原理适用场景修复质量计算速度
INPAINT_NSNavier-Stokes PDE适用于平滑过渡的区域,如 天空、水面效果较柔和较慢
INPAINT_TELEA基于快速行进法适用于 小污渍/划痕 的修复效果更自然,边界更清晰更快

选择建议

• 如果修补 大面积污渍(如去除大面积水印) → 推荐 INPAINT_NS

• 如果修补 小划痕/小污点(如修补老照片、擦除小文字) → 推荐 INPAINT_TELEA

5. 总结

Imgproc.inpaint() 是 OpenCV 提供的强大图像修复方法

mask 掩码用于标记需要修补的区域(白色部分修补,黑色部分保持)

支持 INPAINT_TELEA(快速)和 INPAINT_NS(更平滑)两种修补算法

广泛用于去水印、划痕修复、去污渍、旧照片修补等任务

📌 通过 OpenCV 在 Android 上实现自动化图像修补,提升图像处理能力!🚀