OpenCV(八):图像二值化

目录

1.固定值二值化

2.自适应阈值二值化

3.Android JNI完整代码


1.固定值二值化

固定阈值二值化是OpenCV中一种简单而常用的图像处理技术,用于将图像转换为二值图像。在固定阈值二值化中,像素值根据一个预定义的阈值进行分类,大于阈值的像素被设置为白色,而小于或等于阈值的像素被设置为黑色。以下是关于OpenCV固定阈值二值化的一些重要知识点:

1.阈值函数:在OpenCV中,固定阈值二值化可以使用 threshold() 函数来实现。该函数的原型如下:

double threshold(InputArray src, OutputArray dst, double thresh, double maxValue, int thresholdType);

  • src:输入图像,通常为灰度图像。
  • dst:输出二值图像,与输入图像具有相同的大小和类型。
  • thresh:固定阈值,用于将像素分类为黑色或白色。
  • maxValue:分配给大于阈值的像素的像素值。
  • thresholdType:阈值类型,用于指定阈值化的方式,如 THRESH_BINARYTHRESH_BINARY_INV 等。

2.阈值类型:使用 thresholdType 参数可以选择不同的固定阈值化类型,以满足特定需求。一些常用的阈值类型包括:

  • THRESH_BINARY:二进制阈值化,大于阈值的像素值设为 maxValue,小于等于阈值的像素值设为 0。
  • THRESH_BINARY_INV:反二进制阈值化,大于阈值的像素值设为 0,小于等于阈值的像素值设为 maxValue
  • THRESH_TRUNC:截断阈值化,大于阈值的像素值设为阈值,小于等于阈值的保持不变。
  • THRESH_TOZERO:截断到零阈值化,大于阈值的像素值保持不变,小于等于阈值的像素值设为 0。
  • THRESH_TOZERO_INV:反截断到零阈值化,大于阈值的像素值设为 0,小于等于阈值的像素值保持不变。

3.例子

                 (原图)

1.将彩色图像image转换为灰度图像

     Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);

       

         (灰度图像)     

2.彩色图像二值化

    Mat img_B,img_B_V;
    threshold(image,img_B,125,255,THRESH_BINARY);
    imwrite("/sdcard/DCIM/img_B.png",img_B);

 

3.灰度图BINARY二值化

    Mat  gray_B,gray_B_V;
    threshold(gray,gray_B,125,255,THRESH_BINARY);
    threshold(gray,gray_B_V,125,255,THRESH_BINARY_INV);
    imwrite("/sdcard/DCIM/gray_B.png",gray_B);
    imwrite("/sdcard/DCIM/gray_B_V.png",gray_B_V);

 

            gray_B                                                         gray_B_V

4.灰度图像TOZERO变换

    Mat  gray_T,gray_T_V;
    threshold(gray,gray_T,125,255,THRESH_TOZERO);
    threshold(gray,gray_T_V,125,255,THRESH_TOZERO_INV);
    imwrite("/sdcard/DCIM/gray_T.png",gray_T);
    imwrite("/sdcard/DCIM/gray_T_V.png",gray_T_V);

            gray_T                                                    gray_T_V

5.灰度图像TRUNC变换

    Mat gray_TRUNC;
    threshold(gray,gray_TRUNC,125,255,THRESH_TRUNC);
    imwrite("/sdcard/DCIM/gray_TRUNC.png",gray_TRUNC);

              gray_TRUNC
6.灰度图像大津法和三角形法二值化

       Mat img_Thr;
       cvtColor(image,img_Thr,COLOR_BGR2GRAY);
       Mat img_Thr_0,img_Thr_T;
    threshold(img_Thr,img_Thr_0,100,255,THRESH_BINARY|cv::THRESH_OTSU);
    threshold(img_Thr,img_Thr_T,125,255,THRESH_BINARY|cv::THRESH_TRIANGLE);
   imwrite("/sdcard/DCIM/img_Thr_0.png",img_Thr_0);
   imwrite("/sdcard/DCIM/img_Thr_T.png",img_Thr_T);

      

                    img_Thr_T                                            img_Thr_0

2.自适应阈值二值化

1.自适应阈值函数:OpenCV中的自适应阈值二值化可以使用 adaptiveThreshold() 函数来实现。该函数的原型如下:

void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C);

  • src:输入图像,通常为灰度图像。
  • dst:输出二值图像,与输入图像具有相同的大小和类型。
  • maxValue:分配给超过阈值的像素的像素值。
  • adaptiveMethod:自适应阈值化方法,用于指定计算局部阈值的方式,可以是 ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C。
  • thresholdType:阈值化类型,用于指定阈值化的方式,如 THRESH_BINARY、THRESH_BINARY_INV 等。
  • blockSize:用于计算局部阈值的像素领域大小。必须是奇数且大于1。
  • C:从计算阈值中减去的常数。通常为正值。

2.自适应阈值化方法:使用 adaptiveMethod 参数可以选择不同的自适应阈值化方法,以满足特定需求。在OpenCV中,常见的自适应阈值化方法有两种:

  • ADAPTIVE_THRESH_MEAN_C:根据领域中像素的均值计算局部阈值。

  • ADAPTIVE_THRESH_GAUSSIAN_C:根据领域中像素的加权和(权重为高斯窗口)计算局部阈值。

3.灰度图像转换:在进行自适应阈值二值化之前,要将彩色图像转换为灰度图像。可以使用 cvtColor() 函数将彩色图像转换为灰度图像。

cvtColor(image,img_Thr,COLOR_BGR2GRAY);

 4.例子

   Mat adaptive_mean,adaptive_gauss;
adaptiveThreshold(img_Thr,adaptive_mean,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,55,0);
adaptiveThreshold(img_Thr,adaptive_gauss,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,55,0);
imwrite("/sdcard/DCIM/adaptive_mean.png",adaptive_mean);
imwrite("/sdcard/DCIM/adaptive_gauss.png",adaptive_gauss);

      

                adaptive_gauss                                              adaptive_mean

3.Android JNI完整代码

#include <jni.h>
#include <string>
#include <android/bitmap.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <android/log.h>

#define LOG_TAG "xxx"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

using namespace cv;
using namespace std;
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_opencv_1test(JNIEnv *env, jclass clazz,
                                                         jobject bitmap) {
    AndroidBitmapInfo info;
    void *pixels;

    CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
    //判断图片是位图格式有RGB_565 、RGBA_8888
    CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
              info.format == ANDROID_BITMAP_FORMAT_RGB_565);
    CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
    CV_Assert(pixels);

    //将bitmap转化为Mat类
    Mat image(info.height, info.width, CV_8UC4, pixels);

    Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);
    imwrite("/sdcard/DCIM/gray23.png",gray);
    Mat img_B,img_B_V,gray_B,gray_B_V,gray_T,gray_T_V,gray_TRUNC;

    //彩色图像二值化
    threshold(image,img_B,125,255,THRESH_BINARY);
    imwrite("/sdcard/DCIM/img_B.png",img_B);

    //灰度图BINARY二值化
    threshold(gray,gray_B,125,255,THRESH_BINARY);
    threshold(gray,gray_B_V,125,255,THRESH_BINARY_INV);
    imwrite("/sdcard/DCIM/gray_B.png",gray_B);
    imwrite("/sdcard/DCIM/gray_B_V.png",gray_B_V);

    //灰度图像TOZERO变换
    threshold(gray,gray_T,125,255,THRESH_TOZERO);
    threshold(gray,gray_T_V,125,255,THRESH_TOZERO_INV);
    imwrite("/sdcard/DCIM/gray_T.png",gray_T);
    imwrite("/sdcard/DCIM/gray_T_V.png",gray_T_V);

    //灰度图像TRUNC变换
    threshold(gray,gray_TRUNC,125,255,THRESH_TRUNC);
    imwrite("/sdcard/DCIM/gray_TRUNC.png",gray_TRUNC);
    //灰度图像大津法和三角形法二值化
       Mat img_Thr;
       cvtColor(image,img_Thr,COLOR_BGR2GRAY);
       Mat img_Thr_0,img_Thr_T;
    threshold(img_Thr,img_Thr_0,100,255,THRESH_BINARY|cv::THRESH_OTSU);
    threshold(img_Thr,img_Thr_T,125,255,THRESH_BINARY|cv::THRESH_TRIANGLE);
   imwrite("/sdcard/DCIM/img_Thr_0.png",img_Thr_0);
   imwrite("/sdcard/DCIM/img_Thr_T.png",img_Thr_T);
   
       Mat adaptive_mean,adaptive_gauss;
    adaptiveThreshold(img_Thr,adaptive_mean,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,55,0);
    adaptiveThreshold(img_Thr,adaptive_gauss,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,55,0);
    imwrite("/sdcard/DCIM/adaptive_mean.png",adaptive_mean);
    imwrite("/sdcard/DCIM/adaptive_gauss.png",adaptive_gauss);
}

猜你喜欢

转载自blog.csdn.net/weixin_63357306/article/details/132583491