python计算机视觉编程第9章 图像分割

图像分割

图割(graph cut)

图割(Graph Cut)是图像处理领域中的一种基本技术,用于分割图像或者其他类型的图形。它的基本思想是将图像表示成一个图(图论中的概念),其中图的节点代表图像中的像素或者其他感兴趣的区域,图的边则代表节点之间的关系。

图割的主要应用之一是图像分割,即将图像中的像素分成若干个不同的区域或物体。这在计算机视觉领域中有广泛的应用,比如目标检测、图像编辑、医学图像分析等。

图割算法的基本原理是通过在图上定义一个能量函数(或成本函数),然后通过最小化这个能量函数来找到一个图的切割,将图分成若干部分。在图割中,割(Cut)指的是将图中的某些边删除,从而将图分成两个部分。最小割(Minimum Cut)就是寻找一个割,使得被割断的边的权重之和最小。

寻找最小割(minimum cut 或 min cut)等同于在源点和汇点间寻找最大流(maximum flow 或 max flow)

最大流不可能大于最小割,因为最大流所有的水流都一定经过最小割那些割边,流过的水流怎么可能比水管容量还大呢?
最大流不可能小于最小割,如果小,那么说明水管容量没有物尽其用,可以继续加大水流。
最大流 :把有向图看作是水管,容量就是能够通过该水管段最高单位流量。基于此类比,最大流就是从起点到终点所能达到的最高单位流量。

由于网上无法找到用最大流去做分割的相关文档以及相应的库,因此我推断,这种方法基本上已经被弃用,因此这里只做介绍不再进行实验。

利用聚类进行分割

利用聚类进行分割是一种计算机视觉和图像处理中常见的技术,它的目标是将图像中的像素分成几个不同的组(或类),每个组内的像素具有相似的特征。聚类分割的基本思想是根据像素之间的相似性将它们分组,从而形成具有某种内在结构的区域。

以下是利用聚类进行图像分割的基本步骤:

特征提取: 首先,需要从图像中提取用于聚类的特征。这些特征可以是像素的颜色、纹理、亮度等。在一些情况下,可以将图像像素的坐标也作为特征。

数据准备: 将提取的特征整理成一个特征向量,每个向量代表一个像素点的特征。这将形成一个数据集,其中每个样本都是一个特征向量。

选择聚类算法: 选择适合问题的聚类算法。K-Means是最常见的聚类算法之一,它将数据分成K个簇,每个簇由一个中心点代表。其他聚类算法包括层次聚类、DBSCAN等。

执行聚类: 使用选择的聚类算法对特征向量进行聚类。聚类算法将数据点分成不同的簇,每个簇都具有相似的特征。每个数据点都被分配到一个簇中。

分割图像: 根据聚类的结果,将原始图像中的像素分配给相应的簇。这将生成一个分割后的图像,其中每个像素都被赋予其所属的簇的特征。

后处理: 可能需要对分割结果进行一些后处理,以去除噪声、填充孔洞或平滑边界。这可以通过应用图像处理技术来实现。

显示结果: 将原始图像和分割后的图像进行对比显示,以便观察分割的效果。

聚类分割的优点在于它不需要预先定义对象的外观或位置,而是根据数据的内在结构来自动确定区域。然而,它也有一些限制,例如对初始聚类中心的敏感性、对聚类数的选择以及可能对噪声和变化敏感。

下面是用聚类进行分割的一个简单示例:

import cv2
import numpy as np
from sklearn.cluster import KMeans

# Load the image
image = cv2.imread('empire.jpg')
height, width, _ = image.shape
new_height = height // 5
new_width = width // 5
image = cv2.resize(image, (new_width, new_height))
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Reshape image into a feature vector
rows, cols, channels = image_rgb.shape
features = image_rgb.reshape(rows * cols, channels)

# Perform K-Means clustering
num_clusters = 3
kmeans = KMeans(n_clusters=num_clusters)
kmeans.fit(features)

# Get cluster labels for each pixel
cluster_labels = kmeans.labels_

# Assign pixels to cluster centers
segmented_image = kmeans.cluster_centers_[cluster_labels]
segmented_image = segmented_image.reshape(rows, cols, channels)

# Convert back to BGR for display
segmented_image_bgr = cv2.cvtColor(segmented_image.astype(np.uint8), cv2.COLOR_RGB2BGR)

# Display original and segmented images
cv2.imshow('Original Image', image)
cv2.imshow('Segmented Image', segmented_image_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()


在这里插入图片描述
可以看到结果还不错,能够比较正确的区分不同区域的物体。

变分法

Chan-Vese 分割模型对于待分割图像区域假定一个分片常数图像模型。这里我们集中关注两个区域的情形,比如前景和背景,不过这个模型也可以拓展到多区域,

用一组曲线将图像分成两个区域,分割通过最小化模型能量给出:
E ( Γ ) = λ length ⁡ ( Γ ) + ∫ Ω 1 ( I − c 1 ) 2 d x + ∫ Ω 2 ( I − c 2 ) 2 d x E(\Gamma)=\lambda\operatorname{length}(\Gamma)+\int_{\Omega_1}(I-c_1)^2\mathrm{d}\mathbf{x}+\int_{\Omega_2}(I-c_2)^2\mathrm{d}\mathbf{x} E(Γ)=λlength(Γ)+Ω1(Ic1)2dx+Ω2(Ic2)2dx

简单的示例代码:

import rof
from numpy import *
from PIL import Image

im = array(Image.open('houses.png').convert("L"))
U,T = rof.denoise(im,im,tolerance=0.001)
t = 0.4 # 阈值
from matplotlib.pyplot import *
imsave('result.pdf',U < t*U.max())
imshow(U < t*U.max(),'gray')

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值