文章目录

  • 前言
  • 一、基于阈值的分割方法
    • 1.1 固定阈值法——直方图双峰法
    • 1.2 迭代阈值图像分割
    • 1.3 自适应阈值图像分割
      • 1.3.1 常规方法
      • 1.3.2 大津法(OTSU)
  • 参考文献:

前言

本文主要介绍图像分割基于阈值处理的一些基本方法。


一、基于阈值的分割方法

1.1 固定阈值法——直方图双峰法

该方法基于图像直方图上出现的双峰现象。当一个图像有双峰现象时,其直方图会出现两个峰,分别对应图像中两种不同的颜色或亮度区域。这时我们可以使用直方图双峰法来自动确定合适的阈值。其基本思路如下:

  1. 计算图像的灰度直方图。
  2. 根据直方图的两个峰的位置,计算出两个峰之间的阈值,作为图像的阈值。
  3. 根据计算出的阈值对图像进行二值化处理,将图像分成目标和背景两个部分。

注意:该方法只适用于存在双峰现象的图像,对于单峰或峰不明显的图像,则需要使用其他的阈值分割方法。

使用cv2.threshold(src, thresh, maxval, type)函数。

常用的阈值处理方法有:

1.THRESH_BINARY 二值阈值化
该方法将像素值与设定的阈值进行比较,若像素值大于等于阈值,则将该像素值设为最大值,否则设为0。可以用于处理灰度图像与彩色图像。2.THRESH_BINARY_INV 反二值阈值化
该方法将像素值与设定的阈值进行比较,若像素值小于阈值,则将该像素值设为最大值,否则设为0。可以用于处理灰度图像与彩色图像。3.THRESH_TRUNC 截断阈值化
该方法将像素值与设定的阈值进行比较,若像素值大于等于阈值,则将该像素值设为阈值,否则不更改。可以用于处理灰度图像。4.THRESH_TOZERO 零阈值化
该方法将像素值与设定的阈值进行比较,若像素值大于等于阈值,则不更改,否则设为0。可以用于处理灰度图像。5.THRESH_TOZERO_INV 反零阈值化
该方法将像素值与设定的阈值进行比较,若像素值小于等于阈值,则不更改,否则设为0。可以用于处理灰度图像

代码:

# 直方图双峰法
import cv2
import numpy as np
from matplotlib import pyplot as plt# 读取图像(阈值处理方法不同)
img = cv2.imread('house.tif',0)
x,img1 = cv2.threshold(img,150,255,cv2.THRESH_BINARY)
x,img2 = cv2.threshold(img,150,255,cv2.THRESH_TRUNC)
x,img3 = cv2.threshold(img,150,255,cv2.THRESH_TOZERO)# 显示原始图像和恢复后的图像
plt.figure(figsize=(20, 20))
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(img1, cmap='gray')
plt.title('seg img THRESH_BINARY'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(img2, cmap='gray')
plt.title('seg img THRESH_TRUNC'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img3, cmap='gray')
plt.title('seg img THRESH_TOZERO'), plt.xticks([]), plt.yticks([])
plt.show()


这种全局阈值处理方法缺点是对噪声的处理的效果并不好,需要进行平滑处理。

import cv2
import random
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('house.tif',0)# 加上高斯噪声
noise = np.random.normal(0,100,size=img.size).reshape(img.shape[0],img.shape[1])
img1 = img + noise
img1 = np.clip(img1,0,255)# 平滑处理
img2 = cv2.GaussianBlur(img1,(5,5),0)# 直方图双峰法
x,img3 = cv2.threshold(img,150,255,cv2.THRESH_BINARY)
x,img4 = cv2.threshold(img1,150,255,cv2.THRESH_BINARY)
x,img5 = cv2.threshold(img2,150,255,cv2.THRESH_BINARY)# 显示原始图像和恢复后的图像
plt.figure(figsize=(20, 20))
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(img1, cmap='gray')
plt.title('noise img'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(img4, cmap='gray')
plt.title('seg noise img '), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img5, cmap='gray')
plt.title('seg blur img '), plt.xticks([]), plt.yticks([])
plt.show()

1.2 迭代阈值图像分割

这一种自适应的图像分割方法,其主要思想是通过对图像的灰度值进行迭代,不断调整阈值使得分割更加准确。
分割步骤如下:

  1. 随机选取一个初始阈值(可以是图像的平均灰度值)
  2. 根据该阈值将图像分割成两部分:小于等于阈值的部分为前景,大于阈值的部分为背景
  3. 计算前景和背景的平均灰度值
  4. 将前景和背景的平均灰度值的平均值作为新的阈值
  5. 如果新的阈值和原来的阈值相同,则分割结束。否则,回到第2步,重复迭代直到收敛

代码:

#  迭代阈值图像分割法
import numpy as np
from PIL import Image# 读取图像
img = Image.open('house.tif').convert('L')
width, height = img.size
pixels = img.load()# 初始化阈值
threshold = 150
delta = 1
while delta > 0:# 根据阈值将图像分割foreground = []background = []for y in range(height):for x in range(width):if pixels[x, y] > threshold:background.append(pixels[x, y]) #大于阈值的部分为背景else:foreground.append(pixels[x, y]) #小于等于阈值的部分为前景avr_foreground = sum(foreground) // len(foreground)avr_background = sum(background) // len(background)# 更新阈值new_threshold = (avr_foreground + avr_background) // 2delta = abs(new_threshold - threshold)threshold = new_threshold# 重新分割图像
for y in range(height):for x in range(width):if pixels[x, y] > threshold:pixels[x, y] = 255else:pixels[x, y] = 0# 显示分割后的图像
img.show('result.jpg')

优点:1.迭代阈值图像分割相对于静态阈值分割而言,具有更高的实用性和鲁棒性。2.该方法能够有效地应对光照变化、背景复杂多样等情况下的图像分割问题。
缺点:对于大尺寸图像,迭代阈值图像分割的计算速度可能成为其一个缺点。

1.3 自适应阈值图像分割

1.3.1 常规方法

分割步骤如下:

  1. 针对输入的灰度图像,定义一个大小为 N × N N×N N×N 的窗口,在窗口中央选择一个像素点作为处理的核心像素点。
  2. 根据窗口内的像素信息计算局部阈值,作为当前像素的阈值,这个阈值可以是均值、中值、模式等统计量。
  3. 将处理完的像素点和当前像素点的局部阈值进行比较,大于等于阈值的像素点设置为白色,小于阈值的像素点设置为黑色,分割出新的二值化图像。
  4. 将窗口向图像的其他区域移动,继续对各个区域进行高斯自适应阈值分割,直到图像的所有区域都被分割为二值化图像。

代码:

# 自适应阈值图像分割
import numpy as np
from PIL import Image# 图像预处理
img = Image.open('house.tif').convert('L')
width, height = img.size
pixels = img.load()
block_size = 11  # 设置块大小# 分割图像并计算局部阈值
for y in range(0, height, block_size):for x in range(0, width, block_size):# 获取局部区域region = []for j in range(y, y+block_size):for i in range(x, x+block_size):if i < width and j < height:region.append(pixels[i, j])# 计算局部区域平均值作为阈值threshold = sum(region) // len(region)# 对区域进行二值化处理for j in range(y, y+block_size):for i in range(x, x+block_size):if i < width and j < height:if pixels[i, j] > threshold:pixels[i, j] = 255else:pixels[i, j] = 0#显示分割后的图像
img.show('result.jpg')

也可以直接调用cv2.adaptiveThreshold()函数实现。

import cv2
# 读取原始图像
img = cv2.imread('house.tif', 0)
# 自适应阈值分割
img_thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# 显示结果
cv2.imshow('Original Image', img)
cv2.imshow('Adaptive Thresholding', img_thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.3.2 大津法(OTSU)

大津法基于以下观察结果:
当图像被分为多个区域时,如果区域内的像素值差异较小,区域的均值方差就会较小。
而当区域内像素值差异较大时,区域的均值方差就会较大。
因此,局部图像的全局最佳阈值是能使类间方差最大的那个灰度级。

步骤:

代码:

import cv2# 读取图片
img = cv2.imread('house.tif', 0)# 大津法阈值分割
ret, img_thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示结果
cv2.imshow('Original Image', img)
cv2.imshow('OTSU Thresholding', img_thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

优点:多种检测任务效果较好。
缺点:计算量比较大,适用于数据量较小的图像分割场合。

参考文献:

[1] 阮秋琦,阮宇智译;(美)拉斐尔·C.冈萨雷斯,理查德·E.伍兹.国外电子书与通信教材系列 数字图像处理 第4版[M].北京:电子工业出版社,2020

图像分割---基于阈值处理的基本方法相关推荐

  1. 基于vc的数字图像分割——基于阙值的分割方法

    图像分割的依据是认为图像中各区域具有不同的特性(比如,灰度,颜色,纹理).图像分割的目的是将图像划分成若干个具有相近或相同特性的子区域,以便继续在分割成的相关区域中提取目标,并进而根据目标的特征或结构 ...

  2. 基于阈值方法的大津法(OTSU算法)---图像分割

    基于阈值方法的大津法(OTSU算法)---图像分割 主要分为三部分去实现: 1.基本概念 大津法:属于阈值分割的范畴.阈值分割方法:利用图像中要提取的目标物体和背景在灰度上的差异,选择一个合适的阈值, ...

  3. 基于阈值的7种图像分割方法以及Python实现

    阈值图像分割的7种方法 1. 什么是阈值分割 2. 固定阈值分割 3.灰度直方图双峰法 1. 什么是阈值分割 阈值分割是根据图像的灰度特征按照设定的阈值将图像分割成不同的子区域.简单的理解就是先将图像 ...

  4. 【CV】基于阈值处理的图像分割算法!

    图像处理 Author:louwill Machine Learning Lab 基于阈值的图像分割因其处理直观.实现简单和计算速度快,是一种更为常用的传统图像分割算法.本文基于图像灰度阈值处理的基本 ...

  5. 基于阈值处理的图像分割算法!

    图像处理 Author:louwill Machine Learning Lab 基于阈值的图像分割因其处理直观.实现简单和计算速度快,是一种更为常用的传统图像分割算法.本文基于图像灰度阈值处理的基本 ...

  6. 图像分割:基于阈值(Otsu)

    图像分割算法的综述参考论文<图像分割方法综述_黄鹏>,知网上很方便查到下载,而且时间而言比较新. 基于阈值的方法,最普遍的一个是二值化,将阈值以下和以上的分为两部分.应用比较广泛的有Ots ...

  7. [Python从零到壹] 六十.图像识别及经典案例篇之基于阈值及边缘检测的图像分割

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  8. 图像分割:阈值获取方法总结

    参考 http://www.cnblogs.com/BYTEMAN/archive/2012/07/22/2603572.html http://blog.sina.com.cn/s/blog_9f4 ...

  9. 基于阈值的图像二值化方法MATLAB

    文章目录 一.目录 二.摘要 三.实验步骤 3.1 固定阈值法 (1)计算均值和方差 (2)绘制和分析高斯分布图像 (3)以128为阈值进行固定阈值分割 (4)观察灰度直方图选择最优固定阈值 3.2 ...

最新文章

  1. 关于linux基础的博客,第一篇博客,以下。
  2. webstorm使用前的准备——Node.js安装及配置
  3. 二叉搜索树的删除操作可以交换吗_JavaScript数据结构 — 二叉搜索树(BST)ES6实现...
  4. 《中学生可以这样学Python》84节配套微课免费观看地址
  5. 企业级软件协作,没有数据怎么人工智能?
  6. 计算机图形学笔记------变换与光栅化的理论知识
  7. 贪吃蛇代码--c语言版 visual c++6.0打开
  8. USB无线网卡和PCI-E无线网卡如何选择?
  9. 个人独立开发的一款天气app
  10. CSS如何进行图片定位
  11. 2020面试题合集之吊打面试官系列(一),Android中为什么需要Handler
  12. 最小二乘法构建线性回归方程
  13. 达观数据:文字的起源与文本挖掘的前世今生
  14. pr零基础晋升笔记(学习复习用)
  15. Java API VIII
  16. SAP CO模块的英文缩写
  17. JavaSE02(类与对象)
  18. Docker安装Weblogic
  19. 使用uploadify进行上传
  20. java笔试--北京轩宇信息

热门文章

  1. win10下使内存修改可用与关闭windows defender
  2. 铁血论坛v4.0官方iPhone版
  3. 信道编码-卷积码、QC-LDPC码
  4. 520情人节程序员的浪漫告白~html+css+js浪漫星空❤爱心3D相册 (含音乐)
  5. 数据库系统概论——概念结构设计
  6. 使用rsync同步文件夹
  7. python中,‘str‘ object is not callable,对象不可调用
  8. 计算机中安装音乐软件是一种,零成本搭建卧室无线音乐系统(上)
  9. input、textarea设置光标位置 | ele.setSelectionRange()
  10. 微型计算机系统实验报告,《微型计算机系统原理及应用》实验报告1.doc