图像不同的降采样方式(模糊处理)

本文介绍了OpenCV库中用于图像模糊处理的四种算法:平均模糊、高斯模糊、中值模糊和双边模糊,并提及scipy库中的类似方法。模糊处理常用于边沿检测和去噪声。文章提供了一段实验过程中的批处理代码示例,以实现不同采样数据的获取。

模糊处理在边沿检测和去噪声方面有较为广泛的应用。OpenCV中提供了4种模糊算法,列举如下:

  • average
  • median
  • gaussian
  • bilateral

 

而scipy中同样有几种方式,其本质上是没区别的。

我们先来看模糊算法的实现:

 

1.average

    import numpy
    import argparse
    import cv2

    image = cv2.imread('1.jpg')
    cv2.imshow("Original", image)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv2.imshow("Gray", gray)


    #[x,y] is the kernel for bluring
    #the large kernel becomes, the more blurred imag will appear
    #hstack is able to stack multiple images together
    #using simple mean to average
    blurred = numpy.hstack([
    cv2.blur(gray, (3,3)),
    cv2.blur(gray, (5,5)),
    cv2.blur(gray, (7,7))])

    #display two images in a figure
    cv2.imshow("Blurring by average", blurred)

    cv2.imwrite("1_blur_by_average.jpg", blurred)


    if(cv2.waitKey(0)==27):
     cv2.destroyAllWindows()

 

2.

Gaussian

import numpy
    import argparse
    import cv2

    image = cv2.imread('1.jpg')
    cv2.imshow("Original", image)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv2.imshow("Gray", gray)


    #[x,y] is the kernel for bluring
    #the large kernel becomes, the more blurred imag will appear
    #hstack is able to stack multiple images together
    #using weighted mean
    #where neighborhood pixels that are closer to the central pixel contribute more "weight" to the average
    blurred = numpy.hstack([
    cv2.GaussianBlur(gray, (3,3), 0),
    cv2.GaussianBlur(gray, (5,5), 0),
    cv2.GaussianBlur(gray, (7,7), 0)])

    #display two images in a figure
    cv2.imshow("Blurring by Gaussian", blurred)

    cv2.imwrite("1_blur_by_Gaussian.jpg", blurred)


    if(cv2.waitKey(0)==27):
     cv2.destroyAllWindows()


3.

median

  import numpy
    import argparse
    import cv2

    image = cv2.imread('1.jpg')
    cv2.imshow("Original", image)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv2.imshow("Gray", gray)


    #[x,y] is the kernel for bluring
    #the large kernel becomes, the more blurred imag will appear
    #hstack is able to stack multiple images together
    #the central pixel is replaced with the median of the neighborhood
    #it is the most effective when removing salt-and-pepper noise
    blurred = numpy.hstack([
    cv2.medianBlur(gray, 3),
    cv2.medianBlur(gray, 5),
    cv2.medianBlur(gray, 7)])

    #display two images in a figure
    cv2.imshow("Blurring by Median", blurred)

    cv2.imwrite("1_blur_by_Median.jpg", blurred)


    if(cv2.waitKey(0)==27):
     cv2.destroyAllWindows()


4.

bilateral

  import numpy
    import argparse
    import cv2

    image = cv2.imread('1.jpg')
    cv2.imshow("Original", image)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    cv2.imshow("Gray", gray)


    #[x,y] is the kernel for bluring
    #the large kernel becomes, the more blurred imag will appear
    #hstack is able to stack multiple images together
    #in order to reduce noise while maintaining edges
    blurred = numpy.hstack([
    cv2.bilateralFilter(gray, 5,21,21),
    cv2.bilateralFilter(gray, 7,31,31),
    cv2.bilateralFilter(gray, 9,41,41)])

    #display two images in a figure
    cv2.imshow("Blurring by Bilateral", blurred)

    cv2.imwrite("1_blur_by_Bilateral.jpg", blurred)


    if(cv2.waitKey(0)==27):
     cv2.destroyAllWindows()

 

 

图像下采样,基于模糊算法再进行一定的缩放即可,这里贴下我在实验过程中用到的方法供大家参考:

 

 

为了获取不同的采样数据,我直接写成批处理,代码如下:

from PIL import Image
import os,sys
from multiprocessing import Pool
import scipy.misc as misc
import shutil
import random
import numpy as np
import cv2 as cv

# 指定输入和输出路径
input_dir = '../data/Mosaic_HR/'
output_dir = '../data/Mosaic_LR_NEW/'
scale = 4.  # 4. 放大倍数

if not os.path.exists(output_dir):
    os.mkdir(output_dir)    # os.makedirs
image_list = os.listdir(input_dir)
image_list = [os.path.join(input_dir, _) for _ in image_list]

# 采样函数定义
def downscale(name):
    print(name)
    with Image.open(name) as im:
        w, h = im.size
        w_new = int(w / scale)
        h_new = int(h / scale)
        im_new = im.resize((w_new, h_new), Image.ANTIALIAS)
        save_name = os.path.join(output_dir, name.split('/')[-1])
        im_new.save(save_name)

def resize(image, newsize):
    #methods = ['nearest','lanczos','bilinear','bicubic','cubic']
    methods = ['bicubic','lanczos','bilinear','bicubic','cubic']
    scale = [4, 3, 2, 1.5, 0.75, 0.5, 0.25]
    #0.309090465205
    value = random.random()
    if (len(image.shape) == 3):
        w, h, d = image.shape
    else:
        w, h = image.shape

    s = int(value*1000) % 7
    if s == 0:
        image = image + np.random.random_sample(image.shape)*(int(value*100) % 50)
    elif s == 1:
        image = cv.blur(image, (5, 5))
    elif s == 2:
        image = cv.GaussianBlur(image, (5, 5), 1)
    elif s == 3:
        image = cv.medianBlur(image, 5)
    elif s == 4:
        cv.bilateralFilter(image, 9, 75, 75)

    image = misc.imresize(image, newsize, methods[int(value*10)%5])
    for i in range(int(value*100) % 5):
        image = misc.imresize(image, (int(newsize[0]*scale[int(value*(10 ** (1+i)))%7]), int(newsize[1]*scale[int(value*(10**(1+i)))%7])), methods[int(value*(10 ** (4+i)) % 5)])
        image = misc.imresize(image, newsize, methods[int(value*(10 ** (4+i)) % 10 - 5)])
    return image

index = 0

def newDownscale(name):
    global index
    index += 1
    try:
        sys.stdout.write('\r>>Converting image %d/100000 ' % (index))
        sys.stdout.flush()
        image = misc.imread(name)
        w, h, d = image.shape
        w_new = int(w / scale)
        h_new = int(h / scale)
        image = resize(image, (w_new, h_new))
        save_name = os.path.join(output_dir, name.split('/')[-1])
        misc.imsave(save_name, image)


    except IOError as e:
        print('could not read:',name)
        print('error:',e)
        shutil.move(name,'/home/gavin/Desktop/face_test')
        print('skip it\n')
    except ValueError as err:
        print('valuer Error: %s' % name )
        print('error:', err)
        shutil.move(name, "/home/gavin/Desktop/valueErr")
    else:
        shutil.move(name, '/home/gavin/Desktop/Mosaic_HR_NEW')




p = Pool(5)
p.map(newDownscale, image_list)

sys.stdout.write('Convert Over!\n')
sys.stdout.flush()

 

utils.py数据增强

# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import os
import random
from PIL import Image
from PIL import ImageFilter

class DataLoader(object):
    
    def __init__(self, scale=4, crop_size=96, name=None):
        self.__scale = 4
        self.__crop_size = 96
        self.scale = scale
        self.crop_size = crop_size
        self.name = name
        pass
    
    @property
    def scale(self):
        return self.__scale
    
    @scale.setter
    def scale(self, value):
        if not isinstance(value, int):
            raise ValueError("scale must be int")
        elif value <= 0:
            raise ValueError("scale must > 0")
        else:
            self.__scale = value
            pass
        pass
    
    @property
    def crop_size(self):
        return self.__crop_size
    
    @crop_size.setter
    def crop_size(self, value):
        if not isinstance(value, int):
            raise ValueError("crop size must be int")
        elif value <= 0:
            raise ValueError("crop size must > 0")
        else:
            self.__crop_size = value
            pass
        pass
    
    def imread(self, path):
        return Image.open(path)
    
    def resize(self, image, size):
        resamples = [Image.NEAREST, Image.BILINEAR, Image.HAMMING, \
                     Image.BICUBIC, Image.LANCZOS]
        resample = random.choice(resamples)
        return image.resize(size, resample=resample)
    
    def gaussianblur(self, image, radius=2):
        return image.filter(ImageFilter.GaussianBlur(radius=radius))
    
    def medianfilter(self, image, size=3):
        return image.filter(ImageFilter.MedianFilter(size=size))
    
    def downsampling(self, image):
        resize = (image.size[0]//self.scale, image.size[1]//self.scale)
        hidden_scale = random.uniform(1, 3)
        hidden_resize = (int(resize[0]/hidden_scale), int(resize[1]/hidden_scale))
        radius = random.uniform(1, 3)
        image = self.gaussianblur(image, radius)
        image = self.resize(image, hidden_resize)
        image = self.resize(image, resize)
        return image
    
    def search(self, setpath):
        results = []
        files = os.listdir(setpath)
        for file in files:
            path = os.path.join(setpath, file)
            results.append(path)
            pass
        return results
    
    def rotate(self, lr, hr):
        angle = random.choice([0, 90, 180, 270])
        lr = lr.rotate(angle, expand=True)
        hr = hr.rotate(angle, expand=True)
        return lr, hr
    
    def flip(self, lr, hr):
        mode = random.choice([0, 1, 2, 3])
        if mode == 0:
            pass
        elif mode == 1:
            lr = lr.transpose(Image.FLIP_LEFT_RIGHT)
            hr = hr.transpose(Image.FLIP_LEFT_RIGHT)
            pass
        elif mode == 2:
            lr = lr.transpose(Image.FLIP_TOP_BOTTOM)
            hr = hr.transpose(Image.FLIP_TOP_BOTTOM)
            pass
        elif mode == 3:
            lr = lr.transpose(Image.FLIP_LEFT_RIGHT)
            hr = hr.transpose(Image.FLIP_LEFT_RIGHT)
            lr = lr.transpose(Image.FLIP_TOP_BOTTOM)
            hr = hr.transpose(Image.FLIP_TOP_BOTTOM)
            pass
        return lr, hr
    
    def crop(self, lr, hr):
        hr_crop_size = self.crop_size
        lr_crop_size = hr_crop_size//self.scale
        lr_w = np.random.randint(lr.size[0] - lr_crop_size + 1)
        lr_h = np.random.randint(lr.size[1] - lr_crop_size + 1)
        hr_w = lr_w * self.scale
        hr_h = lr_h * self.scale
        lr = lr.crop([lr_w, lr_h, lr_w+lr_crop_size, lr_h+lr_crop_size])
        hr = hr.crop([hr_w, hr_h, hr_w+hr_crop_size, hr_h+hr_crop_size])
        return lr, hr
    
    def pair(self, fp):
        hr = self.imread(fp)
        lr = self.downsampling(hr)
        lr, hr = self.rotate(lr, hr)
        lr, hr = self.flip(lr, hr)
        lr, hr = self.crop(lr, hr)
        lr =  np.asarray(lr)
        hr =  np.asarray(hr)
        return lr, hr
    
    def batches(self, setpath="datasets/train", batch_size=16, complete_batch_only=False):
        images = self.search(setpath)
        sizes = []
        for image in images:
            array = plt.imread(image)
            sizes.append(array.shape[0])
            sizes.append(array.shape[1])
            pass
        crop_size_max = min(sizes)
        crop_size = min(crop_size_max, self.crop_size)
        if self.crop_size != crop_size:
            self.crop_size = crop_size
            print("Info: crop size adjusted to " + str(self.crop_size) + ".")
            pass
        np.random.shuffle(images)
        n_complete_batches = int(len(images)/batch_size)
        self.n_batches = int(len(images) / batch_size)
        have_res_batch = (len(images)/batch_size) > n_complete_batches
        if have_res_batch and complete_batch_only==False:
            self.n_batches += 1
            pass
        for i in range(n_complete_batches):
            batch = images[i*batch_size:(i+1)*batch_size]
            lrs, hrs = [], []
            for image in batch:
                lr, hr = self.pair(image)
                lrs.append(lr)
                hrs.append(hr)
                pass
            lrs = np.array(lrs)
            hrs = np.array(hrs)
            yield lrs, hrs
        if self.n_batches > n_complete_batches:
            batch = images[n_complete_batches*batch_size:]
            lrs, hrs = [], []
            for image in batch:
                lr, hr = self.pair(image)
                lrs.append(lr)
                hrs.append(hr)
                pass
            lrs = np.array(lrs)
            hrs = np.array(hrs)
            yield lrs, hrs
        pass
        
    pass

 

 

 

 

 

参考文献:

1.https://blog.youkuaiyun.com/chevroletss/article/details/49785435

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值