图像语义分割——python滑窗法裁剪数据

B站:xxx
CSDN:python图像分割——滑窗法裁剪数据_百年后封笔-CSDN博客
Github:封笔
公众号:百年后封笔

一、 背景和需求

对图像分割而言,往往给的原图是非常大的,无法直接用于网络训练,因此有必要使用滑窗法进行图像的裁剪,把大图裁剪成一个个小的patch图,如下所示,当然如果有分类的需求,也可以根据要求来把裁剪的图像进行分类。

在这里插入图片描述

下面给出一个例子:

目标:把一个二分类(不包含背景)的细胞分割图(label标注为红色和绿色),使用滑窗法进行分割,并根据patch中两种类别的占比来进行分类保存。
注:不考虑超出像素边界的残缺patch,如需考虑可以用cv2的 copyMakeBorder解决

二、实现

2.1 代码实现

直接上代码:

import os
import cv2
import numpy as np
from tqdm import tqdm

# 根据传统视觉进行图像两类标签的mask生成(原始标签是彩色图像,需要提取绿色和红色的部分)
def get_g_r_label(label):
    b, g, r = label[..., 0], label[..., 1], label[..., 2]
    b = b.astype(np.float)
    g = g.astype(np.float)
    r = r.astype(np.float)
    green = g - b - r
    red = r - b - g

    red = np.where(red > 0, 255, 0)
    green = np.where(green > 0, 255, 0)
    #
    # cv2.imshow('label', label.astype(np.uint8))
    # cv2.imshow('green', green.astype(np.uint8))
    # cv2.imshow('red', red.astype(np.uint8))
    # cv2.waitKey(0)

    return red.astype(np.uint8), green.astype(np.uint8)

# 裁剪函数
def crop(img, label, label_g, label_r, save_dirs, save_name,
         crop_size=(50, 50), gap=(50, 50), ratio=0.7, isshow=False):
    h, w, _ = img.shape
    gp_w, gp_h = gap
    cp_w, cp_h = crop_size
    num = 0
    for j in range(0, h, gp_h):
        if j + cp_h > h: continue
        for i in range(0, w, gp_w):
            if i + cp_w > w: continue
            # print(j, i, j*gap_h, j*gap_h+cp_h, i*gap_w, i*gp_w+cp_w)
            cp_img = img[j:j+cp_h, i:i+cp_w, :]
            a_img = label_r[j:j+cp_h, i:i+cp_w]
            b_img = label_g[j:j+cp_h, i:i+cp_w]
            if np.sum(a_img.flatten()) > cp_w * cp_h * 255 * ratio:
                cv2.imwrite(os.path.join(save_dirs[0], save_name.replace('.jpg', f'_{num}.jpg')), cp_img)
                if isshow:
                    cv2.imwrite(os.path.join(save_dirs[0], save_name.replace('.jpg', f'_{num}_show.jpg')), label[j:j+cp_h, i:i+cp_w, :])

            elif np.sum(b_img.flatten()) > cp_w * cp_h * 255 * ratio:
                cv2.imwrite(os.path.join(save_dirs[1], save_name.replace('.jpg', f'_{num}.jpg')), cp_img)
                if isshow:
                    cv2.imwrite(os.path.join(save_dirs[1], save_name.replace('.jpg', f'_{num}_show.jpg')), label[j:j+cp_h, i:i+cp_w, :])

            num += 1

            # cv2.imshow('cp', cp_img)
            # cv2.imshow('ori', img)
            # cv2.imshow('a', a_img)
            # cv2.imshow('b', b_img)
            # cv2.waitKey(0)


if __name__ == '__main__':
    label_dir = r'path/to/your_label'
    img_dir = r'path/to/your_images'
    # 定义两个类别的保存路径
    save_dir1 = r'./cls_1'
    save_dir2 = r'./cls_2'
    if not os.path.isdir(save_dir1): os.makedirs(save_dir1)
    if not os.path.isdir(save_dir2): os.makedirs(save_dir2)
    crop_w, crop_h = 100, 100 # 定义裁剪图像尺寸
    gap_w, gap_h = 100, 100 # 定义滑动间隔
    ratio = 0.7 # 像素占比
    for label_name in tqdm(os.listdir(label_dir)):
        img_path = os.path.join(img_dir, label_name.replace('.v2', ''))
        label_path = os.path.join(label_dir, label_name)
        label = cv2.imread(label_path, cv2.IMREAD_COLOR)
        img = cv2.imread(img_path, cv2.IMREAD_COLOR)
        red, green = get_g_r_label(label)  # 获取标签模板
        crop(img, label, red, green, [save_dir1, save_dir2], save_name=label_name.replace('.v2', ''),
             crop_size=(crop_w, crop_h), gap=(gap_w, gap_h), ratio=ratio, isshow=False)






2.2 根据颜色获取不同类别的mask

# 根据传统视觉进行图像两类标签的mask生成(原始标签是彩色图像,需要提取绿色和红色的部分)
def get_g_r_label(label):
    b, g, r = label[..., 0], label[..., 1], label[..., 2]
    b = b.astype(np.float)
    g = g.astype(np.float)
    r = r.astype(np.float)
    green = g - b - r
    red = r - b - g

    red = np.where(red > 0, 255, 0)
    green = np.where(green > 0, 255, 0)
    #
    # cv2.imshow('label', label.astype(np.uint8))
    # cv2.imshow('green', green.astype(np.uint8))
    # cv2.imshow('red', red.astype(np.uint8))
    # cv2.waitKey(0)

    return red.astype(np.uint8), green.astype(np.uint8)

在这里插入图片描述

2.3 滑窗法裁剪 crop

# 裁剪函数
def crop(img, label, label_g, label_r, save_dirs, save_name,
         crop_size=(50, 50), gap=(50, 50), ratio=0.7, isshow=False):
    h, w, _ = img.shape
    gp_w, gp_h = gap
    cp_w, cp_h = crop_size
    num = 0
    for j in range(0, h, gp_h):
        if j + cp_h > h: continue
        for i in range(0, w, gp_w):
            if i + cp_w > w: continue
            # print(j, i, j*gap_h, j*gap_h+cp_h, i*gap_w, i*gp_w+cp_w)
            cp_img = img[j:j+cp_h, i:i+cp_w, :]
            a_img = label_r[j:j+cp_h, i:i+cp_w]
            b_img = label_g[j:j+cp_h, i:i+cp_w]
            if np.sum(a_img.flatten()) > cp_w * cp_h * 255 * ratio:
                cv2.imwrite(os.path.join(save_dirs[0], save_name.replace('.jpg', f'_{num}.jpg')), cp_img)
                if isshow:
                    cv2.imwrite(os.path.join(save_dirs[0], save_name.replace('.jpg', f'_{num}_show.jpg')), label[j:j+cp_h, i:i+cp_w, :])

            elif np.sum(b_img.flatten()) > cp_w * cp_h * 255 * ratio:
                cv2.imwrite(os.path.join(save_dirs[1], save_name.replace('.jpg', f'_{num}.jpg')), cp_img)
                if isshow:
                    cv2.imwrite(os.path.join(save_dirs[1], save_name.replace('.jpg', f'_{num}_show.jpg')), label[j:j+cp_h, i:i+cp_w, :])

            num += 1

在这里插入图片描述
在这里插入图片描述
如上是分割出来的不同类别的patch图像。

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要在Python中进行图像语义分割,可以使用PixelLib库。PixelLib使用Deeplabv3+框架实现语义分割,并在pascalvoc数据集上训练了Xception模型用于语义分割\[1\]。 首先,需要安装所需的第三方库文件,包括TensorFlow、Pillow、OpenCV-Python、scikit-image和PixelLib\[2\]。可以使用pip命令进行安装。 接下来,导入PixelLib模块,并使用semantic_segmentation类进行语义分割。可以使用以下代码进行导入和语义分割的操作: ``` import pixellib from pixellib.semantic import semantic_segmentation segment_image = semantic_segmentation() segment_image.load_pascalvoc_model("path_to_Xception_model") segment_image.segmentAsPascalvoc("path_to_image", output_image_name="path_to_output_image") ``` 在上述代码中,需要将路径替换为自己的环境路径。首先,使用`load_pascalvoc_model`方法加载预训练的Xception模型。然后,使用`segmentAsPascalvoc`方法对图像进行语义分割,并指定输出图像的路径\[3\]。 这样,你就可以在Python中使用PixelLib库进行图像语义分割了。 #### 引用[.reference_title] - *1* *2* *3* [Python代码实现图像语义分割](https://blog.csdn.net/No1_Lucky_pig/article/details/119571351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百年后封笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值