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() 示例
示例需求
我们希望去除图像中的 污渍/划痕,首先:
-
加载原始图像。
-
创建掩码(Mask) 标记需要修补的区域。
-
使用 inpaint() 进行图像修补。
-
显示修补后的图像。
完整代码示例
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_NS | Navier-Stokes PDE | 适用于平滑过渡的区域,如 天空、水面 | 效果较柔和 | 较慢 |
| INPAINT_TELEA | 基于快速行进法 | 适用于 小污渍/划痕 的修复 | 效果更自然,边界更清晰 | 更快 |
选择建议
• 如果修补 大面积污渍(如去除大面积水印) → 推荐 INPAINT_NS。
• 如果修补 小划痕/小污点(如修补老照片、擦除小文字) → 推荐 INPAINT_TELEA。
5. 总结
✅ Imgproc.inpaint() 是 OpenCV 提供的强大图像修复方法
✅ mask 掩码用于标记需要修补的区域(白色部分修补,黑色部分保持)
✅ 支持 INPAINT_TELEA(快速)和 INPAINT_NS(更平滑)两种修补算法
✅ 广泛用于去水印、划痕修复、去污渍、旧照片修补等任务
📌 通过 OpenCV 在 Android 上实现自动化图像修补,提升图像处理能力!🚀