热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数字图像处理第十章图像分割

文章目录1、概述2、阈值分割2.1定义2.2阈值选择方法2.3最佳阈值3、区域分割3.1区域生长法3.2区域分裂与合并4、总结1、概述图像分割就是把图像分成若干个特定的、具有独特

文章目录

  • 1、概述
  • 2、阈值分割
    • 2.1 定义
    • 2.2 阈值选择方法
    • 2.3 最佳阈值
  • 3、区域分割
    • 3.1 区域生长法
    • 3.2 区域分裂与合并
  • 4、总结


1、概述

图像分割就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。它是由图像处理到图像分析的关键步骤。从数学角度来看,图像分割是将数字图像划分成互不相交的区域的过程。它在机器视觉、人脸识别、指纹识别等多个领域都发挥着极为重要的作用。下面,我们来简单了解一下图像分割的几种方法。

2、阈值分割

2.1 定义

阈值分割:将所有灰度值大于或等于某阈值的像素都被判属于物体,将所有灰度值小于该阈值的像素被安排在物体之外,适用于物体与背景有较强对比的景物的分割。
由于阈值分割的直观性和易于实现的性质,使它在图像分割应用中处于中心地位。
在阈值分割中,阈值的选择将直接太影响分割效果,通常可以通过对灰度直方图的分析来确定它的值。当图像的直方图为双峰或多峰时,可选择两峰之间的谷底作为阈值。

2.2 阈值选择方法

1、人工选择
2、全局阈值
如果背景的灰度值在整个图像中可合理的看作为恒定,而且所有物体与背景都具有几乎相同的对比度,那么,只要选择了正确的阈值,使用一个固定的全局阈值一般会有较好的结果。
3、自适应阈值
在许多的情况下背景的灰度值并不是恒定的,这时,一个在图像某区域效果良好的阈值在其他区域却可能效果很差。在这种情况下,把灰度阈值取成一个随图像中位置缓慢变化的函数值时适宜的。

import cv2
import numpy as np
from matplotlib import pyplot as pltimg=cv2.imread(d:/imdata/coins.png',0) #0是第二个参数,将其转为灰度图img = cv2.medianBlur(img,5)
#全局阈值
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#自适应阈值
th2=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)#按均值进行阈值选择
titles = ['Original', 'Global Threshold', 'Adaptive threshold']
images = [img, th1, th2, th3]
for i in xrange(4):plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

在这里插入图片描述
从结果可以发现,自适应阈值法是要比全局阈值法好一些的。

2.3 最佳阈值

最佳阈值的选择:直方图技术、最大类间方差法、迭代法求阈值。
• 直方图技术:适用于图像直方图中有双峰或多峰的情况。其步骤为:
1、选择谷底
2、把阈值设在相对于两峰的某个固定位置。

• 最大类间法:又称为OTSU算法,该算法是在灰度直方图的基础上用最小二乘法原理推导出来的,具有统计意义上的最佳分割阈值。基本原理是以最佳阈值将图像的灰度直方图分割成两部分,使两部分之间的方差取最大值,及分离性最大。

• 迭代法
1)选择图像灰度值的中值作为初始阈值Ti=T0
2)利用阈值Ti将图像分割成两部分区域,R1和R2,并计算其灰度均值。
3)计算新的阈值Ti+1,Ti+1=1/2(u1+u2)
4)重复步骤2,3,直到小于某个给定值。

3、区域分割

阈值分割由于没有或很少考虑空间关系,使得阈值分割方法受到限制,这时候,区域分割法出现了。基于区域的分割方法可以弥补这方面的不足,它利用的是图像的空间性质,该方法认为分割出来的属于同一区域的像素应既有相似的性质,其概念是相当直观的。
传统的区域分割算法又区域生长法和分裂合并法两种。

3.1 区域生长法

区域生长是一种根据实现定义的准则将像素子区域聚合成更大区域的过程。
区域生长法主要考虑像素及其空间邻域像素的关系,其具体的步骤为:
1)选定一个或多个像素点作为种子。
2)按照某种相似性准则增长区域,逐步生成具有某种均匀性的空间区域,将相邻的具有相似性质的像素或区域归并从而逐步增长区域,直至没有可以归并的点或其他小区域为止。
• 区域内像素的相似性度量可以包括平均灰度值、纹理、颜色等信息。
• 生长准则:所考虑的像素点的灰度值和种子点区域的平均灰度值的差的绝对值小于或等于某个阈值T,就将该像素点归入种子点所在的区域。

区域分割法里比较重要的过程有:
1)选择合适的种子点
2)确定相似性准则(生长准则)
3)确定生长停止条件

import cv2
import numpy as np
import matplotlib.pyplot as plt#初始种子选择
def originalSeed(gray, th):ret, thresh = cv2.cv2.threshold(gray, th, 255, cv2.THRESH_BINARY)#二值图,种子区域(不同划分可获得不同种子)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))#3×3结构元thresh_copy = thresh.copy() #复制thresh_A到thresh_copy
thresh_B = np.zeros(gray.shape, np.uint8) #thresh_B大小与A相同,像素值为0seeds = [ ] #为了记录种子坐标#循环,直到thresh_copy中的像素值全部为0
while thresh_copy.any():Xa_copy, Ya_copy = np.where(thresh_copy > 0) #thresh_A_copy中值为255的像素的坐标thresh_B[Xa_copy[0], Ya_copy[0]] = 255 #选取第一个点,并将thresh_B中对应像素值改为255#连通分量算法,先对thresh_B进行膨胀,再和thresh执行and操作(取交集)for i in range(200):dilation_B = cv2.dilate(thresh_B, kernel, iterations=1)thresh_B = cv2.bitwise_and(thresh, dilation_B)#取thresh_B值为255的像素坐标,并将thresh_copy中对应坐标像素值变为0Xb, Yb = np.where(thresh_B > 0)thresh_copy[Xb, Yb] = 0#循环,在thresh_B中只有一个像素点时停止while str(thresh_B.tolist()).count("255") > 1:thresh_B = cv2.erode(thresh_B, kernel, iterations=1) #腐蚀操作X_seed, Y_seed = np.where(thresh_B > 0) #取处种子坐标if X_seed.size > 0 and Y_seed.size > 0:seeds.append((X_seed[0], Y_seed[0]))#将种子坐标写入seedsthresh_B[Xb, Yb] = 0 #将thresh_B像素值置零
return seedsdef regionGrow(gray, seeds, thresh, p):seedMark = np.zeros(gray.shape)#八邻域if p == 8:connection = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1)]elif p == 4:connection = [(-1, 0), (0, 1), (1, 0), (0, -1)]
#seeds内无元素时候生长停止while len(seeds) !&#61; 0:#栈顶元素出栈pt &#61; seeds.pop(0)for i in range(p):tmpX &#61; pt[0] &#43; connection[i][0]tmpY &#61; pt[1] &#43; connection[i][1]#检测边界点if tmpX <0 or tmpY <0 or tmpX >&#61; gray.shape[0] or tmpY >&#61; gray.shape[1]:continueif abs(int(gray[tmpX, tmpY]) - int(gray[pt])) gray &#61; cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
seeds &#61; originalSeed(gray, th&#61;53)
seedMark &#61; regionGrow(gray, seeds, thresh&#61;3, p&#61;8)
cv2.imshow("seedMark", seedMark)
cv2.waitKey(0)

在这里插入图片描述
可以看出&#xff0c;通过区域生长法分割后的图像&#xff0c;每一区域的差异十分明显。

3.2 区域分裂与合并

区域分裂合并算法的基本思想是先确定一个分裂合并的准则,当图像中某个区域的特征不一致时就将该区域分裂成4 个相等的子区域,当相邻的子区域满足一致性特征时则将它们合成一个大区域,直至所有区域不再满足分裂合并的条件为止。

import numpy as np
import cv2
def judge(w0, h0, w, h):a &#61; img[h0: h0 &#43; h, w0: w0 &#43; w]ave &#61; np.mean(a)std &#61; np.std(a, ddof&#61;1)count &#61; 0total &#61; 0for i in range(w0, w0 &#43; w):for j in range(h0, h0 &#43; h):if abs(img[j, i] - ave) <1 * std:count &#43;&#61; 1total &#43;&#61; 1if (count / total) <0.95:return Trueelse:return Falsedef draw(w0, h0, w, h):for i in range(w0, w0 &#43; w):for j in range(h0, h0 &#43; h):if img[j, i] > 175:img[j, i] &#61; 255else:img[j, i] &#61; 0def function(w0, h0, w, h):if judge(w0, h0, w, h) and (min(w, h) > 5):function(w0, h0, int(w / 2), int(h / 2))function(w0 &#43; int(w / 2), h0, int(w / 2), int(h / 2))function(w0, h0 &#43; int(h / 2), int(w / 2), int(h / 2))function(w0 &#43; int(w / 2), h0 &#43; int(h / 2), int(w / 2), int(h / 2))else:draw(w0, h0, w, h)img &#61; cv2.imread(&#39;d:/imdata/coins.png&#39;, 0)
img_input &#61; cv2.imread(&#39;d:/imdata/coins.png&#39;, 0)
height, width &#61; img.shape
function(0, 0, width, height)
cv2.imshow(&#39;input&#39;,img_input)
cv2.imshow(&#39;output&#39;,img)cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

4、总结

本章我们学习了图像分割的一些相关内容&#xff0c;了解了一些阈值分割和区域分割方法并进行了实验。图像分割是数字图像处理中极为重要的一部分&#xff0c;是我们以后学习目标识别内容所必须的基础知识。


推荐阅读
  • Java编程实现邻接矩阵表示稠密图的方法及实现类介绍
    本文介绍了Java编程如何实现邻接矩阵表示稠密图的方法,通过一个名为AMWGraph.java的类来构造邻接矩阵表示的图,并提供了插入结点、插入边、获取邻接结点等功能。通过使用二维数组来表示结点之间的关系,并通过元素的值来表示权值的大小,实现了稠密图的表示和操作。对于对稠密图的表示和操作感兴趣的读者可以参考本文。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • importjava.util.ArrayList;publicclassPageIndex{privateintpageSize;每页要显示的行privateintpageNum ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
author-avatar
手机用户2602886747
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有