图像二值化

这篇具有很好参考价值的文章主要介绍了图像二值化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 图像二值化

图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

要得到二值化图像,首先要把图像灰度化,然后将256个亮度等级的灰度图像通过适当的阈值选取而获得仍然可以反映图像整体和局部特征的二值化图像。所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。

2. 图像二值化方法及Python实现

比较常用的二值化方法有:简单二值法,平均值法,双峰法和OTSU法等。

2.1 简单二值法

将图像灰度化后,我们选择127(灰度值范围的一半)作为阈值,即将像素值大于127的像素值全部设为255,小于127的全部设为0。

def Easy_Binarization(srcImg_path):
    img = cv.imread(srcImg_path)
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    img_gray[img_gray>127] = 255
    img_gray[img_gray<=127] = 0
    plt.imshow(img_gray, cmap='gray')
    plt.title('Easy_Binarization')
    plt.show()

图像二值化

2.2 平均值法

为了应对每张图片的灰度值大不相同,阈值取为图像本身的平均值。

def Mean_Binarization(srcImg_path):
    img = cv.imread(srcImg_path)
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    threshold = np.mean(img_gray)
    print(threshold)
    img_gray[img_gray>threshold] = 255
    img_gray[img_gray<=threshold] = 0
    plt.imshow(img_gray, cmap='gray')
    plt.title('Mean_Binarization')
    plt.show()

图像二值化

实验中该方法计算的阈值为123。

2.3 双峰法

直方图是图像的重要特质,它可以帮助我们分析图像中的灰度变化。因此,如果物体与背景的灰度值对比明显,直方图就会包含双峰,它们分别为图像的前景和背景,而它们之间的谷底即为边缘附近相对较少数目的像素点,一般来讲,这个最小值就为最优二值化的分界点,通过这个点可以把前景和背景很好地分开。

def Hist_Binarization(srcImg_path):
    img = cv.imread(srcImg_path)
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    hist = img_gray.flatten()
    plt.subplot(121)
    plt.hist(hist,256)

    cnt_hist = Counter(hist)
    print(cnt_hist)
    begin,end = cnt_hist.most_common(2)[0][0],cnt_hist.most_common(2)[1][0]
    if begin > end:
        begin, end = end, begin
    print(f'{begin}: {end}')

    cnt = np.iinfo(np.int16).max
    threshold = 0
    for i in range(begin,end+1):
        if cnt_hist[i]<cnt:
            cnt = cnt_hist[i]
            threshold = i
    print(f'{threshold}: {cnt}')
    img_gray[img_gray>threshold] = 255
    img_gray[img_gray<=threshold] = 0
    plt.subplot(122)
    plt.imshow(img_gray, cmap='gray')
    plt.show()

图像二值化

实验中该方法得到的双峰为(145,154),阈值为150。

2.4 OTSU法

双峰法具有明显的缺陷,因为直方图是不连续的,有非常多尖峰和抖动,要找到准确的极值点十分困难。日本工程师大津展之为这个波谷找到了一个合适的数学表达,并于1979年发表。这个二值化方法称为大津算法(Otsu’s method)。

OTSU法也称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。它被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致类间差别变小。因此,使类间方差最大的分割意味着错分概率最小。

具体计算阈值方法如下:
设阈值为t, 将原图转化成灰度图后,将其高与宽存于h,w,并将小于阈值的灰度值存储在前景front中,大于等于阈值的存在背景back中。如下所示:

# 阈值:t
h, w = img.shape[:2]
front = img[img < t]
back = img[img >= t]

显然,前景与背景的长度和应与h, w的乘积相等,即:

len(front) + len(back) == h * w.

设前景像素数量占总像素数量的比重为frontP,背景像素数量占总像素数量的比重为backP,前景和背景的灰度平均值分别为frontMean和backMean,总平均灰度值为m,则方差公式可写成:
v = f r o n t P ∗ ( f r o n t M e a n − m ) 2 + b a c k P ∗ ( b a c k M e a n − m ) 2 v=frontP*(frontMean-m)^2+backP*(backMean-m)^2 v=frontP(frontMeanm)2+backP(backMeanm)2
又因为:
m = f r o n t P ∗ f r o n t M e a n + b a c k P ∗ b a c k M e a n m=frontP*frontMean+backP*backMean m=frontPfrontMean+backPbackMean
上式可化简为:
v = f r o n t P ∗ b a c k P ∗ ( f r o n t M e a n − b a c k M e a n ) 2 v=frontP*backP*(frontMean-backMean)^2 v=frontPbackP(frontMeanbackMean)2
实验代码如下:

def Otsu(srcImg_path):
    img = cv.imread(srcImg_path)
    img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    h, w = img.shape[:2]
    threshold_t = 0
    max_g = 0
    
    for t in range(255):
        front = img[img < t]
        back = img[img >= t]
        front_p = len(front) / (h * w)
        back_p = len(back) / (h * w)
        front_mean = np.mean(front) if len(front) > 0 else 0.
        back_mean = np.mean(back) if len(back) > 0 else 0.
        
        g = front_p * back_p * ((front_mean - back_mean)**2)
        if g > max_g:
            max_g = g
            threshold_t = t
    print(f"threshold = {threshold_t}")

    img[img < threshold_t] = 0
    img[img >= threshold_t] = 255
    plt.imshow(img, cmap='gray')
    plt.title('Otsu')
    plt.show()

二值化图像如下:
图像二值化

对比以上四种方法可以发现,Otsu方法得到的二值化图像细节更多,图像更细腻。

3. opencv-python中二值化方法的应用

在OpenCV中,分为简单的阈值分割与自适应阈值分割。

3.1 简单阈值分割(Simple Thresholding)

函数原型如下:

retval, dst = cv.threshold(src, thresh, maxval, type[, dst])

参数说明:
第一个参数src为原图,需要注意的是输入的图像需为灰度图。
第二个参数thresh即为阈值,用于对像素值的分类(一般定义为127)。
第三个参数maxval是最大值,即超过阈值后所定义的值(255)。
第四个参数type,在Simple Thresholding中一共有五种不同的方式: cv.THRESH_BINARY、cv.THRESH_BINARY_INV 、cv.THRESH_TRUNC 、cv.THRESH_TOZERO、cv.THRESH_TOZERO_INV

测试代码如下:

img = cv.imread('lenna.jpg')
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
img_gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
ret,thresh1 = cv.threshold(img_gray,127,255,cv.THRESH_BINARY)
ret,thresh2 = cv.threshold(img_gray,127,255,cv.THRESH_BINARY_INV)
ret,thresh3 = cv.threshold(img_gray,127,255,cv.THRESH_TRUNC)
ret,thresh4 = cv.threshold(img_gray,127,255,cv.THRESH_TOZERO)
ret,thresh5 = cv.threshold(img_gray,127,255,cv.THRESH_TOZERO_INV)

titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.axis('off')
plt.show()

下图是5种方式的实际效果:
图像二值化

3.2 自适应阈值分割(Adaptive Thresholding)

函数原型如下:

dst = cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])

其中src, maxValue和thresholdType与Simple Thresholding相同。

在自适应阈值分割中,adaptive method(阈值的计算方式)有两种:

  • cv.ADAPTIVE_THRESH_MEAN_C: 邻域面积(blockSize * blockSize)的平均值并减去C.
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C: 邻域面积的高斯加权总和然后减去C.

下面是它们的实际效果(对于thresholdType在这里选择cv.THRESH_BINARY),测试代码如下:

img = cv.imread('lenna.jpg')
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
img_gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
ret,th1 = cv.threshold(img_gray,127,255,cv.THRESH_BINARY)
th2 = cv.adaptiveThreshold(img_gray,255,cv.ADAPTIVE_THRESH_MEAN_C,\
            cv.THRESH_BINARY,11,2)
th3 = cv.adaptiveThreshold(img_gray,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv.THRESH_BINARY,11,2)

titles = ['Original Image', 'Simple Thresholding',
            'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]

for i in range(4):
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.axis('off')
plt.show()

效果如下:
图像二值化

发现没有像之前otsu那样输出一张类似的图片,但是,它将图像中的边框描绘了出来,实际应用中这样的方式更适合处理文字形式的图片。

4. 源码仓库地址

🌼图像处理、机器学习的常用算法汇总文章来源地址https://www.toymoban.com/news/detail-448398.html

到了这里,关于图像二值化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • opencv(20) 图像阈值(二值化)

    二值化核心思想,设阈值,大于阈值的为0(黑色)或 255(白色),使图像称为黑白图。 阈值可固定,也可以自适应阈值。 自适应阈值一般为一点像素与这点为中序的区域像素平均值或者高斯分布加权和的比较,其中可以设置一个差值也可以不设置。 图像的阈值化旨在提取

    2024年02月02日
    浏览(50)
  • OpenCV图像处理----图像的二值化

    图像二值化( Image Binarization) 就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。 二值化的原理 OpenCV提供的图像二值化API threshold()方法参数: 图片矩阵 阈值 图片中的最大值 二值化的方式 二值化的方式: THRESH_BINARY 高于阈值改为

    2024年02月12日
    浏览(39)
  • [2] 图像处理之----二值化处理

    简单阈值是选取一个全局阈值,然后把整幅图像分成非黑即白的二值图像,灰度值大于阈值就赋为255反之为0。 ret,mask = cv2.threshold(img2gray,175,255,cv2.THRESH_BINAR) 返回值一: 阈值,(Otsu‘s二值化会用到) 返回值二: 处理以后的图像 参数一: 初始图像 参数二:我们自己设定的阈

    2024年02月05日
    浏览(52)
  • 利用Python实现图像的二值化

       目录 1、全局阈值法 1.1主要函数: 1.2全局阈值的代码实现 1.3特点 2、自适应阈值法 2.1主要函数: 2.2实现代码: 2.3特点: 3、OTSU二值化(最大类间方差法) 3.1实现代码: 3.2特点 4、实例展示 参考文献:             传统的机器视觉通常包括两个步骤:预处理和物体检测

    2024年02月03日
    浏览(76)
  • 基于opencv的c++图像处理(图像二值化)

    基于opencv的c++接口,实现常用的图像二值化方法,包括了最大类间方差法(OTSU)、固定化阈值以及自适应阈值。 该函数将固定级别的阈值应用于多通道阵列。该函数通常用于从灰度图像中获取双层(二进制)图像(#compare 也可用于此目的)或用于去除噪声,即过滤掉值过小

    2024年02月07日
    浏览(46)
  • python图像处理实战(二)—二值化图像与线性变换

    🚀写在前面🚀 🖊个人主页:https://blog.csdn.net/m0_52051577?type=blog  🎁欢迎各位大佬支持点赞收藏,三连必回!! 🔈本人新开系列专栏—python图像处理 ❀愿每一个骤雨初晴之时,所有的蜻蜓振翅和雨后惊雷,都归你。 前言         首先引入以下灰度变换的概念。      

    2024年02月07日
    浏览(47)
  • FPGA|数字图像处理实现口罩识别——二值化

    【写在前面】刚入门小菜鸟,记录一下口罩识别学习过程。参考文件和网址会在文末注明。有错误欢迎指出,也欢迎进行补充~ 原理图如下,二值化对应为红框里的部分 使用的二值化方法是 手动指定一个 阈值 ,通过阈值来进行二值化处理 。(还有一种方法是一个自适应阈值

    2023年04月11日
    浏览(46)
  • MATLAB 图像处理 (二值化,image图片黑白处理)

    Q: MATLAB如何将图片进行 二值化 ,并将 二值化后图片 中的 黑色变成白色 , 原本的白色保持不变,黑白之间的黑色轮廓保持不变。 A: 使用 MATLAB 中的 imbinarize 函数 进行图片二值化。将指定阈值以下的像素值设为 0,其他像素值设为 1。 然后可以使用逻辑取反运算符 ~ (波浪线

    2023年04月08日
    浏览(41)
  • 使用OpenCV C++进行图像二值化操作

    threshold()将固定阈值应用于多通道图像阵列,通常用于从灰度图像中获得二值图像或用于去除噪声,即滤除值过小或过大的像素。该函数支持几种类型的阈值设置,它们由类型参数决定。 src:输入数组(多通道,8位或32位浮点数) dst:输出数组(与src的尺寸、类型、通道数相

    2024年02月03日
    浏览(41)
  • OpenCV常用功能——灰度处理和图像二值化处理

    1.1 cvtColor函数 函数原型: 功能 :转换图像颜色空间。 参数 : src: 输入图像。 code: 颜色空间转换代码。可以取常量cv2.COLOR_BGR2GRAY或cv2.COLOR_RGB2GRAY。 dst: 输出图像。 dstCn: 输出图像的通道数,如果设置为0,则跟随转换代码自动设置。 内置函数示例代码: 灰度处理的原理是将

    2024年02月08日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包