OpenCV4图像处理-图像交互式分割-GrabCut

简介: 1.理论介绍用户指定前景的大体区域,剩下为背景区域,还可以明确指出某些地方为前景或者背景,GrabCut算法采用分段迭代的方法分析前景物体形成模型树,最后根据权重决定某个像素是前景还是背景。

1.理论介绍

用户指定前景的大体区域,剩下为背景区域,还可以明确指出某些地方为前景或者背景,GrabCut算法采用分段迭代的方法分析前景物体形成模型树,最后根据权重决定某个像素是前景还是背景。


算法:GrabCut(img, mask, rect, bgdModel, fgdModel, 5, //iteratormode)

img:要分割的图像

mask:生称的掩码(以原图像大小为基准),该算法会把mask分为4部分,像素点的值为0,1,2,3四种值吗,其中每种值代表不同的意思。

rect:用户指定的矩形区域,元组的形式(起始坐标x, y , width,height)

bgdModel:1行65列的0矩阵,元素类型为float64。

fgdModel:1行65列的0矩阵,元素类型为float64。

5:迭代次数iterator

mode:第一次找用RECT,以后迭代用MASK

d13562eb30e44aea9403b3420362114d.png


1773353b26c14dffba4294d5d3c05d14.png

2. 鼠标交互

下面是一个鼠标交互的程序,可以通过点击鼠标滑动鼠标在图像上作图。

不太清楚的读者可以参考下面博客:Opencv(图像处理)-基于Python-绘图功能

代码如下:

import cv2
import numpy as np
'''
该api可以在图上作图
点击并滑动鼠标可以在图上画出矩形框
'''
# 定义一个类来封装该方法
class MouseStich:
    startX = 0
    startY = 0
    rect_flag = False
    def onmouse(self, event, x, y, flags, param):
        # print("onmouse")
        if event == cv2.EVENT_LBUTTONDOWN:
            self.rect_flag = True
            self.startX = x
            self.startY = y
            # print("LBUTTONDOWN")
        elif event == cv2.EVENT_LBUTTONUP:
            # print("LBUTTONUP")
            self.rect_flag = False
            cv2.rectangle(self.img,
                          (self.startX, self.startY),
                          (x, y),
                          (0, 0, 255),
                          3)
        elif event == cv2.EVENT_MOUSEMOVE:
            # print("MOUSEMOVE")
            # 每次都在新的图像上画
            if self.rect_flag == True:
                self.img = self.img2.copy()
                cv2.rectangle(self.img,
                              (self.startX, self.startY),
                              (x, y),
                              (0, 255, 0),
                              3)
    def run(self):
        print("run....")
        # 绑定鼠标事件的窗口
        cv2.namedWindow('input')
        cv2.setMouseCallback('input', self.onmouse)
    # 暂存一个img2
        self.img = cv2.imread('./image/lena.jpg')
        self. img2 = self.img.copy()
        # 读取图片,在该窗口显示
        while(1):
            # 展示原图,被画的图
            cv2.imshow('input', self.img)
            k = cv2.waitKey(100) & 0xff
            if k == ord('q'):
                break
MouseStich().run()

3. GrabCut

将GrabCut需要的参数构造好后,传进去,获得mask掩模,然后我们用np.where把像素值是1,3的位置改成255,目的是用bitwise_and函数提取出前景区域。

import cv2
import numpy as np
'''
该api可以在图上作图
点击并滑动鼠标可以在图上画出矩形框
'''
# 定义一个类来封装该方法
class MouseStich:
    startX = 0
    startY = 0
    rect_flag = False
    rect = (0, 0, 0, 0)
    def onmouse(self, event, x, y, flags, param):
        # print("onmouse")
        if event == cv2.EVENT_LBUTTONDOWN:
            self.rect_flag = True
            self.startX = x
            self.startY = y
            # print("LBUTTONDOWN")
        elif event == cv2.EVENT_LBUTTONUP:
            # print("LBUTTONUP")
            self.rect_flag = False
            cv2.rectangle(self.img,
                          (self.startX, self.startY),
                          (x, y),
                          (0, 0, 255),
                          3)
        elif event == cv2.EVENT_MOUSEMOVE:
            # print("MOUSEMOVE")
            # 每次都在新的图像上画
            if self.rect_flag == True:
                # 每次都在新的图像上画move
                self.img = self.img2.copy()
                cv2.rectangle(self.img,
                              (self.startX, self.startY),
                              (x, y),
                              (0, 255, 0),
                              3)
        # 构造矩形的信息
        self.rect = (min(self.startX, x), min(self.startY, y),
                     abs(self.startX - x), abs(self.startY - y))
    def run(self):
        print("run....")
        # 绑定鼠标事件的窗口
        cv2.namedWindow('input')
        cv2.setMouseCallback('input', self.onmouse)
        self.img = cv2.imread('./image/lena.jpg')
        self. img2 = self.img.copy()
        # 定义一个与图片相同大小的掩码
        self.mask = np.zeros(self.img.shape[:2], dtype=np.uint8)
        self.output = np.zeros(self.img.shape, dtype=np.uint8)
        # 读取图片,在该窗口显示
        while(1):
            # 展示原图,被画的图
            cv2.imshow('input', self.img)
            cv2.imshow('output', self.output)
            k = cv2.waitKey(100) & 0xff
            if k == ord('q'):
                break
            if k == ord('g'):
                bgdmodel = np.zeros((1, 65), np.float64)
                fgdmodel = np.zeros((1, 65), np.float64)
                cv2.grabCut(self.img2, self.mask, self.rect,
                            bgdmodel, fgdmodel,
                            1,
                            cv2.GC_INIT_WITH_RECT)
            # 构造提取前景的淹没
            mask2 = np.where((self.mask==1)|(self.mask==3), 255, 0).astype('uint8')
            self.output = cv2.bitwise_and(self.img2, self.img2, mask=mask2)
MouseStich().run()

展示效果:先使用鼠标画出区域,然后按’g’分割图片。


image.png

以上是关于GrabCut算法的实战内容,如有问题欢迎在评论区讨论。

目录
相关文章
|
3月前
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
137 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
2月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
504 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
3月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
53 4
|
3月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
|
2月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
64 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
|
2月前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
89 2
|
4月前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
WK
|
4月前
|
计算机视觉 Python
如何使用OpenCV进行基本图像处理
使用OpenCV进行基本图像处理包括安装OpenCV,读取与显示图像,转换图像颜色空间(如从BGR到RGB),调整图像大小,裁剪特定区域,旋转图像,以及应用图像滤镜如高斯模糊等效果。这些基础操作是进行更复杂图像处理任务的前提。OpenCV还支持特征检测、图像分割及对象识别等高级功能。
WK
53 4
WK
|
4月前
|
编解码 计算机视觉 Python
如何在OpenCV中进行图像转换
在OpenCV中,图像转换涉及颜色空间变换、大小调整及类型转换等操作。常用函数如`cvtColor`可实现BGR到RGB、灰度图或HSV的转换;`resize`则用于调整图像分辨率。此外,通过`astype`或`convertScaleAbs`可改变图像数据类型。对于复杂的几何变换,如仿射或透视变换,则可利用`warpAffine`和`warpPerspective`函数实现。这些技术为图像处理提供了强大的工具。
WK
121 1
|
6月前
|
算法 计算机视觉
【Qt&OpenCV 图像的感兴趣区域ROI】
【Qt&OpenCV 图像的感兴趣区域ROI】
211 1