【OpenCV图像处理14】图像分割与修复(上)

简介: 【OpenCV图像处理14】图像分割与修复(上)

十四、图像分割与修复

1、图像分割

图像分割: 将前景物体从背景中分离出来。

图像分割的方法:

  • 传统的图像分割方法
  • 分水岭法
  • GrabCut法
  • MeanShift法
  • 背景抠图
  • 基于深度学习的图像分割方法

1.1 分水岭

1、分水岭法的原理:

2、分水岭法的问题:

图像存在过多的极小区域,从而产生许多小的集水盆。

3、分水岭法的基本步骤:

  • 标记背景
  • 标记前景
  • 标记未知域
  • 进行分割

4、实战:分割硬币

watershed()用法:

cv2.watershed(image, markers)

参数说明:

  • markers:前景、背景设置不同的值用以区分它们

原图像:

获取背景:

获取前景:

获取未知域:

4.1 获取背景:

# 获取背景
# 1.通过二值法得到黑白图像
# 2.通过形态学获取背景
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)
cv2.imshow('thresh', thresh)
cv2.imshow('bg', bg)

4.2 获取前景:

距离变换:distanceTransform()用法

cv2.distanceTransform(src, distanceType, maskSize, dst: None, dstType: None)

参数说明:

  • distanceType:DIST_L1(绝对值),DIST_L2(勾股定理)
  • maskSize:L1:3,L2:5
# 获取前景
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5)
ret, fg = cv2.threshold(dist, 0.7*dist.max(), 255, cv2.THRESH_BINARY)
# plt.imshow(dist, cmap='gray')
# plt.show()
# exit()
cv2.imshow('dist', dist)
cv2.imshow('fg', fg)

使用Matplotlib画出dist:

4.3 获取未知域:

求连通域:connectedComponents()用法

cv2.connectedComponents(image, labels: None, connectivity: None, ltype: None)

参数说明:

  • connectivity:4,8(默认)
# 获取未知域
fg = np.uint8(fg)
unknown = cv2.subtract(bg, fg)
# 创建连通域
ret, marker = cv2.connectedComponents(fg)
cv2.imshow('unknown', unknown)

4.4 进行分割:

# 进行分割
result = cv2.watershed(img, marker)
img[result == -1] = [0, 0, 255]
cv2.imshow('img', img)

代码实现(完整代码):

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('../resource/money.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 获取背景
# 1.通过二值法得到黑白图像
# 2.通过形态学获取背景
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)
# 获取前景
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5)
ret, fg = cv2.threshold(dist, 0.7 * dist.max(), 255, cv2.THRESH_BINARY)
# plt.imshow(dist, cmap='gray')
# plt.show()
# exit()
# 获取未知域
fg = np.uint8(fg)
unknown = cv2.subtract(bg, fg)
# 创建连通域
ret, marker = cv2.connectedComponents(fg)
marker += 1
marker[unknown == 255] = 0
# 进行分割
result = cv2.watershed(img, marker)
img[result == -1] = [0, 0, 255]
# cv2.imshow('thresh', thresh)
# cv2.imshow('bg', bg)
# cv2.imshow('dist', dist)
# cv2.imshow('fg', fg)
# cv2.imshow('unknown', unknown)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.2 GrabCut

GrabCut:通过交互的方式获得前景物体。

基本原理:

(1):用户可以指定前景的大体区域,剩下的为背景区域。

(2):用户还可以明确指定某些地方为前景或背景。

(3):GrabCut采用分段迭代的方法分析前景物体形成模型树。

(3):最后根据权重决定某个像素是前景还是背景。

实战步骤:

(1):主体结构

(2):鼠标事件的处理

(3):调用GrabCut实现图像分割

1、主体结构:

class App:
    def onmouse(self, event, x, y, flags, param):
        print('onmouse')
    def run(self):
        print('run')
        cv2.namedWindow('input')
        cv2.setMouseCallback('input', self.onmouse)
        img = cv2.imread('../resource/lena.bmp')
        cv2.imshow('input', img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
App().run()

2、鼠标事件的处理

class App:
    flag_rect = False
    startX = 0
    startY = 0
    def onmouse(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.flag_rect = True
            self.startX = x
            self.startY = y
            print('LBUTTONDOWN: 左键按下')
        elif event == cv2.EVENT_LBUTTONUP:
            self.flag_rect = False
            cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (0, 0, 255), 3)
            print('LBUTTONUP: 左键抬起')
        elif event == cv2.EVENT_MOUSEMOVE:
            if self.flag_rect == True:
                self.img = self.img2.copy()
                cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (0, 255, 0), 3)
            print('MOUSEMOVE: 鼠标移动')
        print('onmouse')
    def run(self):
        print('run')
        cv2.namedWindow('input')
        cv2.setMouseCallback('input', self.onmouse)
        self.img = cv2.imread('../resource/lena.bmp')
        self.img2 = self.img.copy()
        while (1):
            cv2.imshow('input', self.img)
            key = cv2.waitKey(100)
            if key == 27:
                break
App().run()

目录
相关文章
|
28天前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
基于qt的opencv实时图像处理框架FastCvLearn实战
|
19天前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
44 2
|
2月前
|
计算机视觉 C++
基于VS2019和Opencv4,对hsv颜色空间的图像分割原理以及实现
这篇文章介绍了基于HSV颜色空间的图像分割原理,包括HSV模型的基本概念和如何在OpenCV中通过设置HSV的色彩范围来实现图像中特定颜色的物体分割,并通过示例代码展示了在静态图像和视频流中进行颜色分割的方法。
基于VS2019和Opencv4,对hsv颜色空间的图像分割原理以及实现
WK
|
2月前
|
计算机视觉 Python
如何使用OpenCV进行基本图像处理
使用OpenCV进行基本图像处理包括安装OpenCV,读取与显示图像,转换图像颜色空间(如从BGR到RGB),调整图像大小,裁剪特定区域,旋转图像,以及应用图像滤镜如高斯模糊等效果。这些基础操作是进行更复杂图像处理任务的前提。OpenCV还支持特征检测、图像分割及对象识别等高级功能。
WK
39 4
|
5月前
|
人工智能 计算机视觉 Python
【OpenCV】计算机视觉图像处理基础知识(上)
【OpenCV】计算机视觉图像处理基础知识(上)
|
5月前
|
算法 计算机视觉
【OpenCV】计算机视觉图像处理基础知识(下)
【OpenCV】计算机视觉图像处理基础知识(下)
|
5月前
|
算法 安全 机器人
最新版opencv4.9安装介绍,基本图像处理详解
最新版opencv4.9安装介绍,基本图像处理详解
269 0
|
5月前
|
机器学习/深度学习 存储 算法
OpenCV与NumPy:图像处理中的黄金组合
【4月更文挑战第17天】OpenCV和NumPy是Python图像处理的两大利器,互补协作形成黄金组合。OpenCV专注计算机视觉,提供丰富算法,而NumPy擅长数值计算和数组操作。两者无缝对接,共同实现高效、灵活的图像处理任务。通过灰度化、二值化、边缘检测等案例,展示了它们的协同作用。未来,这一组合将在计算机视觉和机器学习领域发挥更大作用,解锁更多图像处理潜力。
|
11天前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
107 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
1月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
39 4