【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法

【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法
【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法
【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】


【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法


6. 图像分割之图割法

基于图论的图像分割技术的基本思想是:将图像映射为带权的无向图,把像素视为节点,两个节点之间的边的权重对应于两个像素之间相似性的度量,割的容量就对应于能量函数;使用最大流最小割算法对图进行切割,得到的最小割就对应于最优图像分割。

6.1 图割分割算法 Graph cuts

将图像表示为无向图后,基于网络流优化技术求解最小图割,以获得图像分割结果。

一个图或网络的割表示一个切面或切线,将图或网络分为分别包含源点和汇点的两个子集,该切线或切面与网络相交的楞或边的集合,称为图像的割。最小割(Minimum cut),是指边的容量(权重)之和最小的割。

图论中的最大流最小割定理指出,从源点到汇点的最大流等于最小割,因此最小割问题等价于最大流问题。求解最大流问题有很多高效的多项式时间算法, 可以应用于图像分割。

包含源点和汇点的两个子集,对应于图像中的两个分区; 边的权重,对应于图像中两个像素之间的相似性。

对于给定的全无向图 G=(V,E)G=(V,E)G=(V,E),图的切割将节点 V 分为两个子集 A、B:A∪B=VA \cup B= VAB=VA∩B=ϕA \cap B= \phiAB=ϕ

连接边的权重 w(i,j)w(i,j)w(i,j) 是节点 i,ji, ji,j 之间相似性的函数:
w(i,j)=1/(∣I(ni)−I(nj)∣+η)w(i,j)=1 / \big( |I(n_i) - I(n_j)| +\eta \big) w(i,j)=1/(I(ni)I(nj)+η)

最小割定义为割集的边的最小总权重:

cut(A,B)=∑u∈A,v∈Bw(u,v)cut(A,B) = \sum_{u \in A, v \in B} w(u,v) cut(A,B)=uA,vBw(u,v)

一种改进方法,使用归一化切割(Ncut)的测度定义:

Ncut(A,B)=cut(A,B)assoc(A,V)+cut(A,B)assoc(B,V)Nassoc(A,B)=assoc(A,A)assoc(A,V)+assoc(B,B)assoc(B,V)assoc(A,V)=∑u∈A,z∈Vw(u,z)assoc(B,V)=∑v∈B,z∈Vw(v,z)\begin{aligned} Ncut(A,B) &= \frac{cut(A,B)}{assoc(A,V)} + \frac{cut(A,B)}{assoc(B,V)} \\ Nassoc(A,B) &= \frac{assoc(A,A)}{assoc(A,V)} + \frac{assoc(B,B)}{assoc(B,V)} \\ assoc(A,V) &= \sum_{u \in A, z \in V} w(u,z) \\ assoc(B,V) &= \sum_{v \in B, z \in V} w(v,z) \end{aligned} Ncut(A,B)Nassoc(A,B)assoc(A,V)assoc(B,V)=assoc(A,V)cut(A,B)+assoc(B,V)cut(A,B)=assoc(A,V)assoc(A,A)+assoc(B,V)assoc(B,B)=uA,zVw(u,z)=vB,zVw(v,z)

另一种常用的方法,使用基于区域分布直方图和边界形状的能量函数 E(L):

E(L)=αR(L)+B(L)E(L) = \alpha R(L) + B(L) E(L)=αR(L)+B(L)

其中,R(L) 是区域分布项(regional term),B(L) 是边界项(boundary term),E(L) 是能量函数。图割的目标是最小化能量函数。

图割分割算法(Graph Cut)运用最小割最大流算法进行图像的分割,将图像分割为前景和背景。

GraphCut 算法需要用户在前景和背景处各画几笔作为输入,由此建立各个像素点与前景背景相似度的赋权图,并通过求解最小割进行图像的前景和背景分割。


例程 11.34: 图割分割算法 Graph Cuts

# 11.34 GraphCuts 交互式图割分割算法 
'''
说明:(1) 用鼠标左键标记前景,鼠标右键标记背景;(2) 可以重复标记,不断优化;(3) 按 Esc 键退出,完成分割。
'''# Copyright 2022 Youcans, XUPT
# Crated:2021-12-27import cv2
import numpy as np
from matplotlib import pyplot as pltdrawing = False
mode = Falseclass GraphCutXupt:def __init__(self, t_img):self.img = t_imgself.img_raw = img.copy()self.img_width = img.shape[0]self.img_height = img.shape[1]self.scale_size = 640 * self.img_width // self.img_heightif self.img_width > 640:self.img = cv2.resize(self.img, (640, self.scale_size), interpolation=cv2.INTER_AREA)self.img_show = self.img.copy()self.img_gc = self.img.copy()self.img_gc = cv2.GaussianBlur(self.img_gc, (3, 3), 0)self.lb_up = Falseself.rb_up = Falseself.lb_down = Falseself.rb_down = Falseself.mask = np.full(self.img.shape[:2], 2, dtype=np.uint8)self.firt_choose = True# 鼠标的回调函数
def mouse_event2(event, x, y, flags, param):global drawing, last_point, start_point# 左键按下:开始画图if event == cv2.EVENT_LBUTTONDOWN:drawing = Truelast_point = (x, y)start_point = last_pointparam.lb_down = Trueprint('mouse lb down')elif event == cv2.EVENT_RBUTTONDOWN:drawing = Truelast_point = (x, y)start_point = last_pointparam.rb_down = Trueprint('mouse rb down')# 鼠标移动,画图elif event == cv2.EVENT_MOUSEMOVE:if drawing:if param.lb_down:cv2.line(param.img_show, last_point, (x, y), (0, 0, 255), 2, -1)cv2.rectangle(param.mask, last_point, (x, y), 1, -1, 4)else:cv2.line(param.img_show, last_point, (x, y), (255, 0, 0), 2, -1)cv2.rectangle(param.mask, last_point, (x, y), 0, -1, 4)last_point = (x, y)# 左键释放:结束画图elif event == cv2.EVENT_LBUTTONUP:drawing = Falseparam.lb_up = Trueparam.lb_down = Falsecv2.line(param.img_show, last_point, (x, y), (0, 0, 255), 2, -1)if param.firt_choose:param.firt_choose = Falsecv2.rectangle(param.mask, last_point, (x, y), 1, -1, 4)print('mouse lb up')elif event == cv2.EVENT_RBUTTONUP:drawing = Falseparam.rb_up = Trueparam.rb_down = Falsecv2.line(param.img_show, last_point, (x, y), (255, 0, 0), 2, -1)if param.firt_choose:param.firt_choose = Falseparam.mask = np.full(param.img.shape[:2], 3, dtype=np.uint8)cv2.rectangle(param.mask, last_point, (x, y), 0, -1, 4)print('mouse rb up')if __name__ == '__main__':img = cv2.imread("../images/imgDeer.png", flags=1)  # 读取彩色图像(Youcans)g_img = GraphCutXupt(img)cv2.namedWindow('image')# 定义鼠标的回调函数cv2.setMouseCallback('image', mouse_event2, g_img)while (True):cv2.imshow('image', g_img.img_show)if g_img.lb_up or g_img.rb_up:g_img.lb_up = Falseg_img.rb_up = FalsebgdModel = np.zeros((1, 65), np.float64)fgdModel = np.zeros((1, 65), np.float64)rect = (1, 1, g_img.img.shape[1], g_img.img.shape[0])print(g_img.mask)mask = g_img.maskg_img.img_gc = g_img.img.copy()cv2.grabCut(g_img.img_gc, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_MASK)mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')  # 0和2做背景g_img.img_gc = g_img.img_gc * mask2[:, :, np.newaxis]  # 使用蒙板来获取前景区域cv2.imshow('youcans', g_img.img_gc)# 按下ESC键退出if cv2.waitKey(20) == 27:breakplt.figure(figsize=(10, 7))plt.subplot(221), plt.axis('off'), plt.title("xupt")plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 显示 img(RGB)plt.subplot(222), plt.axis('off'), plt.title("mask")plt.imshow(mask, 'gray')plt.subplot(223), plt.axis('off'), plt.title("mask2")plt.imshow(mask2, 'gray')plt.subplot(224), plt.axis('off'), plt.title("Grab Cut")plt.imshow(cv2.cvtColor(g_img.img_gc, cv2.COLOR_BGR2RGB))plt.tight_layout()plt.show()

在这里插入图片描述


(本节完)


版权声明:

OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124723416)

Copyright 2022 youcans, XUPT
Crated:2022-5-10


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法
【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法
【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

element 搜索匹配_分享一个element-ui级联选择器的搜索问题,顺便问下有没有解决方案。...

楼主做的是一个三级联动的城市筛选,后台给过来的数据并不全是按照label, value, children的key给到我,数据格式但是官方的props只能指到一级,具体指到2-3级我还不没弄明白。于是 , 需要自己转换:options"options"v-mode…

【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)

【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法 【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法 【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景) 【youcans 的 OpenCV 例程200篇】179.图像分割…

点击出现小心心

使用鼠标的点击事件,使用鼠标点击任意地方的时候,点击的地方会出现一个小心,每一次出现的小心的颜色都不一样。 原理分析 1.设置点击的范围 2.鼠标点击事件 3.记录鼠标点击的位置在此位置出现一颗小心 4.小心向上浮动并且自动消失 5.小心颜色…

【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)

【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法 【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法 【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景) 【youcans 的 OpenCV 例程200篇】179.图像分割…

VScode 透明背景设置

我们通常使用VScode开发项目,时间长了不免有些疲惫,在此教给大家一个设置VScode 透明背景的方法,给大家的代码之旅带来一点乐趣。 1.首先在vscode扩展中,找到并下载background这个插件,快捷键Ctrlshiftx 2.完成第一步…

【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

IDEA设置主题和背景图片

我们使用IDEA开发的时候长期使用一种主题会感到沉重,那麽我们如何为IDEA设置我们自己想要的背景图片呢??? 一 . 设置主题 Idea主题自带的有三种:1、黑色模式 2、Intellij模式 3、高对比度模式; 具体修改步…

【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

java concurrent int_java.util.concurrent.AtomicInteger

AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,i和i操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。来看AtomicInteger提供的接口。//…

IDEA创建SpringBoot

对于SpringBoot的开发我们使用IDEA工具是非常方便的,不仅开发效率高,而且代码能自动添加补全,那麽我们如何使用IDEA创建SpringBoot项目呢??? 1.使用IntelliJ IDEA 内置的Spring Initializr来创建SpringBoo…

【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

procyon java8_java jdk 8反编译工具JD-GUI、procyon-decompiler、luyten、crf下载使用简介

本文对常用的反编译工具进行简单介绍JD-GUI、procyon-decompiler、luyten、crf反编译工具分类JD-GUIJDK7以及之前可以使用 JD-GUI,如果版本>1.8 各种问题http://java-decompiler.github.ioprocyon-decompiler如果版本>1.8 ,可以使用 procyon-dec…

SpringBoot页面出现 Whitelabel Error Page

我们运行SpringBoot项目之后需要通过Tomcat进行访问,但是我们访问的时候出现了Whitelabel Error Page的错误,我们该如何解决呢??? 错误页面 究其原因是我们的主程序缺少一个RestController的注解。 没有使用RestCon…

SpringBoot入门小案例

使用SpringBoot项目输出一个hello SpringBoot的入门小项目。 1.再IDEA中创建SpringBoot项目,创建完成如下所示。 2.项目创建完后打开包结构,WebApplication是项目的入口,是启动类,SpringBootApplication,这个注解非常…

【youcans 的 OpenCV 例程200篇】183.基于轮廓标记的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

【youcans 的 OpenCV 例程200篇】184.鼠标交互标记的分水岭算法

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】180.基于距离变换的分水岭算法 【youcans 的 OpenCV 例程200篇】181.基于 Sobel 梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】182.基于形态学梯度的分水岭算法 【youcans 的 OpenCV 例程200篇】183.基…

【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】185.图像金字塔之高斯金字塔 6. 图像金字塔 图像金字塔是一种以多分辨率来解释图像的结构,常用于图像分割、图像压缩和机器视觉。 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列…

【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】186.图像金字塔之拉普拉斯金字塔 图像金字塔是一种以多分辨率来解释图像的结构,常用于图像分割、图像压缩和机器视觉。 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步…

【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像

OpenCV 例程200篇 总目录-202205更新 【youcans 的 OpenCV 例程200篇】187.由拉普拉斯金字塔还原图像 图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。从底层图像可以看清更多细节,从顶层图像可以看到更多的轮廓特征。通常&…

整型和浮点型之间的转化

在Java中,我们如何将整型转化为浮点型,或者我们如何将浮点型转化成整型的呢? 结果演示 代码演示 package com.ten;public class Zidongzh {public static void main(String[] args) {double a 127.0;float b(float)a;float c(float)b;int…