在Android上玩转Opencv 系列: 3.基础知识 图像二值化(thresholding)

317 阅读3分钟

在 Android 中使用 OpenCV 进行图像二值化(thresholding),使用 Imgproc.threshold 函数。这个函数将图像的灰度值按照指定的阈值进行分类,通常将像素分为两类:一种是符合条件的(通常为白色),另一种是不符合条件的(通常为黑色)。这是图像预处理中的常见操作,广泛用于特征提取、边缘检测、文字识别等任务。

Imgproc.threshold 函数

函数原型:

public static double threshold(Mat src, Mat dst, double thresh, double maxVal, int type)

参数说明:

src:输入图像,必须是单通道的灰度图像(CV_8UC1)。如果输入图像是彩色图像,必须先将其转换为灰度图像。

dst:输出图像,二值化后的图像。

thresh:阈值,用于决定哪些像素应该变成 maxVal,哪些应该变成 0。

maxVal:最大值。如果像素值大于或等于阈值 thresh,则像素值会被设置为 maxVal。

type:阈值类型,定义了阈值化操作的方式。

阈值类型(type):

Imgproc.threshold 支持不同的阈值类型,常见的类型如下:

  1. Imgproc.THRESH_BINARY:二值化,如果像素值大于阈值,则将其设为 maxVal,否则设为 0。

• 公式:

image.png 2. Imgproc.THRESH_BINARY_INV:反二值化,如果像素值大于阈值,则将其设为 0,否则设为 maxVal。

• 公式:

image.png

  1. Imgproc.THRESH_TRUNC:阈值截断,如果像素值大于阈值,则将其设为阈值 thresh,否则保持不变。

• 公式:

image.png

  1. Imgproc.THRESH_TOZERO:如果像素值大于阈值,则保持不变,否则将其设为 0。

• 公式:

image.png

  1. Imgproc.THRESH_TOZERO_INV:反转 THRESH_TOZERO,如果像素值大于阈值,则设为 0,否则保持不变。

返回值:

该函数返回应用阈值处理后的最大阈值。在大多数情况下,这个返回值可以忽略,但它可以用于某些特殊的算法(比如自适应阈值处理等)。

示例代码:

下面是一个在 Android 上使用 OpenCV 进行图像二值化的简单示例:

1. 导入 OpenCV 库并初始化

在 Android 项目中使用 OpenCV,首先确保你已经在 build.gradle 文件中添加了 OpenCV 的依赖,并初始化 OpenCV。

dependencies {
    implementation 'org.opencv:opencv-android:4.5.1'
}

在 MainActivity 中进行初始化:

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

    if (!OpenCVLoader.initDebug()) {
        Log.e("OpenCV", "OpenCV initialization failed.");
    } else {
        Log.d("OpenCV", "OpenCV initialization succeeded.");
    }
}

2. 读取图像并进行灰度化

假设我们有一个输入图像 src,我们需要先将其转换为灰度图像。接着应用阈值操作。

public void applyThreshold(Mat src) {
    // 将彩色图像转换为灰度图像
    Mat gray = new Mat();
    Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);

    // 创建输出图像
    Mat dst = new Mat();

    // 应用二值化阈值处理
    double thresh = 128;  // 设置阈值
    double maxVal = 255;  // 设置最大值
    int type = Imgproc.THRESH_BINARY;  // 设置二值化类型

    // 应用阈值操作
    Imgproc.threshold(gray, dst, thresh, maxVal, type);

    // 显示结果
    Imgcodecs.imwrite("/sdcard/thresh_output.jpg", dst); // 将结果保存到文件
}

3. 解释

Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY) :将输入图像从 BGR 彩色图像转换为灰度图像。

Imgproc.threshold:使用给定的阈值 thresh 对灰度图像进行二值化处理,生成二值图像 dst。在这个例子中,我们使用 Imgproc.THRESH_BINARY 类型,表示大于阈值的像素将变为白色(maxVal),小于阈值的像素将变为黑色(0)。

4. 应用不同的阈值类型

你可以尝试不同的阈值类型来获得不同的效果。例如,使用反二值化:

int type = Imgproc.THRESH_BINARY_INV;  // 使用反二值化

或者使用截断:

int type = Imgproc.THRESH_TRUNC;  // 使用阈值截断

QQ_1742298304760.png 总结:

Imgproc.threshold 是一个强大的函数,广泛用于图像二值化处理。它能够帮助你基于阈值将图像分为两部分,通常用于图像分割、特征提取和图像分析。在 Android 上使用 OpenCV 时,你只需要将图像转换为灰度图像,并选择合适的阈值类型来进行二值化处理。