Python基于纹理背景和聚类算法实现图像分割详解

目录
  • 一.基于纹理背景的图像分割
  • 二.基于K-Means聚类算法的区域分割
  • 三.总结

一.基于纹理背景的图像分割

该部分主要讲解基于图像纹理信息(颜色)、边界信息(反差)和背景信息的图像分割算法。在OpenCV中,GrabCut算法能够有效地利用纹理信息和边界信息分割背景,提取图像目标物体。该算法是微软研究院基于图像分割和抠图的课题,它能有效地将目标图像分割提取,如图1所示[1]。

GrabCut算法原型如下所示:

mask, bgdModel, fgdModel = grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode])

– image表示输入图像,为8位三通道图像

– mask表示蒙板图像,输入/输出的8位单通道掩码,确定前景区域、背景区域、不确定区域。当模式设置为GC_INIT_WITH_RECT时,该掩码由函数初始化

– rect表示前景对象的矩形坐标,其基本格式为(x, y, w, h),分别为左上角坐标和宽度、高度

– bdgModel表示后台模型使用的数组,通常设置为大小为(1, 65)np.float64的数组

– fgdModel表示前台模型使用的数组,通常设置为大小为(1, 65)np.float64的数组

– iterCount表示算法运行的迭代次数

– mode是cv::GrabCutModes操作模式之一,cv2.GC_INIT_WITH_RECT 或 cv2.GC_INIT_WITH_MASK表示使用矩阵模式或蒙板模式

下面是Python的实现代码,通过调用np.zeros()函数创建掩码、fgbModel和bgModel,接着定义rect矩形范围,调用函数grabCut()实现图像分割。由于该方法会修改掩码,像素会被标记为不同的标志来指明它们是背景或前景。接着将所有的0像素和2像素点赋值为0(背景),而所有的1像素和3像素点赋值为1(前景),完整代码如下所示。

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

#读取图像
img = cv2.imread('nv.png')

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

#设置掩码、fgbModel、bgModel
mask = np.zeros(img.shape[:2], np.uint8)
bgdModel = np.zeros((1,65), np.float64)
fgdModel = np.zeros((1,65), np.float64)

#矩形坐标
rect = (100, 100, 500, 800)

#图像分割
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5,
            cv2.GC_INIT_WITH_RECT)

#设置新掩码:0和2做背景
mask2 = np.where((mask==2)|(mask==0), 0, 1).astype('uint8')

#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']

#显示原图
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.subplot(1,2,1)
plt.imshow(img)
plt.title('(a)原始图像')

plt.xticks([]), plt.yticks([])

#使用蒙板来获取前景区域
img = img*mask2[:, :, np.newaxis]
plt.subplot(1,2,2)
plt.imshow(img)
plt.title('(b)目标图像')

plt.colorbar()
plt.xticks([]), plt.yticks([])
plt.show()

输出图像如图2所示,图2(a)为原始图像,图2(b)为图像分割后提取的目标人物,但人物右部分的背景仍然存在。如何移除这些背景呢?这里需要使用自定义的掩码进行提取,读取一张灰色背景轮廓图,从而分离背景与前景,希望读者下来实现该功能。

二.基于K-Means聚类算法的区域分割

K-Means聚类是最常用的聚类算法,最初起源于信号处理,其目标是将数据点划分为K个类簇,找到每个簇的中心并使其度量最小化。该算法的最大优点是简单、便于理解,运算速度较快,缺点是只能应用于连续型数据,并且要在聚类前指定聚集的类簇数[2]。

下面是K-Means聚类算法的分析流程,步骤如下:

  • 第一步,确定K值,即将数据集聚集成K个类簇或小组;
  • 第二步,从数据集中随机选择K个数据点作为质心(Centroid)或数据中心;
  • 第三步,分别计算每个点到每个质心之间的距离,并将每个点划分到离最近质心的小组,跟定了那个质心;
  • 第四步,当每个质心都聚集了一些点后,重新定义算法选出新的质心;
  • 第五步,比较新的质心和老的质心,如果新质心和老质心之间的距离小于某一个阈值,则表示重新计算的质心位置变化不大,收敛稳定,则认为聚类已经达到了期望的结果,算法终止;
  • 第六步,如果新的质心和老的质心变化很大,即距离大于阈值,则继续迭代执行第三步到第五步,直到算法终止。

图29-3是对身高和体重进行聚类的算法,将数据集的人群聚集成三类。

在图像处理中,通过K-Means聚类算法可以实现图像分割、图像聚类、图像识别等操作,本小节主要用来进行图像颜色分割。假设存在一张100×100像素的灰度图像,它由10000个RGB灰度级组成,我们通过K-Means可以将这些像素点聚类成K个簇,然后使用每个簇内的质心点来替换簇内所有的像素点,这样就能实现在不改变分辨率的情况下量化压缩图像颜色,实现图像颜色层级分割。

在OpenCV中,Kmeans()函数原型如下所示:

retval, bestLabels, centers = kmeans(data, K, bestLabels, criteria, attempts, flags[, centers])

– data表示聚类数据,最好是np.flloat32类型的N维点集

– K表示聚类类簇数

– bestLabels表示输出的整数数组,用于存储每个样本的聚类标签索引

– criteria表示算法终止条件,即最大迭代次数或所需精度。在某些迭代中,一旦每个簇中心的移动小于criteria.epsilon,算法就会停止

– attempts表示重复试验kmeans算法的次数,算法返回产生最佳紧凑性的标签

– flags表示初始中心的选择,两种方法是cv2.KMEANS_PP_CENTERS ;和cv2.KMEANS_RANDOM_CENTERS

– centers表示集群中心的输出矩阵,每个集群中心为一行数据

下面使用该方法对灰度图像颜色进行分割处理,需要注意,在进行K-Means聚类操作之前,需要将RGB像素点转换为一维的数组,再将各形式的颜色聚集在一起,形成最终的颜色分割。

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

#读取原始图像灰度颜色
img = cv2.imread('scenery.png', 0) 

#获取图像高度、宽度
rows, cols = img.shape[:]

#图像二维像素转换为一维
data = img.reshape((rows * cols, 1))
data = np.float32(data)

#定义中心 (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

#设置标签
flags = cv2.KMEANS_RANDOM_CENTERS

#K-Means聚类 聚集成4类
compactness, labels, centers = cv2.kmeans(data, 4, None, criteria, 10, flags)

#生成最终图像
dst = labels.reshape((img.shape[0], img.shape[1]))

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图像
titles = ['原始图像', '聚类图像']
images = [img, dst]
for i in range(2):
   plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray'),
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

输出结果如图4所示,左边为灰度图像,右边为K-Means聚类后的图像,它将灰度级聚集成四个层级,相似的颜色或区域聚集在一起。

下面代码是对彩色的图像进行颜色分割处理,它将彩色的图像聚集成2类、4类和64类。

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

#读取原始图像
img = cv2.imread('scenery.png') 

#图像二维像素转换为一维
data = img.reshape((-1,3))
data = np.float32(data)

#定义中心 (type,max_iter,epsilon)
criteria = (cv2.TERM_CRITERIA_EPS +
            cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)

#设置标签
flags = cv2.KMEANS_RANDOM_CENTERS

#K-Means聚类 聚集成2类
compactness, labels2, centers2 = cv2.kmeans(data, 2, None, criteria, 10, flags)

#K-Means聚类 聚集成4类
compactness, labels4, centers4 = cv2.kmeans(data, 4, None, criteria, 10, flags)

#K-Means聚类 聚集成8类
compactness, labels8, centers8 = cv2.kmeans(data, 8, None, criteria, 10, flags)

#K-Means聚类 聚集成16类
compactness, labels16, centers16 = cv2.kmeans(data, 16, None, criteria, 10, flags)

#K-Means聚类 聚集成64类
compactness, labels64, centers64 = cv2.kmeans(data, 64, None, criteria, 10, flags)

#图像转换回uint8二维类型
centers2 = np.uint8(centers2)
res = centers2[labels2.flatten()]
dst2 = res.reshape((img.shape))

centers4 = np.uint8(centers4)
res = centers4[labels4.flatten()]
dst4 = res.reshape((img.shape))

centers8 = np.uint8(centers8)
res = centers8[labels8.flatten()]
dst8 = res.reshape((img.shape))

centers16 = np.uint8(centers16)
res = centers16[labels16.flatten()]
dst16 = res.reshape((img.shape))

centers64 = np.uint8(centers64)
res = centers64[labels64.flatten()]
dst64 = res.reshape((img.shape))

#图像转换为RGB显示
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
dst2 = cv2.cvtColor(dst2, cv2.COLOR_BGR2RGB)
dst4 = cv2.cvtColor(dst4, cv2.COLOR_BGR2RGB)
dst8 = cv2.cvtColor(dst8, cv2.COLOR_BGR2RGB)
dst16 = cv2.cvtColor(dst16, cv2.COLOR_BGR2RGB)
dst64 = cv2.cvtColor(dst64, cv2.COLOR_BGR2RGB)

#用来正常显示中文标签
plt.rcParams['font.sans-serif']=['SimHei']

#显示图像
titles = ['原始图像', '聚类图像 K=2', '聚类图像 K=4',
          '聚类图像 K=8', '聚类图像 K=16', '聚类图像 K=64']
images = [img, dst2, dst4, dst8, dst16, dst64]
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()

输出结果如图5所示,它对比了原始图像和各K-Means聚类处理后的图像。当K=2时,聚集成2种颜色;当K=4时,聚集成4种颜色;当K=8时,聚集成8种颜色;当K=16时,聚集成16种颜色;当K=64时,聚集成64种颜色。

同样,如果是人物图像显示如图6所示,比如小珞珞。

三.总结

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

到此这篇关于Python基于纹理背景和聚类算法实现图像分割详解的文章就介绍到这了,更多相关Python图像分割内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python 第三方opencv库实现图像分割处理

    目录 前言 1.加载图片 2.对图片做灰度处理 3.对图片做二值化处理 3.1.自定义阈值 4.提取轮廓 5.对轮廓画矩形框 6.分割图片并保存 7.查看分割图片 8.完整代码 前言 所需要安装的库有: pip install opencv-python pip install matplotlib Python接口帮助文档网址:https://docs.opencv.org/4.5.2/d6/d00/tutorial_py_root.html 本文所用到的图片素材: 首先,导入所用到的库: i

  • 通过PYTHON来实现图像分割详解

    程序思路: 此次程序主要是利用PIL(Python Image Libraty)这库,来进行图片的处理. PIL是一个功能非常强大的python图像处理标准库,但由于PIL只支持python2.7.如今很多python程序员都使用python3.x,所以PIL在之前的基础上分离出来一个分支,另外创建一个Pillow库,以便支持python3.x, 本程序在使用之前确保已经安装了Pillow库. 程序首先把你要分隔的图像读取到一个变量中,然后我们定义了一个 fill_image() 方法,用来填充

  • python基于K-means聚类算法的图像分割

    1 K-means算法 实际上,无论是从算法思想,还是具体实现上,K-means算法是一种很简单的算法.它属于无监督分类,通过按照一定的方式度量样本之间的相似度,通过迭代更新聚类中心,当聚类中心不再移动或移动差值小于阈值时,则就样本分为不同的类别. 1.1 算法思路 随机选取聚类中心 根据当前聚类中心,利用选定的度量方式,分类所有样本点 计算当前每一类的样本点的均值,作为下一次迭代的聚类中心 计算下一次迭代的聚类中心与当前聚类中心的差距 如4中的差距小于给定迭代阈值时,迭代结束.反之,至2继续下

  • 基于Python的图像阈值化分割(迭代法)

    1.阈值化分割原理 通过对图像的灰度直方图进行数学统计,选择一个或多个阈值将像素划分为若干类.一般情况下,当图像由灰度值相差较大的目标和背景组成时,如果目标区域内部像素灰度分布均匀一致,背景区域像素在另一个灰度级上也分布均匀,这时图像的灰度直方图会呈现出双峰特性. 在这种情况下,选取位于这两个峰值中间的谷底对应的灰度值T作为灰度阈值,将图像中各个像素的灰度值与这个阈值进行比较,根据比较的结果将图像中的像素划分到两个类中.像素灰度值大于阈值T的像素点归为一类,其余像素点归为另一类.经阈值化处理后的

  • python中的opencv 图像分割与提取

    目录 图像分割与提取 用分水岭算法实现图像分割与提取 算法原理 相关函数介绍 分水岭算法图像分割实例 交互式前景提取 图像分割与提取 图像中将前景对象作为目标图像分割或者提取出来.对背景本身并无兴趣分水岭算法及GrabCut算法对图像进行分割及提取. 用分水岭算法实现图像分割与提取 分水岭算法将图像形象地比喻为地理学上的地形表面,实现图像分割,该算法非常有效. 算法原理 任何一幅灰度图像,都可以被看作是地理学上的地形表面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷. 左图是原

  • Python基于纹理背景和聚类算法实现图像分割详解

    目录 一.基于纹理背景的图像分割 二.基于K-Means聚类算法的区域分割 三.总结 一.基于纹理背景的图像分割 该部分主要讲解基于图像纹理信息(颜色).边界信息(反差)和背景信息的图像分割算法.在OpenCV中,GrabCut算法能够有效地利用纹理信息和边界信息分割背景,提取图像目标物体.该算法是微软研究院基于图像分割和抠图的课题,它能有效地将目标图像分割提取,如图1所示[1]. GrabCut算法原型如下所示: mask, bgdModel, fgdModel = grabCut(img,

  • Python 基于FIR实现Hilbert滤波器求信号包络详解

    在通信领域,可以通过希尔伯特变换求解解析信号,进而求解窄带信号的包络. 实现希尔伯特变换有两种方法,一种是对信号做FFT,单后只保留单边频谱,在做IFFT,我们称之为频域方法:另一种是基于FIR根据传递函数设计一个希尔伯特滤波器,我们称之为时域方法. # -*- coding:utf8 -*- # @TIME : 2019/4/11 18:30 # @Author : SuHao # @File : hilberfilter.py import scipy.signal as signal im

  • Python基于keras训练实现微笑识别的示例详解

    目录 一.数据预处理 二.训练模型 创建模型 训练模型 训练结果 三.预测 效果 四.源代码 pretreatment.py train.py predict.py 一.数据预处理 实验数据来自genki4k 提取含有完整人脸的图片 def init_file():     num = 0     bar = tqdm(os.listdir(read_path))     for file_name in bar:         bar.desc = "预处理图片: "      

  • Python基于OpenCV库Adaboost实现人脸识别功能详解

    本文实例讲述了Python基于OpenCV库Adaboost实现人脸识别功能.分享给大家供大家参考,具体如下: 以前用Matlab写神经网络的面部眼镜识别算法,研究算法逻辑,采集大量训练数据,迭代,计算各感知器的系数...相当之麻烦~而现在运用调用pythonOpenCV库Adaboost算法,无需知道算法逻辑,无需进行模型训练,人脸识别变得相当之简单了. 需要用到的库是opencv(open source computer vision),下载安装方式如下: 使用pip install num

  • Python基于机器学习方法实现的电影推荐系统实例详解

    推荐算法在互联网行业的应用非常广泛,今日头条.美团点评等都有个性化推荐,推荐算法抽象来讲,是一种对于内容满意度的拟合函数,涉及到用户特征和内容特征,作为模型训练所需维度的两大来源,而点击率,页面停留时间,评论或下单等都可以作为一个量化的 Y 值,这样就可以进行特征工程,构建出一个数据集,然后选择一个合适的监督学习算法进行训练,得到模型后,为客户推荐偏好的内容,如头条的话,就是咨询和文章,美团的就是生活服务内容. 可选择的模型很多,如协同过滤,逻辑斯蒂回归,基于DNN的模型,FM等.我们使用的方式

  • python 基于TCP协议的套接字编程详解

    基于TCP协议的套接字编程 实现电话沟通为例,这里传递的是字符,可以自己尝试去发送一个文件 # 服务端 import socket # 1. 符合TCP协议的手机 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # TCP # 2. 绑定手机号 一个服务器,我们自己的电脑作为服务器的话,用自己的IP地址 server.bind(('127.0.0.1',8000)) # 127.0.0.1 代表本地 # server.bind(

  • Python基于Opencv来快速实现人脸识别过程详解(完整版)

    前言 随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界. 首先看一下本实验需要的数据集,为了简便我们只进行两个人的识别,选取了beyond乐队的主唱黄家驹和贝斯手黄家强,这哥俩长得有几分神似,这也是对人脸识别的一个考验: 两个文件夹,一个为训练数据集,一个为测试数据集,训练数据集中有两个文件夹0和1,之前看一些资料有说这里要遵循"slabel"命名规则,但后面处理起来比较麻烦,

  • Python基于sklearn库的分类算法简单应用示例

    本文实例讲述了Python基于sklearn库的分类算法简单应用.分享给大家供大家参考,具体如下: scikit-learn已经包含在Anaconda中.也可以在官方下载源码包进行安装.本文代码里封装了如下机器学习算法,我们修改数据加载函数,即可一键测试: # coding=gbk ''' Created on 2016年6月4日 @author: bryan ''' import time from sklearn import metrics import pickle as pickle

  • Python中八大图像特效算法的示例详解

    目录 0写在前面 1毛玻璃特效 2浮雕特效 3油画特效 4马赛克特效 5素描特效 6怀旧特效 7流年特效 8卡通特效 0 写在前面 图像特效处理是基于图像像素数据特征,将原图像进行一定步骤的计算——例如像素作差.灰度变换.颜色通道融合等,从而达到期望的效果.图像特效处理是日常生活中应用非常广泛的一种计算机视觉应用,出现在各种美图软件中,这些精美滤镜背后的数学原理都是相通的,本文主要介绍八大基本图像特效算法,在这些算法基础上可以进行二次开发,生成更高级的滤镜. 本文采用面向对象设计,定义了一个图像

  • 基于Python数据可视化利器Matplotlib,绘图入门篇,Pyplot详解

    Pyplot matplotlib.pyplot是一个命令型函数集合,它可以让我们像使用MATLAB一样使用matplotlib.pyplot中的每一个函数都会对画布图像作出相应的改变,如创建画布.在画布中创建一个绘图区.在绘图区上画几条线.给图像添加文字说明等.下面我们就通过实例代码来领略一下他的魅力. import matplotlib.pyplot as plt plt.plot([1,2,3,4]) plt.ylabel('some numbers') plt.show() 上图是我们通

随机推荐