欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望我们都能在人生路上开心快乐、共同成长。
该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。
第一部分作者介绍了图像处理基础知识,第二部分介绍了图像运算和图像增强,接下来第三部分我们将详细讲解图像识别及图像处理经典案例,该部分属于高阶图像处理知识,能进一步加深我们的理解和实践能力。图像分割是将图像分成若干具有独特性质的区域并提取感兴趣目标的技术和过程,它是图像处理和图像分析的关键步骤。主要分为基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法和基于特定理论的分割方法。本文将重点围绕图像处理实例,详细讲解各种图像分割的方法。希望文章对您有所帮助,如果有不足之处,还请海涵。
下载地址:记得点赞喔 O(∩_∩)O
前文赏析:(尽管该部分占大量篇幅,但我舍不得删除,哈哈!)
第一部分 基础语法
第二部分 网络爬虫
第三部分 数据分析和机器学习
第四部分 Python图像处理基础
第五部分 Python图像运算和图像增强
第六部分 Python图像识别和图像高阶案例
第七部分 NLP与文本挖掘
第八部分 人工智能入门知识
第九部分 网络攻防与AI安全
第十部分 知识图谱构建实战
扩展部分 人工智能高级案例
作者新开的“娜璋AI安全之家”将专注于Python和安全技术,主要分享Web渗透、系统安全、人工智能、大数据分析、图像识别、恶意代码检测、CVE复现、威胁情报分析等文章。虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础性文章对你有所帮助,在Python和安全路上与大家一起进步。
图像分割(Image Segmentation)技术是计算机视觉领域的重要研究方向,是图像语义理解和图像识别的重要一环。它是指将图像分割成若干具有相似性质的区域的过程,研究方法包括基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法和基于特定理论的分割方法(含图论、聚类、深度语义等)。该技术广泛应用于场景物体分割、人体背景分割、三维重建、车牌识别、人脸识别、无人驾驶、增强现实等行业[2-4]。如图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边缘检测的方法,下面的代码是对比常用的微分算子,如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算子分割图。
下面讲解另一种边缘检测的方法。在OpenCV中,可以通过cv2.findContours()函数从二值图像中寻找轮廓,其函数原型如下所示[3]:
在使用findContours()函数检测图像边缘轮廓后,通常需要和drawContours()函数联合使用,接着绘制检测到的轮廓,drawContours()函数的原型如下:
下面代码是使用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为最终提取的风景图的边缘线条。
本文主要讲解了常用的图像分割方法,包括基于阈值的图像分割方法、基于边缘检测的图像分割方法。希望读者能结合本文知识点,围绕自己的研究领域或工程项目进行深入的学习,实现所需的图像处理。
感谢在求学路上的同行者,不负遇见,勿忘初心。图像处理系列主要包括三部分,分别是:
2022年即将离去,又是忙碌的一年,感谢女神的鼓励和小珞治愈的笑容。守得云开见明月,加油!读博四年,还是写了一些东西,从初入安全的无知到现在的懵懂,也记录一些笔记,也希望对大家有所帮助。思过崖一周难忘的经历,心情五味陈杂,忙忙碌碌,期间还赶了论文修改的DDL前晚收到家人的生日祝福很开心,一句话就很温暖。回想那晚带上了他俩的照片,亲情永远那么美好。希望小珞珞永远开心,全家人平平安安,身体健康,爱你们喔!2022年最重要的事活着,希望大家都好。
(By:Eastmount 2022-12-23 夜于武汉 http://blog.csdn.net/eastmount/ )
参考文献: