详解Python实现图像分割增强的两种方法

方法一

import random
import numpy as np
from PIL import Image, ImageOps, ImageFilter
from skimage.filters import gaussian
import torch
import math
import numbers
import random

class RandomVerticalFlip(object):
    def __call__(self, img):
        if random.random() < 0.5:
            return img.transpose(Image.FLIP_TOP_BOTTOM)
        return img

class DeNormalize(object):
    def __init__(self, mean, std):
        self.mean = mean
        self.std = std

    def __call__(self, tensor):
        for t, m, s in zip(tensor, self.mean, self.std):
            t.mul_(s).add_(m)
        return tensor

class MaskToTensor(object):
    def __call__(self, img):
        return torch.from_numpy(np.array(img, dtype=np.int32)).long()

class FreeScale(object):
    def __init__(self, size, interpolation=Image.BILINEAR):
        self.size = tuple(reversed(size))  # size: (h, w)
        self.interpolation = interpolation

    def __call__(self, img):
        return img.resize(self.size, self.interpolation)

class FlipChannels(object):
    def __call__(self, img):
        img = np.array(img)[:, :, ::-1]
        return Image.fromarray(img.astype(np.uint8))

class RandomGaussianBlur(object):
    def __call__(self, img):
        sigma = 0.15 + random.random() * 1.15
        blurred_img = gaussian(np.array(img), sigma=sigma, multichannel=True)
        blurred_img *= 255
        return Image.fromarray(blurred_img.astype(np.uint8))
# 组合
class Compose(object):
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, img, mask):
        assert img.size == mask.size
        for t in self.transforms:
            img, mask = t(img, mask)
        return img, mask
# 随机裁剪
class RandomCrop(object):
    def __init__(self, size, padding=0):
        if isinstance(size, numbers.Number):
            self.size = (int(size), int(size))
        else:
            self.size = size
        self.padding = padding

    def __call__(self, img, mask):
        if self.padding > 0:
            img = ImageOps.expand(img, border=self.padding, fill=0)
            mask = ImageOps.expand(mask, border=self.padding, fill=0)

        assert img.size == mask.size
        w, h = img.size
        th, tw = self.size
        if w == tw and h == th:
            return img, mask
        if w < tw or h < th:
            return img.resize((tw, th), Image.BILINEAR), mask.resize((tw, th), Image.NEAREST)

        x1 = random.randint(0, w - tw)
        y1 = random.randint(0, h - th)
        return img.crop((x1, y1, x1 + tw, y1 + th)), mask.crop((x1, y1, x1 + tw, y1 + th))

#  中心裁剪
class CenterCrop(object):
    def __init__(self, size):
        if isinstance(size, numbers.Number):
            self.size = (int(size), int(size))
        else:
            self.size = size

    def __call__(self, img, mask):
        assert img.size == mask.size
        w, h = img.size
        th, tw = self.size
        x1 = int(round((w - tw) / 2.))
        y1 = int(round((h - th) / 2.))
        return img.crop((x1, y1, x1 + tw, y1 + th)), mask.crop((x1, y1, x1 + tw, y1 + th))

class RandomHorizontallyFlip(object):
    def __call__(self, img, mask):
        if random.random() < 0.5:
            return img.transpose(Image.FLIP_LEFT_RIGHT), mask.transpose(Image.FLIP_LEFT_RIGHT)
        return img, mask

class Scale(object):
    def __init__(self, size):
        self.size = size

    def __call__(self, img, mask):
        assert img.size == mask.size
        w, h = img.size
        if (w >= h and w == self.size) or (h >= w and h == self.size):
            return img, mask
        if w > h:
            ow = self.size
            oh = int(self.size * h / w)
            return img.resize((ow, oh), Image.BILINEAR), mask.resize((ow, oh), Image.NEAREST)
        else:
            oh = self.size
            ow = int(self.size * w / h)
            return img.resize((ow, oh), Image.BILINEAR), mask.resize((ow, oh), Image.NEAREST)

class RandomSizedCrop(object):
    def __init__(self, size):
        self.size = size

    def __call__(self, img, mask):
        assert img.size == mask.size
        for attempt in range(10):
            area = img.size[0] * img.size[1]
            target_area = random.uniform(0.45, 1.0) * area
            aspect_ratio = random.uniform(0.5, 2)

            w = int(round(math.sqrt(target_area * aspect_ratio)))
            h = int(round(math.sqrt(target_area / aspect_ratio)))

            if random.random() < 0.5:
                w, h = h, w

            if w <= img.size[0] and h <= img.size[1]:
                x1 = random.randint(0, img.size[0] - w)
                y1 = random.randint(0, img.size[1] - h)

                img = img.crop((x1, y1, x1 + w, y1 + h))
                mask = mask.crop((x1, y1, x1 + w, y1 + h))
                assert (img.size == (w, h))

                return img.resize((self.size, self.size), Image.BILINEAR), mask.resize((self.size, self.size),
                                                                                       Image.NEAREST)

        # Fallback
        scale = Scale(self.size)
        crop = CenterCrop(self.size)
        return crop(*scale(img, mask))

class RandomRotate(object):
    def __init__(self, degree):
        self.degree = degree

    def __call__(self, img, mask):
        rotate_degree = random.random() * 2 * self.degree - self.degree
        return img.rotate(rotate_degree, Image.BILINEAR), mask.rotate(rotate_degree, Image.NEAREST)

class RandomSized(object):
    def __init__(self, size):
        self.size = size
        self.scale = Scale(self.size)
        self.crop = RandomCrop(self.size)

    def __call__(self, img, mask):
        assert img.size == mask.size

        w = int(random.uniform(0.5, 2) * img.size[0])
        h = int(random.uniform(0.5, 2) * img.size[1])

        img, mask = img.resize((w, h), Image.BILINEAR), mask.resize((w, h), Image.NEAREST)

        return self.crop(*self.scale(img, mask))

class SlidingCropOld(object):
    def __init__(self, crop_size, stride_rate, ignore_label):
        self.crop_size = crop_size
        self.stride_rate = stride_rate
        self.ignore_label = ignore_label

    def _pad(self, img, mask):
        h, w = img.shape[: 2]
        pad_h = max(self.crop_size - h, 0)
        pad_w = max(self.crop_size - w, 0)
        img = np.pad(img, ((0, pad_h), (0, pad_w), (0, 0)), 'constant')
        mask = np.pad(mask, ((0, pad_h), (0, pad_w)), 'constant', constant_values=self.ignore_label)
        return img, mask

    def __call__(self, img, mask):
        assert img.size == mask.size

        w, h = img.size
        long_size = max(h, w)

        img = np.array(img)
        mask = np.array(mask)

        if long_size > self.crop_size:
            stride = int(math.ceil(self.crop_size * self.stride_rate))
            h_step_num = int(math.ceil((h - self.crop_size) / float(stride))) + 1
            w_step_num = int(math.ceil((w - self.crop_size) / float(stride))) + 1
            img_sublist, mask_sublist = [], []
            for yy in range(h_step_num):
                for xx in range(w_step_num):
                    sy, sx = yy * stride, xx * stride
                    ey, ex = sy + self.crop_size, sx + self.crop_size
                    img_sub = img[sy: ey, sx: ex, :]
                    mask_sub = mask[sy: ey, sx: ex]
                    img_sub, mask_sub = self._pad(img_sub, mask_sub)
                    img_sublist.append(Image.fromarray(img_sub.astype(np.uint8)).convert('RGB'))
                    mask_sublist.append(Image.fromarray(mask_sub.astype(np.uint8)).convert('P'))
            return img_sublist, mask_sublist
        else:
            img, mask = self._pad(img, mask)
            img = Image.fromarray(img.astype(np.uint8)).convert('RGB')
            mask = Image.fromarray(mask.astype(np.uint8)).convert('P')
            return img, mask

class SlidingCrop(object):
    def __init__(self, crop_size, stride_rate, ignore_label):
        self.crop_size = crop_size
        self.stride_rate = stride_rate
        self.ignore_label = ignore_label

    def _pad(self, img, mask):
        h, w = img.shape[: 2]
        pad_h = max(self.crop_size - h, 0)
        pad_w = max(self.crop_size - w, 0)
        img = np.pad(img, ((0, pad_h), (0, pad_w), (0, 0)), 'constant')
        mask = np.pad(mask, ((0, pad_h), (0, pad_w)), 'constant', constant_values=self.ignore_label)
        return img, mask, h, w

    def __call__(self, img, mask):
        assert img.size == mask.size

        w, h = img.size
        long_size = max(h, w)

        img = np.array(img)
        mask = np.array(mask)

        if long_size > self.crop_size:
            stride = int(math.ceil(self.crop_size * self.stride_rate))
            h_step_num = int(math.ceil((h - self.crop_size) / float(stride))) + 1
            w_step_num = int(math.ceil((w - self.crop_size) / float(stride))) + 1
            img_slices, mask_slices, slices_info = [], [], []
            for yy in range(h_step_num):
                for xx in range(w_step_num):
                    sy, sx = yy * stride, xx * stride
                    ey, ex = sy + self.crop_size, sx + self.crop_size
                    img_sub = img[sy: ey, sx: ex, :]
                    mask_sub = mask[sy: ey, sx: ex]
                    img_sub, mask_sub, sub_h, sub_w = self._pad(img_sub, mask_sub)
                    img_slices.append(Image.fromarray(img_sub.astype(np.uint8)).convert('RGB'))
                    mask_slices.append(Image.fromarray(mask_sub.astype(np.uint8)).convert('P'))
                    slices_info.append([sy, ey, sx, ex, sub_h, sub_w])
            return img_slices, mask_slices, slices_info
        else:
            img, mask, sub_h, sub_w = self._pad(img, mask)
            img = Image.fromarray(img.astype(np.uint8)).convert('RGB')
            mask = Image.fromarray(mask.astype(np.uint8)).convert('P')
            return [img], [mask], [[0, sub_h, 0, sub_w, sub_h, sub_w]]

方法二

import numpy as np
import random

import torch
from torchvision import transforms as T
from torchvision.transforms import functional as F

def pad_if_smaller(img, size, fill=0):
    # 如果图像最小边长小于给定size,则用数值fill进行padding
    min_size = min(img.size)
    if min_size < size:
        ow, oh = img.size
        padh = size - oh if oh < size else 0
        padw = size - ow if ow < size else 0
        img = F.pad(img, (0, 0, padw, padh), fill=fill)
    return img

class Compose(object):
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, image, target):
        for t in self.transforms:
            image, target = t(image, target)
        return image, target

class RandomResize(object):
    def __init__(self, min_size, max_size=None):
        self.min_size = min_size
        if max_size is None:
            max_size = min_size
        self.max_size = max_size

    def __call__(self, image, target):
        size = random.randint(self.min_size, self.max_size)
        # 这里size传入的是int类型,所以是将图像的最小边长缩放到size大小
        image = F.resize(image, size)
        # 这里的interpolation注意下,在torchvision(0.9.0)以后才有InterpolationMode.NEAREST
        # 如果是之前的版本需要使用PIL.Image.NEAREST
        target = F.resize(target, size, interpolation=T.InterpolationMode.NEAREST)
        return image, target

class RandomHorizontalFlip(object):
    def __init__(self, flip_prob):
        self.flip_prob = flip_prob

    def __call__(self, image, target):
        if random.random() < self.flip_prob:
            image = F.hflip(image)
            target = F.hflip(target)
        return image, target

class RandomCrop(object):
    def __init__(self, size):
        self.size = size

    def __call__(self, image, target):
        image = pad_if_smaller(image, self.size)
        target = pad_if_smaller(target, self.size, fill=255)
        crop_params = T.RandomCrop.get_params(image, (self.size, self.size))
        image = F.crop(image, *crop_params)
        target = F.crop(target, *crop_params)
        return image, target

class CenterCrop(object):
    def __init__(self, size):
        self.size = size

    def __call__(self, image, target):
        image = F.center_crop(image, self.size)
        target = F.center_crop(target, self.size)
        return image, target

class ToTensor(object):
    def __call__(self, image, target):
        image = F.to_tensor(image)
        target = torch.as_tensor(np.array(target), dtype=torch.int64)
        return image, target

class Normalize(object):
    def __init__(self, mean, std):
        self.mean = mean
        self.std = std

    def __call__(self, image, target):
        image = F.normalize(image, mean=self.mean, std=self.std)
        return image, target

到此这篇关于详解Python实现图像分割增强的两种方法的文章就介绍到这了,更多相关Python图像分割增强内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 通过PYTHON来实现图像分割详解

    程序思路: 此次程序主要是利用PIL(Python Image Libraty)这库,来进行图片的处理. PIL是一个功能非常强大的python图像处理标准库,但由于PIL只支持python2.7.如今很多python程序员都使用python3.x,所以PIL在之前的基础上分离出来一个分支,另外创建一个Pillow库,以便支持python3.x, 本程序在使用之前确保已经安装了Pillow库. 程序首先把你要分隔的图像读取到一个变量中,然后我们定义了一个 fill_image() 方法,用来填充

  • Python基于域相关实现图像增强的方法教程

    目录 介绍 昆虫增强 使用针的增强 实验结果 介绍 当在图像上训练深度神经网络模型时,通过对由数据增强生成的更多图像进行训练,可以使模型更好地泛化.常用的增强包括水平和垂直翻转/移位.以一定角度和方向(顺时针/逆时针)随机旋转.亮度.饱和度.对比度和缩放增强. Python中一个非常流行的图像增强库是albumentations(https://albumentations.ai/),通过直观的函数和优秀的文档,可以轻松地增强图像.它也可以与PyTorch和TensorFlow等流行的深度学习框

  • python 图像增强算法实现详解

    使用python编写了共六种图像增强算法: 1)基于直方图均衡化 2)基于拉普拉斯算子 3)基于对数变换 4)基于伽马变换 5)限制对比度自适应直方图均衡化:CLAHE 6)retinex-SSR 7)retinex-MSR其中,6和7属于同一种下的变化. 将每种方法编写成一个函数,封装,可以直接在主函数中调用. 采用同一幅图进行效果对比. 图像增强的效果为: 直方图均衡化:对比度较低的图像适合使用直方图均衡化方法来增强图像细节 拉普拉斯算子可以增强局部的图像对比度 log对数变换对于整体对比度

  • Python图像分割之均匀性度量法分析

    均匀性度量图像分割是图像像素分割的一种方法,当然还有其他很多的方法.这里简单的介绍下其原理和实现代码[有源码] 其流程大概分为一下几步 1.确定一个阈值 2.计算阈值两边的像素个数.占比.以及方差 3.将两边的方差和占比想乘再相加 4.循环1~3的步骤 下面以这个例子为示例做一个演示 计算公式: 阈值为: 1 阈值左边值为: [1, 1, 0, 0, 0] 均值: 0.08 阈值右边值为: [3, 9, 9, 8, 2, 3, 7, 3, 3, 6, 6, 4, 6, 8, 2, 5, 2, 9

  • Python 深入了解opencv图像分割算法

    使用 OpenCV 函数 cv::filter2D 执行一些拉普拉斯滤波以进行图像锐化 使用 OpenCV 函数 cv::distanceTransform 以获得二值图像的派生(derived)表示,其中每个像素的值被替换为其到最近背景像素的距离 使用 OpenCV 函数 cv::watershed 将图像中的对象与背景隔离 加载源图像并检查它是否加载没有任何问题,然后显示它: # Load the image parser = argparse.ArgumentParser(descript

  • python 基于opencv实现图像增强

    为了得到更加清晰的图像我们需要通过技术对图像进行处理,比如使用对比度增强的方法来处理图像,对比度增强就是对图像输出的灰度级放大到指定的程度,获得图像质量的提升.本文主要通过代码的方式,通过OpenCV的内置函数将图像处理到我们理想的结果. 灰度直方图 灰度直方图通过描述灰度级在图像矩阵中的像素个数来展示图像灰度级的信息,通过灰度直方图的统计我们可以看到每个灰度值的占有率.下面是一个灰度直方图的实现: import cv2 import numpy as np import sys import

  • 详解Python实现图像分割增强的两种方法

    方法一 import random import numpy as np from PIL import Image, ImageOps, ImageFilter from skimage.filters import gaussian import torch import math import numbers import random class RandomVerticalFlip(object): def __call__(self, img): if random.random()

  • 详解Python实现字典合并的四种方法

    目录 1.用for循环把一个字典合并到另一个字典 2.用dict(b, **a)方法构造一个新字典 3.用b.update(a)的方法,更新字典 4.把字典转换成列表合并后,再转换成字典 (1)利用a.items().b.items()把a.b两个字典转换成元组键值对列表 (2)合并列表并且把合并后的列表转换成字典 5.实例,netmiko使用json格式的数据进行自动化操作 (1)json格式的处理 (2)json格式的设备信息列表 (3)netmiko读取json类型信息示例 1.用for循

  • 详解Git建立本地仓库的两种方法

    Git是一种分布式版本控制系统,通常这类系统都可以与若干远端代码进行交互.Git项目具有三个主要部分:工作区,暂存目录,暂存区,本地目录: 安装完Git后,要做的第一件事,就是设置用户名和邮件地址.每个Git提交都使用此信息,并且将它永久地烘焙到您开始创建的提交中: $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com 之后我们可以建立一个本地仓库.

  • 详解vue-cli中模拟数据的两种方法

    在main.js中引入vue-resource模块,Vue.use(vueResource). 1.使用json-server(不能用post请求) 接下来找到build目录下的webpack.dev.conf.js文件,在const portfinder = require('portfinder')后面引入json-server. /*引入json-server*/ const jsonServer = require('json-server') /*搭建一个server*/ const

  • 详解Eclipse安装SVN插件的两种方法

    eclipse里安装SVN插件,一般来说,有两种方式: 直接下载SVN插件,将其解压到eclipse的对应目录里 使用eclipse 里Help菜单的"Install New Software",通过输入SVN地址,直接下载安装到eclipse里 第一种方式: 1.下载SVN插件 SVN插件下载地址及更新地址,你根据需要选择你需要的版本.现在最新是1.8.x Links for 1.8.x Release: Eclipse update site URL: http://subclip

  • 详解react-router4 异步加载路由两种方法

    方法一:我们要借助bundle-loader来实现按需加载. 首先,新建一个bundle.js文件: import React, { Component } from 'react' export default class Bundle extends React.Component { state = { // short for "module" but that's a keyword in js, so "mod" mod: null } componen

  • 详解Python OpenCV图像分割算法的实现

    目录 前言 1.图像二值化 2.自适应阈值分割算法 3.Otsu阈值分割算法 4.基于轮廓的字符分离 4.1轮廓检测 4.2轮廓绘制 4.3包围框获取 4.4矩形绘制 前言 图像分割是指根据灰度.色彩.空间纹理.几何形状等特征把图像划分成若干个互不相交的区域. 最简单的图像分割就是将物体从背景中分割出来 1.图像二值化 cv2.threshold是opencv-python中的图像二值化方法,可以实现简单的分割功能. retval, dst = cv2.threshold(src, thresh

  • Python获取网络时间戳的两种方法详解

    目录 方法一 代码实现 调用方法 返回结果 方法二 代码实现 调用方法 返回结果 在我们进行注册码的有效期验证时,通常使用获取网络时间的方式来进行比对. 以下为获取网络时间的几种方式. 方法一 需要的时间会比较长,个别电脑上可能会出现不兼容现象 代码实现 def get_web_server_time(self, host_URL, year_str='-', time_str=':'): ''' 获取网络时间,需要的时间会比较长,个别电脑上可能会出现不兼容现象 :param host_URL:

  • 详解Python中list[::-1]的几种用法

    本文主要介绍了Python中list[::-1]的几种用法,分享给大家,具体如下: s = "abcde" list的[]中有三个参数,用冒号分割 list[param1:param2:param3] param1,相当于start_index,可以为空,默认是0 param2,相当于end_index,可以为空,默认是list.size param3,步长,默认为1.步长为-1时,返回倒序原序列 举例说明 param1 = -1,只有一个参数,作用是通过下标访问数据,-1为倒数第一个

  • 一文详解Python中实现单例模式的几种常见方式

    目录 Python 中实现单例模式的几种常见方式 元类(Metaclass): 装饰器(Decorator): 模块(Module): new 方法: Python 中实现单例模式的几种常见方式 元类(Metaclass): class SingletonType(type): """ 单例元类.用于将普通类转换为单例类. """ _instances = {} # 存储单例实例的字典 def __call__(cls, *args, **kwa

随机推荐