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

欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望我们都能在人生路上开心快乐、共同成长。

该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。

第一部分作者介绍了图像处理基础知识,第二部分介绍了图像运算和图像增强,接下来第三部分我们将详细讲解图像识别及图像处理经典案例,该部分属于高阶图像处理知识,能进一步加深我们的理解和实践能力。图像分割是将图像分成若干具有独特性质的区域并提取感兴趣目标的技术和过程,它是图像处理和图像分析的关键步骤。主要分为基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法和基于特定理论的分割方法。本文将重点围绕图像处理实例,详细讲解各种图像分割的方法。希望文章对您有所帮助,如果有不足之处,还请海涵。

文章目录

  • 一.图像分割
  • 二.基于阈值的图像分割
  • 三.基于边缘检测的图像分割
  • 四.总结

下载地址:记得点赞喔 O(∩_∩)O

  • https://github.com/eastmountyxz/Python-zero2one
  • 开源600多页电子书:https://github.com/eastmountyxz/HWCloudImageRecognition

前文赏析:(尽管该部分占大量篇幅,但我舍不得删除,哈哈!)

第一部分 基础语法

  • [Python从零到壹] 一.为什么我们要学Python及基础语法详解
  • [Python从零到壹] 二.语法基础之条件语句、循环语句和函数
  • [Python从零到壹] 三.语法基础之文件操作、CSV文件读写及面向对象

第二部分 网络爬虫

  • [Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例
  • [Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解
  • [Python从零到壹] 六.网络爬虫之BeautifulSoup爬取豆瓣TOP250电影详解
  • [Python从零到壹] 七.网络爬虫之Requests爬取豆瓣电影TOP250及CSV存储
  • [Python从零到壹] 八.数据库之MySQL基础知识及操作万字详解
  • [Python从零到壹] 九.网络爬虫之Selenium基础技术万字详解(定位元素、常用方法、键盘鼠标操作)
  • [Python从零到壹] 十.网络爬虫之Selenium爬取在线百科知识万字详解(NLP语料构造必备技能)

第三部分 数据分析和机器学习

  • [Python从零到壹] 十一.数据分析之Numpy、Pandas、Matplotlib和Sklearn入门知识万字详解(1)
  • [Python从零到壹] 十二.机器学习之回归分析万字总结全网首发(线性回归、多项式回归、逻辑回归)
  • [Python从零到壹] 十三.机器学习之聚类分析万字总结全网首发(K-Means、BIRCH、层次聚类、树状聚类)
  • [Python从零到壹] 十四.机器学习之分类算法三万字总结全网首发(决策树、KNN、SVM、分类算法对比)
  • [Python从零到壹] 十五.文本挖掘之数据预处理、Jieba工具和文本聚类万字详解
  • [Python从零到壹] 十六.文本挖掘之词云热点与LDA主题分布分析万字详解
  • [Python从零到壹] 十七.可视化分析之Matplotlib、Pandas、Echarts入门万字详解
  • [Python从零到壹] 十八.可视化分析之Basemap地图包入门详解
  • [Python从零到壹] 十九.可视化分析之热力图和箱图绘制及应用详解
  • [Python从零到壹] 二十.可视化分析之Seaborn绘图万字详解
  • [Python从零到壹] 二十一.可视化分析之Pyechart绘图万字详解
  • [Python从零到壹] 二十二.可视化分析之OpenGL绘图万字详解
  • [Python从零到壹] 二十三.十大机器学习算法之决策树分类分析详解(1)
  • [Python从零到壹] 二十四.十大机器学习算法之KMeans聚类分析详解(2)
  • [Python从零到壹] 二十五.十大机器学习算法之KNN算法及图像分类详解(3)
  • [Python从零到壹] 二十六.十大机器学习算法之朴素贝叶斯算法及文本分类详解(4)
  • [Python从零到壹] 二十七.十大机器学习算法之线性回归算法分析详解(5)
  • [Python从零到壹] 二十八.十大机器学习算法之SVM算法分析详解(6)
  • [Python从零到壹] 二十九.十大机器学习算法之随机森林算法分析详解(7)
  • [Python从零到壹] 三十.十大机器学习算法之逻辑回归算法及恶意请求检测应用详解(8)
  • [Python从零到壹] 三十一.十大机器学习算法之Boosting和AdaBoost应用详解(9)
  • [Python从零到壹] 三十二.十大机器学习算法之层次聚类和树状图聚类应用详解(10)

第四部分 Python图像处理基础

  • [Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置
  • [Python从零到壹] 三十四.OpenCV入门详解——显示读取修改及保存图像
  • [Python从零到壹] 三十五.图像处理基础篇之OpenCV绘制各类几何图形
  • [Python从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解
  • [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制
  • [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)
  • [Python从零到壹] 三十九.图像处理基础篇之图像几何变换(镜像仿射透视)
  • [Python从零到壹] 四十.图像处理基础篇之图像量化处理
  • [Python从零到壹] 四十一.图像处理基础篇之图像采样处理
  • [Python从零到壹] 四十二.图像处理基础篇之图像金字塔向上取样和向下取样

第五部分 Python图像运算和图像增强

  • [Python从零到壹] 四十三.图像增强及运算篇之图像点运算和图像灰度化处理
  • [Python从零到壹] 四十四.图像增强及运算篇之图像灰度线性变换详解
  • [Python从零到壹] 四十五.图像增强及运算篇之图像灰度非线性变换详解
  • [Python从零到壹] 四十六.图像增强及运算篇之图像阈值化处理
  • [Python从零到壹] 四十七.图像增强及运算篇之腐蚀和膨胀详解
  • [Python从零到壹] 四十八.图像增强及运算篇之形态学开运算、闭运算和梯度运算
  • [Python从零到壹] 四十九.图像增强及运算篇之顶帽运算和底帽运算
  • [Python从零到壹] 五十.图像增强及运算篇之图像直方图理论知识和绘制实现
  • [Python从零到壹] 五十一.图像增强及运算篇之图像灰度直方图对比分析万字详解
  • [Python从零到壹] 五十二.图像增强及运算篇之图像掩膜直方图和HS直方图
  • [Python从零到壹] 五十三.图像增强及运算篇之直方图均衡化处理
  • [Python从零到壹] 五十四.图像增强及运算篇之局部直方图均衡化和自动色彩均衡化处理
  • [Python从零到壹] 五十五.图像增强及运算篇之图像平滑(均值滤波、方框滤波、高斯滤波)
  • [Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)
  • [Python从零到壹] 五十七.图像增强及运算篇之图像锐化Roberts、Prewitt算子实现边缘检测
  • [Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel、Laplacian算子实现边缘检测
  • [Python从零到壹] 五十九.图像增强及运算篇之图像锐化Scharr、Canny、LOG实现边缘检测

第六部分 Python图像识别和图像高阶案例

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

第七部分 NLP与文本挖掘

第八部分 人工智能入门知识

第九部分 网络攻防与AI安全

第十部分 知识图谱构建实战

扩展部分 人工智能高级案例

作者新开的“娜璋AI安全之家”将专注于Python和安全技术,主要分享Web渗透、系统安全、人工智能、大数据分析、图像识别、恶意代码检测、CVE复现、威胁情报分析等文章。虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础性文章对你有所帮助,在Python和安全路上与大家一起进步。


一.图像分割

图像分割(Image Segmentation)技术是计算机视觉领域的重要研究方向,是图像语义理解和图像识别的重要一环。它是指将图像分割成若干具有相似性质的区域的过程,研究方法包括基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法和基于特定理论的分割方法(含图论、聚类、深度语义等)。该技术广泛应用于场景物体分割、人体背景分割、三维重建、车牌识别、人脸识别、无人驾驶、增强现实等行业[2-4]。如图1所示,它将鲜花颜色划分为四个层级。

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

图像分割的目标是根据图像中的物体将图像的像素分类,并提取感兴趣的目标。图像分割是图像识别和计算机视觉至关重要的预处理,没有正确的分割就不可能有正确的识别。图像分割主要依据图像中像素的亮度及颜色,但计算机在自动处理分割时,会遇到各种困难,如光照不均匀、噪声影响、图像中存在不清晰的部分以及阴影等,常常发生图像分割错误。同时,随着深度学习和神经网络的发展,基于深度学习和神经网络的图像分割技术有效提高了分割的准确率,能够较好地解决图像中噪声和不均匀问题。


二.基于阈值的图像分割

最常用的图像分割方法是将图像灰度分为不同的等级,然后用设置灰度门限的方法确定有意义的区域或欲分割的物体边界。图像阈值化(Binarization)旨在剔除掉图像中一些低于或高于一定值的像素,从而提取图像中的物体,将图像的背景和噪声区分开来。图像阈值化可以理解为一个简单的图像分割操作,阈值又称为临界值,它的目的是确定出一个范围,然后这个范围内的像素点使用同一种方法处理,而阈值之外的部分则使用另一种处理方法或保持原样。

阈值化处理可以将图像中的像素划分为两类颜色,常见的阈值化算法如公式(1)所示,当某个像素点的灰度Gray(i,j)小于阈值T时,其像素设置为0,表示黑色;当灰度Gray(i,j)大于或等于阈值T时,其像素值为255,表示白色。

在这里插入图片描述

在Python的OpenCV库中,提供了固定阈值化函数threshold()和自适应阈值化函数adaptiveThreshold(),将一幅图像进行阈值化处理,前面第14篇文章详细介绍了图像阈值化处理方法,下面代码对比了不同阈值化算法的图像分割结果。

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#读取图像
img=cv2.imread('scenery.png')
grayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  

#阈值化处理
ret,thresh1=cv2.threshold(grayImage,127,255,cv2.THRESH_BINARY)  
ret,thresh2=cv2.threshold(grayImage,127,255,cv2.THRESH_BINARY_INV)  
ret,thresh3=cv2.threshold(grayImage,127,255,cv2.THRESH_TRUNC)  
ret,thresh4=cv2.threshold(grayImage,127,255,cv2.THRESH_TOZERO)  
ret,thresh5=cv2.threshold(grayImage,127,255,cv2.THRESH_TOZERO_INV)

#显示结果
titles = ['Gray Image','BINARY','BINARY_INV',
          'TRUNC','TOZERO','TOZERO_INV']  
images = [grayImage, 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.xticks([]),plt.yticks([])  
plt.show()

输出结果如图2所示,它将彩色风景图像转换成五种对应的阈值处理效果,包括二进制阈值化(BINARY)、反二进制阈值化(BINARY_INV)、截断阈值化(THRESH_TRUNC)、阈值化为0(THRESH_TOZERO)、反阈值化为0(THRESH_TOZERO_INV)。

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


三.基于边缘检测的图像分割

图像中相邻区域之间的像素集合共同构成了图像的边缘。基于边缘检测的图像分割方法是通过确定图像中的边缘轮廓像素,然后将这些像素连接起来构建区域边界的过程。由于沿着图像边缘走向的像素值变化比较平缓,而沿着垂直于边缘走向的像素值变化比较大,根据该特点,通常会采用一阶导数和二阶导数来描述和检测边缘。在前文中,详细讲解了Python边缘检测的方法,下面的代码是对比常用的微分算子,如Roberts、Prewitt、Sobel、Laplacian、Scharr、Canny、LOG等算子。

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread('scenery.png')
lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#高斯滤波
gaussianBlur = cv2.GaussianBlur(grayImage, (3,3), 0)

#阈值处理
ret, binary = cv2.threshold(gaussianBlur, 127, 255, cv2.THRESH_BINARY)

#Roberts算子
kernelx = np.array([[-1,0],[0,1]], dtype=int)
kernely = np.array([[0,-1],[1,0]], dtype=int)
x = cv2.filter2D(binary, cv2.CV_16S, kernelx)
y = cv2.filter2D(binary, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)     
absY = cv2.convertScaleAbs(y)    
Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#Prewitt算子
kernelx = np.array([[1,1,1],[0,0,0],[-1,-1,-1]], dtype=int)
kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]], dtype=int)
x = cv2.filter2D(binary, cv2.CV_16S, kernelx)
y = cv2.filter2D(binary, cv2.CV_16S, kernely)
absX = cv2.convertScaleAbs(x)  
absY = cv2.convertScaleAbs(y)    
Prewitt = cv2.addWeighted(absX,0.5,absY,0.5,0)

#Sobel算子
x = cv2.Sobel(binary, cv2.CV_16S, 1, 0)
y = cv2.Sobel(binary, cv2.CV_16S, 0, 1)    
absX = cv2.convertScaleAbs(x)   
absY = cv2.convertScaleAbs(y)    
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#拉普拉斯算法
dst = cv2.Laplacian(binary, cv2.CV_16S, ksize = 3)
Laplacian = cv2.convertScaleAbs(dst)


# Scharr算子
x = cv2.Scharr(gaussianBlur, cv2.CV_32F, 1, 0) #X方向
y = cv2.Scharr(gaussianBlur, cv2.CV_32F, 0, 1) #Y方向
absX = cv2.convertScaleAbs(x)       
absY = cv2.convertScaleAbs(y)
Scharr = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#Canny算子
Canny = cv2.Canny(gaussianBlur, 50, 150)

#先通过高斯滤波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)
 
#再通过拉普拉斯算子做边缘检测
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize = 3)
LOG = cv2.convertScaleAbs(dst)

#效果图
titles = ['Source Image', 'Binary Image', 'Roberts Image',
          'Prewitt Image','Sobel Image', 'Laplacian Image',
          'Scharr Image', 'Canny Image', 'LOG Image']
images = [lenna_img, binary, Roberts,
          Prewitt, Sobel, Laplacian,
          Scharr, Canny, LOG]
for i in np.arange(9):
   plt.subplot(3,3,i+1),plt.imshow(images[i],'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

输出结果如图3所示,它依次为原始图像、二值化图像、Roberts算子分割图、Prewitt算子分割图、Sobel算子分割图、Laplacian算子分割图、Scharr算子分割图、Canny算子分割图和LOG算子分割图。

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

下面讲解另一种边缘检测的方法。在OpenCV中,可以通过cv2.findContours()函数从二值图像中寻找轮廓,其函数原型如下所示[3]:

  • image, contours, hierarchy = findContours(image, mode, method[, contours[, hierarchy[, offset]]])
    – image表示输入图像,即用于寻找轮廓的图像,为8位单通道
    – contours表示检测到的轮廓,其函数运行后的结果存在该变量中,每个轮廓存储为一个点向量
    – hierarchy表示输出变量,包含图像的拓扑信息,作为轮廓数量的表示,它包含了许多元素,每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0]至hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号
    – mode表示轮廓检索模式。cv2.RETR_EXTERNAL表示只检测外轮廓;cv2.RETR_LIST表示提取所有轮廓,且检测的轮廓不建立等级关系;cv2.RETR_CCOMP提取所有轮廓,并建立两个等级的轮廓,上面的一层为外边界,里面一层为内孔的边界信;cv2.RETR_TREE表示提取所有轮廓,并且建立一个等级树或网状结构的轮廓
    – method表示轮廓的近似方法。cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2), abs(y1-y2))=1;cv2.CHAIN_APPROX_SIMPLE压缩水平方向、垂直方向、对角线方向的元素,只保留该方向的终点坐标,例如一个矩阵轮廓只需4个点来保存轮廓信息; cv2.CHAIN_APPROX_TC89_L1和cv2.CHAIN_APPROX_TC89_KCOS使用Teh-Chinl Chain近似算法
    – offset表示每个轮廓点的可选偏移量

在使用findContours()函数检测图像边缘轮廓后,通常需要和drawContours()函数联合使用,接着绘制检测到的轮廓,drawContours()函数的原型如下:

  • image = drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]])
    – image表示目标图像,即所要绘制轮廓的背景图片
    – contours表示所有的输入轮廓,每个轮廓存储为一个点向量
    – contourldx表示轮廓绘制的指示变量,如果为负数表示绘制所有轮廓
    – color表示绘制轮廓的颜色
    – thickness表里绘制轮廓线条的粗细程度,默认值为1
    – lineType表示线条类型,默认值为8,可选线包括8(8连通线型)、4(4连通线型)、CV_AA(抗锯齿线型)
    – hierarchy表示可选的层次结构信息
    – maxLevel表示用于绘制轮廓的最大等级,默认值为INT_MAX
    – offset表示每个轮廓点的可选偏移量

下面代码是使用cv2.findContours()检测图像轮廓,并调用cv2.drawContours()函数绘制出轮廓线条。

# -*- coding: utf-8 -*-
# By: Eastmount 
import cv2  
import numpy as np  
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread('scenery.png')
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#灰度化处理图像
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#阈值化处理
ret, binary = cv2.threshold(grayImage, 0, 255,
                            cv2.THRESH_BINARY+cv2.THRESH_OTSU) 

#边缘检测
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE,
                                              cv2.CHAIN_APPROX_SIMPLE) 

#轮廓绘制
cv2.drawContours(img, contours, -1, (0, 255, 0), 1)

#显示图像5
cv2.imshow('gray', binary)
cv2.imshow('res', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

图4为图像阈值化处理效果图,图5为最终提取的风景图的边缘线条。

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

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


四.总结

本文主要讲解了常用的图像分割方法,包括基于阈值的图像分割方法、基于边缘检测的图像分割方法。希望读者能结合本文知识点,围绕自己的研究领域或工程项目进行深入的学习,实现所需的图像处理。

感谢在求学路上的同行者,不负遇见,勿忘初心。图像处理系列主要包括三部分,分别是:

在这里插入图片描述

在这里插入图片描述

请添加图片描述

2022年即将离去,又是忙碌的一年,感谢女神的鼓励和小珞治愈的笑容。守得云开见明月,加油!读博四年,还是写了一些东西,从初入安全的无知到现在的懵懂,也记录一些笔记,也希望对大家有所帮助。思过崖一周难忘的经历,心情五味陈杂,忙忙碌碌,期间还赶了论文修改的DDL前晚收到家人的生日祝福很开心,一句话就很温暖。回想那晚带上了他俩的照片,亲情永远那么美好。希望小珞珞永远开心,全家人平平安安,身体健康,爱你们喔!2022年最重要的事活着,希望大家都好。

在这里插入图片描述

(By:Eastmount 2022-12-23 夜于武汉 http://blog.csdn.net/eastmount/ )


参考文献:

  • [1]冈萨雷斯著. 数字图像处理(第3版)[M]. 北京:电子工业出版社,2013.
  • [2]阮秋琦. 数字图像处理学(第3版)[M]. 北京:电子工业出版社,2008.
  • [3]毛星云,冷雪飞. OpenCV3编程入门[M]. 北京:电子工业出版社,2015.
  • [4]张铮,王艳平,薛桂香等. 数字图像处理与机器视觉——Visual C++与Matlab实现[M]. 北京:人民邮电出版社,2014.
  • [5]Jumping boy. python+OpenCV图像处理(十一)图像轮廓检测[EB/OL]. (2018-08-30). https://blog.csdn.net/qq_40962368/article/details/82078732.
  • [6]Eastmount. [Python图像处理] 四十.全网首发Python图像分割万字详解(阈值分割、边缘分割、纹理分割、分水岭算法、K-Means分割、漫水填充分割、区域定位)[EB/OL]. (2021-05-18). https://blog.csdn.net/Eastmount/article/details/116952580.
  • [7]杨秀璋, 颜娜. Python网络数据爬取及分析从入门到精通(分析篇)[M]. 北京:北京航天航空大学出版社, 2018.
  • [8]Fukunaga K. and Hostetler L.D. The Estimation of the Gradient of a Density Function, with Applications in Pattern Recognition[J]. IEEE Transactions on Information Theory, 1975, 21, 32-10.

你可能感兴趣的:(Python从零到壹,Python学习系列,python,opencv,计算机视觉,图像分割)