计算机视觉实验五——图像分割

计算机视觉实验五------图像分割

一、实验目标

  1. 了解图割操作,实现用户交互式分割,通过在一幅图像上为前景和背景提供一些标记或利用边界框选择一个包含前景的区域,实现分割。
  2. 采用聚类法实现图像的分割(K-means方法)。

二、实验内容

1.了解图割操作,实现用户交互式分割,通过在一幅图像上为前景和背景提供一些标记或利用边界框选择一个包含前景的区域,实现分割

①图片准备

博主选择了一张前景与背景区分明显 的图片,和一张前景与背景区分不明显 的图片:

②代码

python 复制代码
import cv2
import numpy as np

img = cv2.imread('building.jpg')
img = cv2.resize(img, (960, 720))

# 创建一个和图像大小相同的掩码,用于存储分割结果
mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)


# 定义鼠标回调函数,用于获取用户画出的矩形框
def draw_rect(event, x, y, flags, param):
    global ix, iy, drawing, rect_over

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            img_copy = img.copy()
            cv2.rectangle(img_copy, (ix, iy), (x, y), (0, 255, 0), 2)
            cv2.imshow('image', img_copy)

    # 调用grabCut算法进行分割
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        rect_over = True
        cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 2)
        rect = (min(ix, x), min(iy, y), abs(ix - x), abs(iy - y))
        cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
        cv2.imshow('image', img)


# 创建一个窗口,绑定鼠标回调函数
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_rect)

drawing = False  # 是否正在画矩形框
ix, iy = -1, -1  # 矩形框的起始坐标
rect_over = False  # 是否画完矩形框

while True:
    cv2.imshow('image', img)
    k = cv2.waitKey(1) & 0xFF

    # 如果画完矩形框,根据掩码显示分割结果
    if rect_over == True:
        mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
        img_cut = img * mask2[:, :, np.newaxis]
        cv2.imshow('result', img_cut)

    if k == 27:
        break

cv2.destroyAllWindows()

③运行结果

(1)前景与背景区分明显的图片

用鼠标画出矩形框:

分割结果:

(2)前景与背景区分不明显的图片

用鼠标画出矩形框:

分割结果:

④代码说明

使用了OpenCV库中的grabCut算法。此算法的原理是基于图割(graph cut)的思想,根据颜色信息和空间信息,将图像划分为四个部分:确定的背景、可能的背景、可能的前景和确定的前景。它会迭代地更新这四个部分,直到收敛为止。

  • 首先,读取一张图像,并创建一个和图像大小相同的掩码,用于存储分割结果。
  • 创建grabCut算法需要的背景和前景模型,用于存储颜色信息。
  • 定义一个鼠标回调函数,用于获取用户画出的矩形框(矩形框表示要分割出来的前景对象)。
  • 在这个函数中,当用户按下鼠标左键时,开始画矩形框,并记录起始坐标。当用户移动鼠标时,更新矩形框,并在图像上显示。当用户松开鼠标左键时,结束画矩形框,并调用grabCut算法进行分割。

2.采用聚类法实现图像的分割(K-means方法)

①代码

python 复制代码
import numpy as np
import cv2
from sklearn.cluster import KMeans

# 读取图像并转换为RGB格式
img = cv2.imread('building.jpg')

img = cv2.resize(img, (960, 720))

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 将图像数据转换为二维数组
h, w, c = img.shape
data = img.reshape((h * w, c))

# 使用K-means聚类算法对图像数据进行分割,设置聚类数为3
kmeans = KMeans(n_clusters=3, random_state=0)
kmeans.fit(data)

# 获取聚类标签和中心点
labels = kmeans.labels_
centers = kmeans.cluster_centers_

# 将聚类标签转换为图像数据
labels = labels.reshape((h, w))
result = np.zeros((h, w, c), dtype=np.uint8)

# 根据聚类中心点给每个像素赋予相应的颜色
for i in range(h):
    for j in range(w):
        result[i, j] = centers[labels[i, j]]

# 显示原始图像和分割后的图像
cv2.imshow('Original', img)
cv2.imshow('Segmented', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

②运行结果

(1)前景与背景区分明显的图片

(2)前景与背景区分不明显的图片

③代码说明

使用了K-means方法 实现图像的分割,K-means是一种基于划分的聚类算法,它的目标是将数据集划分为K个簇,使得每个数据点属于离它最近的簇中心所代表的簇。

在代码中,首先导入了numpy和cv2两个库,numpy用于处理数组和矩阵,cv2用于处理图像。然后读取了一张图像,并将其转换为RGB格式。接着将图像数据转换为二维数组,再使用sklearn.cluster中的KMeans类来进行聚类并对数据进行拟合。拟合后,可以获取聚类标签和中心点,再将聚类标签转换为图像数据,根据聚类中心给每个像素赋予相应的颜色,得到分割后的图像。最后显示原始图像和分割后的图像。

相关推荐
我没胡说八道2 小时前
高校论文AI检测优化工具对比研究与实测分析(2026)
人工智能·深度学习·机器学习·计算机视觉·aigc·论文
秦亚伟2 小时前
AI浪潮重塑融资租赁行业新格局
人工智能
love530love2 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
元启数宇2 小时前
喷淋AI布点实战:8小时人工布点→20分钟自动出图
人工智能
哈哈,柳暗花明2 小时前
人工智能专业术语详解(H)
人工智能·专业术语
圣殿骑士-Khtangc2 小时前
AI 编程工具 2026 实战横评:Cursor 3 vs Claude Code vs Copilot,开发者选型完全指南
人工智能·copilot
云器科技2 小时前
云器Lakehouse 2026年5月版本发布:拥抱 AI Agent,重塑数据智能开发新范式
人工智能
小鹰-上海鹰谷-电子实验记录本2 小时前
第六届党建引领科创生态座谈会 | 邓光辉博士出席分享AI赋能创新药科研新范式
人工智能·ai·电子实验记录本·药企合规
遇事不決洛必達2 小时前
【Python基础】GIL 锁是什么及其对爬虫的影响
爬虫·python·线程·进程·gil锁
极客老王说Agent2 小时前
2026电信IDC机房巡检深度报告:人工巡检频次和深度够吗?实在Agent重塑智慧运维新范式
人工智能·ai·chatgpt