2018-11-18 15:02:40 qq_37482202 阅读数 15069
  • Python+OpenCV3.3图像处理视频教程

    Python+OpenCV3.3图像处理视频培训课程:该教程基于Python3.6+OpenCV新版本3.3.0详细讲述Python OpenCV图像处理部分内容,包括opencv人脸识别、人脸检测、数字验证码识别等内容。是Python开发者学习图像知识与应用开发佳实践课程。

    5419 人正在学习 去看看 贾志刚

质量、速度、廉价,选择其中两个

提到图像处理第一个想到的库就是PIL,全称Python Imaging Library Python,图像处理类库,它提供了大量的图像操作,比如图像缩放,裁剪,贴图,模糊等等,很多时候它需要配合numpy库一起使用

1.open()

你可以使用Image.open打开一个图像文件,它会返回PIL图像对象

image = Image.open(image_address)

2.covert()

你可以 covert() 方法转换图像格式,covert() 有三种传参方式

im.convert(mode) ⇒ image

im.convert(“P”, **options) ⇒ image

im.convert(mode, matrix) ⇒ image

最常用的还是第一种,通过该方法你可以将PIL图像转换成九种不同的格式,分别1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。

1.模式“1”

模式“1”为二值图像,非黑即白。但是它每个像素用8个bit表示,0表示黑,255表示白。

2.模式“L”

模式”L”为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。在PIL中,从模式“RGB”转换为“L”模式是按照下面的公式转换的:

L = R * 299/1000 + G * 587/1000+ B * 114/1000

3.模式“p”

模式“P”为8位彩色图像,它的每个像素用8个bit表示,其对应的彩色值是按照调色板查询出来的。

4.模式“RGBA”

模式“RGBA”为32位彩色图像,它的每个像素用32个bit表示,其中24bit表示红色、绿色和蓝色三个通道,另外8bit表示alpha通道,即透明通道。

5.模式“CMYK”

模式“CMYK”为32位彩色图像,它的每个像素用32个bit表示。模式“CMYK”就是印刷四分色模式,它是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。

四种标准颜色是:C:Cyan = 青色,又称为‘天蓝色’或是‘湛蓝’M:Magenta = 品红色,又称为‘洋红色’;Y:Yellow = 黄色;K:Key Plate(blacK) = 定位套版色(黑色)。

6.模式“YCbCr”

模式“YCbCr”为24位彩色图像,它的每个像素用24个bit表示。YCbCr其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。人的肉眼对视频的Y分量更敏感,因此在通过对色度分量进行子采样来减少色度分量后,肉眼将察觉不到的图像质量的变化。

模式“RGB”转换为“YCbCr”的公式如下:

Y= 0.257*R+0.504*G+0.098*B+16
Cb = -0.148*R-0.291*G+0.439*B+128
Cr = 0.439*R-0.368*G-0.071*B+128

7.模式“I”

模式“I”为32位整型灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“I”模式是按照下面的公式转换的:

I = R * 299/1000 + G * 587/1000 + B * 114/1000

8.模式“F”

模式“F”为32位浮点灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式“RGB”转换为“F”模式是按照下面的公式转换的:

F = R * 299/1000+ G * 587/1000 + B * 114/1000

3.调整尺寸、创建缩略图、裁剪、贴图、旋转

PIL库给我们提供了丰富基本图像操作,如果你想调整一张图片的尺寸,你可以使用resize()方法,该方法需要传入你指定新图像宽高的元组

img = img.resize((128,128))

如果你想创建一张图片的缩略图,你可以使用thumbnail()方法,该方法需要传入缩略图的宽高元组

img=img.thumbnail((128,128))

如果你想对一张图片的一部分进行裁剪,你可以使用crop()方法,该方法需要你传入一个元组,该元组指定裁剪区域的左上角坐标和右下角坐标

box = (100,100,400,400)
img = img.crop(box)

如果你想把一张图片覆盖在另一个图片的上面,你可以使用paste()方法,该方法需要传入要贴的图片和位置(左上角坐标和右下角坐标)

img2=img2.paste(img1,(100,100,200,200))

如果你想要旋转一张图片,你可以使用transpose()方法,该方法传入旋转角度

img = img.transpose(Image.ROTATE_180)

不过这些角度很受限制,只可以传下面之中的一个

  • PIL.Image.FLIP_LEFT_RIGHT 
  • PIL.Image.FLIP_TOP_BOTTOM
  • PIL.Image.ROTATE_90
  • PIL.Image.ROTATE_180
  • PIL.Image.ROTATE_270
  • PIL.Image.TRANSPOSE
  • PIL.Image.TRANSVERSE

你也可以使用rotate()方法,该方法更为简单方便,只需要传入一个旋转角度即可

image = image.rotate(45)

4.Numpy

对图像进行变换其实就是对矩阵进行变换,我们需要把一张图片转换成矩阵再进行操作,使用array()方法

image = Image.open(image_address)
imageArray = array(image)

1.反向处理与二值化

图像一般都是三通道的,也就是红绿蓝,他们的值从0-255,所谓反相处理呢,就是把颜色反过来

imageArray = 255 - imageArray

 图像的二值化也很简单,0-255以128为分界,小于128置为0否则置为1

imageArray = 1 * (imageArray < 128)

2.像素值限制范围

如果你想把一个图像的像素值都限制到一个范围内,比如说你想把像素值限制到100-200这个区间上,你可以这么干

imageArray = (100.0 / 255) * imageArray + 100

3.像素值求平方

imageArray = 255.0 * (imageArray / 255.0) ** 2

4.直方图均衡化

图像灰度变换中一个非常有用的例子就是直方图均衡化。直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。在对图像做进一步处理之前,直方图均衡化通常是对图像灰度值进行归一化的一个非常好的方法,并且可以增强图像的对比度。

在这种情况下,直方图均衡化的变换函数是图像中像素值的累积分布函数(cumulative distribution function,简写为 cdf,将像素值的范围映射到目标范围的归一化操作)

def histeq(im,nbr_bins=256):
    """ 对一幅灰度图像进行直方图均衡化"""
    # 计算图像的直方图
    imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
    cdf = imhist.cumsum()
    # cumulative distribution function
    cdf = 255 * cdf / cdf[-1]
    #  归一化
    #  使用累积分布函数的线性插值,计算新的像素值
    im2 = interp(im.flatten(),bins[:-1],cdf)
    return im2.reshape(im.shape), cdf

该函数有两个输入参数,一个是灰度图像,一个是直方图中使用小区间的数目。函数返回直方图均衡化后的图像,以及用来做像素值映射的累积分布函数。注意,函数中使用到累积分布函数的最后一个元素(下标为 -1),目的是将其归一化到 0...1 范围。

直方图均衡化后图像可以使对比度增强,使原先图像灰色区域的细节变得更清晰

5.多种滤波

gaussian滤波是多维的滤波器,是一种平滑滤波,可以消除高斯噪声

通过调节sigma的值来调整滤波效果

imageArray = filters.gaussian_filter(imageArray, 5)

sobel算子可用来检测边缘

edges = filters.sobel(img)

roberts算子、scharr算子、prewitt算子和sobel算子一样,用于检测边缘

edges = filters.roberts(img)
edges = filters.scharr(img)
edges = filters.prewitt(img)

canny算子也是用于提取边缘特征,但它不是放在filters模块,而是放在feature模块

edges1 = feature.canny(img)   #sigma=1
edges2 = feature.canny(img,sigma=3)   #sigma=3

gabor滤波可用来进行边缘检测和纹理特征提取。

通过修改frequency值来调整滤波效果,返回一对边缘结果,一个是用真实滤波核的滤波结果,一个是想象的滤波核的滤波结果。

filt_real, filt_imag = filters.gabor_filter(img,frequency=0.6)   

6.PCA

PCA(Principal Component Analysis,主成分分析)是一个非常有用的降维技巧。它可以在使用尽可能少维数的前提下,尽量多地保持训练数据的信息,在此意义上是一个最佳技巧。即使是一幅 100×100 像素的小灰度图像,也有 10 000 维,可以看成 10 000 维空间中的一个点。一兆像素的图像具有百万维。由于图像具有很高的维数,在许多计算机视觉应用中,我们经常使用降维操作。PCA 产生的投影矩阵可以被视为将原始坐标变换到现有的坐标系,坐标系中的各个坐标按照重要性递减排列。

为了对图像数据进行 PCA 变换,图像需要转换成一维向量表示。我们可以使用 NumPy 类库中的 flatten() 方法进行变换。

将变平的图像堆积起来,我们可以得到一个矩阵,矩阵的一行表示一幅图像。在计算主方向之前,所有的行图像按照平均图像进行了中心化。我们通常使用 SVD(Singular Value Decomposition,奇异值分解)方法来计算主成分;但当矩阵的维数很大时,SVD 的计算非常慢,所以此时通常不使用 SVD 分解。下面就是 PCA 操作的代码:

def pca(X):
    """ 主成分分析:    输入:矩阵X ,其中该矩阵中存储训练数据,每一行为一条训练数据
       返回:投影矩阵(按照维度的重要性排序)、方差和均值"""
    # 获取维数
    num_data,dim = X.shape
    # 数据中心化
    mean_X = X.mean(axis=0)
    X = X - mean_X
    if dim<num_data:
        # PCA- 使用紧致技巧
        M = dot(X,X.T)
        # 协方差矩阵
        e,EV = linalg.eigh(M)
        # 特征值和特征向量
        tmp = dot(X.T,EV).T
        # 这就是紧致技巧
        V = tmp[::-1]
        # 由于最后的特征向量是我们所需要的,所以需要将其逆转
        S = sqrt(e)[::-1]
        # 由于特征值是按照递增顺序排列的,所以需要将其逆转
        for i in range(V.shape[1]):
            V[:,i] /= S
    else:
        # PCA- 使用SVD 方法
        U,S,V = linalg.svd(X)
        V = V[:num_data]
        # 仅仅返回前nun_data 维的数据才合理
        #  返回投影矩阵、方差和均值
    return V,S,mean_X

7.图像添加噪声和降噪

添加噪声比降噪简单得多,只需要把图像矩阵上面随机加一些值就好了

imageArray = imageArray + 30 * random.standard_normal(imageArray.shape)

图像降噪是在去除图像噪声的同时,尽可能地保留图像细节和结构的处理技术,我们这里使用 ROF去燥模型

一幅(灰度)图像 I 的全变差(Total Variation,TV)定义为梯度范数之和。在连续表示的情况下,全变差表示为:

J(\boldsymbol{I})=\int\left|\nabla\boldsymbol{I}\right|\text{dx} 

在离散表示的情况下,全变差表示为:

J(\boldsymbol{I})=\sum_{\text{x}}\left|\nabla\boldsymbol{I}\right|

其中,上面的式子是在所有图像坐标 x=[x, y] 上取和。

在 Chambolle 提出的 ROF 模型里,目标函数为寻找降噪后的图像 U,使下式最小:

\min_U\left|\left|\boldsymbol{I}-\boldsymbol{U}\right|\right|^2+2\lambda J(\boldsymbol{U}),

其中范数 ||I-U|| 是去噪后图像 U 和原始图像 I 差异的度量。也就是说,本质上该模型使去噪后的图像像素值“平坦”变化,但是在图像区域的边缘上,允许去噪后的图像像素值“跳跃”变化。

def denoise(im,U_init,tolerance=0.1,tau=0.125,tv_weight=100):
    """ 使用A. Chambolle(2005)在公式(11)中的计算步骤实现Rudin-Osher-Fatemi(ROF)去噪模型
       输入:含有噪声的输入图像(灰度图像)、U 的初始值、TV 正则项权值、步长、停业条件
        输出:去噪和去除纹理后的图像、纹理残留"""
    m,n = im.shape # 噪声图像的大小

    #  初始化
    U = U_init
    Px = im # 对偶域的x 分量
    Py = im # 对偶域的y 分量
    error = 1
    while (error > tolerance):
        Uold = U

        # 原始变量的梯度
        GradUx = roll(U,-1,axis=1)-U # 变量U 梯度的x 分量
        GradUy = roll(U,-1,axis=0)-U # 变量U 梯度的y 分量

        #  更新对偶变量
        PxNew = Px + (tau/tv_weight)*GradUx
        PyNew = Py + (tau/tv_weight)*GradUy
        NormNew = maximum(1,sqrt(PxNew**2+PyNew**2))
        Px = PxNew/NormNew # 更新x 分量(对偶)
        Py = PyNew/NormNew # 更新y 分量(对偶)
        #  更新原始变量
        RxPx = roll(Px,1,axis=1) # 对x 分量进行向右x 轴平移
        RyPy = roll(Py,1,axis=0) # 对y 分量进行向右y 轴平移

        DivP = (Px-RxPx)+(Py-RyPy) # 对偶域的散度
        U = im + tv_weight*DivP # 更新原始变量

        #  更新误差
        error = linalg.norm(U-Uold)/sqrt(n*m);
    return U,im-U  # 去噪后的图像和纹理残余

5.Matplotlib

我们队图像进行处理之后往往需要知道处理后变化如何,该库便可以方便地绘制出条形图,饼状图等等呢个图像,还可在上面添加标记等等

尽管 Matplotlib 可以绘制出较好的条形图、饼状图、散点图等,但是对于大多数计算机视觉应用来说,仅仅需要用到几个绘图命令。最重要的是,我们想用点和线来表示一些事物,比如兴趣点、对应点以及检测出的物体。下面是用几个点和一条线绘制图像的例子:

from PIL import Image
from pylab import *

# 读取图像到数组中
im = array(Image.open('empire.jpg'))

# 绘制图像
imshow(im)

# 一些点
x = [100,100,400,400]
y = [200,500,200,500]

# 使用红色星状标记绘制点
plot(x,y,'r*')

# 绘制连接前两个点的线
plot(x[:2],y[:2])

# 添加标题,显示绘制的图像
title('Plotting: "empire.jpg"')
show()

上面的代码首先绘制出原始图像,然后在 x 和 y 列表中给定点的 x 坐标和 y 坐标上绘制出红色星状标记点,最后在两个列表表示的前两个点之间绘制一条线段(默认为蓝色)。该例子的绘制结果如图 1-2 所示。show() 命令首先打开图形用户界面(GUI),然后新建一个图像窗口。该图形用户界面会循环阻断脚本,然后暂停,直到最后一个图像窗口关闭。在每个脚本里,你只能调用一次 show() 命令,而且通常是在脚本的结尾调用。注意,在 PyLab 库中,我们约定图像的左上角为坐标原点。

图像的坐标轴是一个很有用的调试工具;但是,如果你想绘制出较美观的图像,加上下列命令可以使坐标轴不显示:

axis('off')

 下面是我写的一个图像处理的脚本

import PIL.Image as Image
import os
from pylab import *
from numpy import *
from scipy.ndimage import filters
from scipy.ndimage import measurements,morphology


def get_imlist(path):
    # 一级文件夹下有用
    # return [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.jpg')]
    g = os.walk(path)
    image_list=[]
    for path, d, filelist in g:
        for filename in filelist:
            if filename.endswith('jpg'):
                image_list.append(os.path.join(path, filename))
    return image_list

def histeq(im,nbr_bins=256):
    """ 对一幅灰度图像进行直方图均衡化"""
    # 计算图像的直方图
    imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
    cdf = imhist.cumsum()
    # cumulative distribution function
    cdf = 255 * cdf / cdf[-1]
    #  归一化
    #  使用累积分布函数的线性插值,计算新的像素值
    im2 = interp(im.flatten(),bins[:-1],cdf)
    return im2.reshape(im.shape), cdf

def pca(X):
    """ 主成分分析:    输入:矩阵X ,其中该矩阵中存储训练数据,每一行为一条训练数据
       返回:投影矩阵(按照维度的重要性排序)、方差和均值"""
    # 获取维数
    num_data,dim = X.shape
    # 数据中心化
    mean_X = X.mean(axis=0)
    X = X - mean_X
    if dim<num_data:
        # PCA- 使用紧致技巧
        M = dot(X,X.T)
        # 协方差矩阵
        e,EV = linalg.eigh(M)
        # 特征值和特征向量
        tmp = dot(X.T,EV).T
        # 这就是紧致技巧
        V = tmp[::-1]
        # 由于最后的特征向量是我们所需要的,所以需要将其逆转
        S = sqrt(e)[::-1]
        # 由于特征值是按照递增顺序排列的,所以需要将其逆转
        for i in range(V.shape[1]):
            V[:,i] /= S
    else:
        # PCA- 使用SVD 方法
        U,S,V = linalg.svd(X)
        V = V[:num_data]
        # 仅仅返回前nun_data 维的数据才合理
        #  返回投影矩阵、方差和均值
    return V,S,mean_X

def denoise(im,U_init,tolerance=0.1,tau=0.125,tv_weight=100):
    """ 使用A. Chambolle(2005)在公式(11)中的计算步骤实现Rudin-Osher-Fatemi(ROF)去噪模型
       输入:含有噪声的输入图像(灰度图像)、U 的初始值、TV 正则项权值、步长、停业条件
        输出:去噪和去除纹理后的图像、纹理残留"""
    m,n = im.shape # 噪声图像的大小

    #  初始化
    U = U_init
    Px = im # 对偶域的x 分量
    Py = im # 对偶域的y 分量
    error = 1
    while (error > tolerance):
        Uold = U

        # 原始变量的梯度
        GradUx = roll(U,-1,axis=1)-U # 变量U 梯度的x 分量
        GradUy = roll(U,-1,axis=0)-U # 变量U 梯度的y 分量

        #  更新对偶变量
        PxNew = Px + (tau/tv_weight)*GradUx
        PyNew = Py + (tau/tv_weight)*GradUy
        NormNew = maximum(1,sqrt(PxNew**2+PyNew**2))
        Px = PxNew/NormNew # 更新x 分量(对偶)
        Py = PyNew/NormNew # 更新y 分量(对偶)
        #  更新原始变量
        RxPx = roll(Px,1,axis=1) # 对x 分量进行向右x 轴平移
        RyPy = roll(Py,1,axis=0) # 对y 分量进行向右y 轴平移

        DivP = (Px-RxPx)+(Py-RyPy) # 对偶域的散度
        U = im + tv_weight*DivP # 更新原始变量

        #  更新误差
        error = linalg.norm(U-Uold)/sqrt(n*m);
    return U,im-U  # 去噪后的图像和纹理残余




image_list = get_imlist("G:\\最后两种\\")

index=6858
for image_address in image_list:
    index = index + 1
    dealIndex=0
    for x in range(1,17):
        image = Image.open(image_address)
        imageArray = array(image)
        dealIndex+=1
        if x==1:
            # 反相处理
            imageArray = 255 - imageArray
            print("第"+str(index)+"张 反向处理")
        elif x==2:
            # 将图像像素值变换到100...200 区间
            imageArray = (100.0 / 255) * imageArray + 100
            print("第" + str(index) + "张 像素值变换")
        elif x==3:
            # 对图像像素值求平方后得到的图像
            imageArray = 255.0 * (imageArray / 255.0) ** 2
            print("第" + str(index) + "张 像素值求平方")
        elif x==4:
            # 图像旋转
            image = image.rotate(random.randint(0,360))
            imageArray=array(image)
            print("第" + str(index) + "张 图像旋转")
        elif x==5:
            # 直方图均衡化
            imageArray,cdf=histeq(imageArray)
            print("第" + str(index) + "张 直方图均衡化")
        elif x==6:
            # gaussian滤波
            imageArray = filters.gaussian_filter(imageArray, 5)
            print("第" + str(index) + "张 gaussian滤波")
        elif x==7:
            # Sobel 导数滤波器
            imx = zeros(imageArray.shape)
            filters.sobel(imageArray, 1, imx)
            imy = zeros(imageArray.shape)
            filters.sobel(imageArray, 0, imy)
            magnitude = sqrt(imx ** 2 + imy ** 2)
            imageArray=magnitude
            print("第" + str(index) + "张  Sobel导数滤波器")
        elif x==8:
            # 噪声
            imageArray = imageArray + 30 * random.standard_normal(imageArray.shape)
            print("第" + str(index) + "张  噪声")
        elif x==9:
            # 反相处理+像素值变换
            imageArray = 255 - imageArray
            imageArray = (100.0 / 255) * imageArray + 100
            print("第" + str(index) + "张  反相处理+像素值变换")
        elif x==10:
            # 反相处理+像素值求平方
            imageArray = 255 - imageArray
            imageArray = 255.0 * (imageArray / 255.0) ** 2
            print("第" + str(index) + "张  反相处理+像素值求平方")
        elif x==11:
            # 像素值求平方+反相处理
            imageArray = 255.0 * (imageArray / 255.0) ** 2
            imageArray = 255 - imageArray
            print("第" + str(index) + "张  像素值求平方+反相处理")
        elif x==12:
            # 像素值变换+像素值求平方
            imageArray = (100.0 / 255) * imageArray + 100
            imageArray = 255.0 * (imageArray / 255.0) ** 2
            print("第" + str(index) + "张  像素值变换+像素值求平方")
        elif x==13:
            # 图像旋转+反相
            image = image.rotate(random.randint(0, 360))
            imageArray = array(image)
            imageArray = 255 - imageArray
            print("第" + str(index) + "张  图像旋转+反相")
        elif x==14:
            # 图像旋转+噪声
            image = image.rotate(random.randint(0, 360))
            imageArray = array(image)
            imageArray = imageArray + 30 * random.standard_normal(imageArray.shape)
            print("第" + str(index) + "张  图像旋转+噪声")
        elif x==15:
            # 噪声+直方图均衡化
            imageArray = imageArray + 30 * random.standard_normal(imageArray.shape)
            imageArray, cdf = histeq(imageArray)
            print("第" + str(index) + "张  噪声+直方图均衡化")


        imageArray = uint8(imageArray)
        image=Image.fromarray(imageArray)
        image = image.convert('RGB')
        if image_address.rfind("不规则")!= -1:
            image.save("G:\\兔屎图片_二次处理\\不规则\\" + str(index)+"_"+str(dealIndex) + ".jpg")
        elif image_address.rfind("大小不一") != -1:
            image.save("G:\\兔屎图片_二次处理\\大小不一\\" + str(index) +"_"+str(dealIndex)+ ".jpg")
        elif image_address.rfind("拉稀") != -1:
            image.save("G:\\兔屎图片_二次处理\\拉稀\\" + str(index) +"_"+str(dealIndex)+ ".jpg")
        elif image_address.rfind("正常") != -1:
            image.save("G:\\兔屎图片_二次处理\\正常\\" + str(index) +"_"+str(dealIndex)+ ".jpg")

        print("完事一个")

参考文章:https://www.cnblogs.com/xk-bench/p/7825290.html

2019-10-09 21:22:01 weixin_40198377 阅读数 15
  • Python+OpenCV3.3图像处理视频教程

    Python+OpenCV3.3图像处理视频培训课程:该教程基于Python3.6+OpenCV新版本3.3.0详细讲述Python OpenCV图像处理部分内容,包括opencv人脸识别、人脸检测、数字验证码识别等内容。是Python开发者学习图像知识与应用开发佳实践课程。

    5419 人正在学习 去看看 贾志刚

1.基本概念及API简介

模糊操作是图像处理中最简单和常用的操作之一,该使用的操作之一原因就为了给图像预处理时减低噪声,基于数学的卷积操作

均值模糊:
将一个区域内所有点的灰度值的平均值作为这个点的灰度值,是线性滤波器。

cv2.blur(src: Any,  ksize: Any, dst: Any = None, anchor: Any = None, borderType: Any = None)

中值模糊:
取领域的中值作为当前点的灰度值,是非线性滤波器。对去除椒盐噪声有很好的效果。

cv2.medianBlur(src: Any,  ksize: Any, dst: Any = None)

ksize: 一个大于1的奇数

自定义模糊:
自定义卷积核对图像进行锐化之类的操作。

cv2.filter2D(src: Any, ddepth: Any, kernel: Any, dst: Any = None, anchor: Any = None, delta: Any = None, borderType: Any = None)

kernel: 当kernel总和为1时:增强锐化。kernel总和为0时:边缘梯度。
ddepth: -1表示和原图像位深一致

高斯模糊:
高斯模糊本质上是低通滤波器,输出图像的每个像素点是原图像上对应像素点与周围像素点的加权和,就是用高斯分布权值矩阵与原始图像矩阵做卷积运算。保留轮廓,保留图像的主要特征,比均值模糊去噪效果好。

GaussianBlur(src: Any, ksize: Any, sigmaX: Any, dst: Any = None, sigmaY: Any = None, borderType: Any = None)

2.代码示例

import cv2
import numpy as np

img1 = cv2.imread('E:/PycharmProjects/one.jpg')

def show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
show('img1', img1)

# 1.均值模糊和中值模糊
def blur_img(img):
    mean_blur = cv2.blur(img, (10, 10))
    show('mean_blur', mean_blur)
    median_blur = cv2.medianBlur(img, 15)
    show('median_blur', median_blur)

blur_img(img1)

# 2.自定义模糊
def custom_blur_img(img):
    kernel = np.ones([10, 10], np.float)/100
    custom_blur = cv2.filter2D(img, -1, kernel=kernel)
    show('custom_blur', custom_blur)

custom_blur_img(img1)

# 3.高斯模糊
def clamp(pv):
    if pv > 255:
        return 255
    if pv < 0:
        return 0
    else:
        return pv

def gaussian_noise(image):
    h, w, c = image.shape
    for row in range(h):
        for col in range(w):
            s = np.random.normal(0, 20, 3)
            b = image[row, col, 0]  # blue
            g = image[row, col, 1]  # green
            r = image[row, col, 2]  # red
            image[row, col, 0] = clamp(b + s[0])
            image[row, col, 1] = clamp(g + s[1])
            image[row, col, 2] = clamp(r + s[2])
    show("noise image",   image)
    dst = cv2.GaussianBlur(image, (3, 3), 0)  
    show("Gaussian Blur", dst)

gaussian_noise(img1)

3.结果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2018-07-29 22:29:30 qq_40962368 阅读数 6249
  • Python+OpenCV3.3图像处理视频教程

    Python+OpenCV3.3图像处理视频培训课程:该教程基于Python3.6+OpenCV新版本3.3.0详细讲述Python OpenCV图像处理部分内容,包括opencv人脸识别、人脸检测、数字验证码识别等内容。是Python开发者学习图像知识与应用开发佳实践课程。

    5419 人正在学习 去看看 贾志刚

图像平滑与滤波

运用它,首先就要了解它,什么是平滑滤波?

      平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是模糊;另一类是消除噪音。空间域的平滑滤波一般采用简单平均法进行,就是求邻近像元点的平均亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。

在看一下滤波的目的:

滤波的本义是指信号有各种频率的成分,滤掉不想要的成分,即为滤掉常说的噪声,留下想要的成分.这即是滤波的过程,也是目的。

 

  • 一是抽出对象的特征作为图像识别的特征模式;(在我未来将要进行的一个项目中将会用的到)
  • 另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声。

有关平滑与滤波更多的介绍,可以查看百度词条:平滑与滤波

里面有对平滑与滤波详细的解释,我就不一 一介绍了,感谢词条的贡献者,感谢分享,非常感谢。

 

对于2D图像可以进行低通或者高通滤波操作,低通滤波(LPF)有利于去噪,模糊图像,高通滤波(HPF)有利于找到图像边界。

(一)2D滤波器cv2.filter2D( )

img = cv2.imread('kenan.jpg', 0)
kernel = np.ones((5, 5), np.float32)/25

dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('dst', dst)
cv2.imshow('yuantu', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

(二)均值滤波

 OpenCV中有一个专门的平均滤波模板供使用------归一化卷积模板,所有的滤波模板都是使卷积框覆盖区域所有像素点与模板相乘后得到的值作为中心像素的值。OpenCV中均值模板可以用cv2.blur和cv2.boxFilter,比如一个3*3的模板其实就可以如下表示;

模板大小m*n是可以设置的。如果不想要前面的1/9,可以使用非归一化模板cv2.boxFitter。

cv2.blur()是一个通用的2D滤波函数,它的使用需要一个核模板。该滤波函数是单通道运算的,
如果是彩色图像,那么需要将彩色图像的各个通道提取出来,然后分别对各个通道滤波。

如果不想使用归一化模板,那么应该使用cv2.boxFilter(), 并且传入参数normalize=False

img = cv2.imread('kenan.jpg', 0)
blur = cv2.blur(img, (3, 5))  # 模板大小为3*5, 模板的大小是可以设定的
box = cv2.boxFilter(img, -1, (3, 5))
cv2.imshow('gray', img)
cv2.imshow('gray_new', blur)
cv2.imshow('gray_new2', box)
cv2.waitKey(0)
cv2.destroyAllWindows()

(三)高斯模糊模板

在上一目录中,我们的卷积模板中的值全是1,现在把卷积模板中的值换一下,不全是1了,换成一组符合高斯分布的数值放在模板里,这时模板中的数值将会中间的数值最大,往两边走越来越小,构造一个小的高斯包。这样可以减少原始图像信息的丢失。

在OpenCV实现的函数为cv2.GaussianBlur()。对于高斯模板,我们需要制定的是高斯核的高和宽(奇数),沿x与y方向的标准差(如果只给x,y=x,如果都给0,那么函数会自己计算)。高斯 核可以有效的去除图像的高斯噪声。当然也可以自己构造高斯核,相关函数为:cv2.GaussianKernel()。

# 高斯模糊模板
img = cv2.imread('kenan.jpg', 0)
for i in range(2000):  # 在图像中加入点噪声
    _x = np.random.randint(0, img.shape[0])
    _y = np.random.randint(0, img.shape[1])
    img[_x, _y] = 255
blur = cv2.GaussianBlur(img, (5, 5), 0)  # (5,5)表示的是卷积模板的大小,0表示的是沿x与y方向上的标准差
cv2.imshow('img', img)
cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果为:

(四)中值滤波模板

中值滤波模板就是用卷积框中像素的中值代替中心值,达到去噪声的目的。这个模板一般用于去除椒盐噪声。前面的滤波器都是用计算得到的一个新值来取代中心像素的值,而中值滤波是用中心像素周围(也可以使他本身)的值来取代他,卷积核的大小也是个奇数。

# 中值滤波模板
img = cv2.imread('kenan.jpg', 0)
for i in range(2000):  # 加入椒盐噪声
    _x = np.random.randint(0, img.shape[0])
    _y = np.random.randint(0, img.shape[1])
    img[_x][_y] = 255
blur = cv2.medianBlur(img, 5)  # 中值滤波函数
cv2.imshow('img', img)
cv2.imshow('medianblur_img', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果为:

可以看到,中值滤波对于这些白点噪声的去除,效果是非常好的。

(五)双边滤波

双边滤波(Bilateral  filter)是一种可以保证边界清晰的去噪的滤波器。之所以可以达到此去噪声效果,是因为滤波器是由两个函数构成。一个函数是由几何空间距离决定滤波器系数。另一个由像素差决定滤波器系数。它的构造比较复杂,即考虑了图像的空间关系,也考虑图像的灰度关系。双边滤波同时使用了空间高斯权重和灰度相似性高斯权重,确保了边界不会被模糊掉。

cv2.bilateralFilter(img, d, 'p1', 'p2')函数有四个参数需要,d是领域的直径,后面两个参数是空间高斯函数标准差和灰度值相似性高斯函数标准差。

# 双边滤波
img = cv2.imread('rose1.jpg', 0)
for i in range(2000):  # 添加椒盐噪声
    _x = np.random.randint(0, img.shape[0])
    _y = np.random.randint(0, img.shape[1])
    img[_x][_y] = 255
# 9表示的是滤波领域直径,后面的两个数字:空间高斯函数标准差,灰度值相似性标准差
blur = cv2.bilateralFilter(img, 9, 80, 80)
cv2.imshow('img', img)
cv2.imshow('blur_img', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果为:

双边滤波函数后面的两个参数设置的越大,图像的去噪越多,但随之而来的是图像ji将变得模糊,所以根据需要调整好后两个参数的大小。

2019-10-09 21:26:01 weixin_40198377 阅读数 30
  • Python+OpenCV3.3图像处理视频教程

    Python+OpenCV3.3图像处理视频培训课程:该教程基于Python3.6+OpenCV新版本3.3.0详细讲述Python OpenCV图像处理部分内容,包括opencv人脸识别、人脸检测、数字验证码识别等内容。是Python开发者学习图像知识与应用开发佳实践课程。

    5419 人正在学习 去看看 贾志刚

边缘保留滤波(Edge Preserving Filter,EPF)

1.基本概念

高斯模糊: 基于权重,权重只考虑像素空间的分布
高斯双边模糊: 除了考虑像素空间的分布,还考虑像素值的差异。相当于磨皮操作。
均值迁移模糊: 相当于把图片转化为油画效果的操作。

2.API 介绍

# 高斯双边模糊
cv2.bilateralFilter(src: Any, d: Any, sigmaColor: Any, sigmaSpace: Any, dst: Any = None, borderType: Any = None)

sigmaColor: 色彩差异,取大一点才能去掉噪声
sigmaSpace: 空间差异,取小一点才能保留边缘

# 均值迁移模糊
pyrMeanShiftFiltering(src: Any, sp: Any, sr: Any, dst: Any = None, maxLevel: Any = None,  termcrit: Any = None)

sp: 空间窗的半径(The spatial window radius)
sr: 色彩窗的半径(The color window radius)

3.代码示例

import cv2

def show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)

cat = cv2.imread('E:/PycharmProjects/cat.jpg')

show('cat', cat)

def bi_demo(img):
    bi = cv2.bilateralFilter(img, 0, 100, 15)
    show('bi_demo', bi)

bi_demo(cat)

def shift_demo(img):
    dst = cv2.pyrMeanShiftFiltering(img, 10, 50)
    show('shift_demo', dst)

shift_demo(cat)

cv2.destroyAllWindows()

4.结果展示

在这里插入图片描述

2007-10-28 23:45:00 lanphaday 阅读数 100673
  • Python+OpenCV3.3图像处理视频教程

    Python+OpenCV3.3图像处理视频培训课程:该教程基于Python3.6+OpenCV新版本3.3.0详细讲述Python OpenCV图像处理部分内容,包括opencv人脸识别、人脸检测、数字验证码识别等内容。是Python开发者学习图像知识与应用开发佳实践课程。

    5419 人正在学习 去看看 贾志刚
用Python做图像处理
       最近在做一件比较 evil 的事情——验证码识别,以此来学习一些新的技能。因为我是初学,对图像处理方面就不太了解了,欲要利吾事,必先利吾器,既然只是做一下实验,那用 Python 来作原型开发再好不过了。在 Python 中,比较常用的图像处理库是 PIL(Python Image Library),当前版本是 1.1.6 ,用起来非常方便。大家可以在 http://www.pythonware.com/products/pil/index.htm 下载和学习。
       在这里,我主要是介绍一下做图像识别时可能会用到的一些 PIL 提供的功能,比如图像增强、还有滤波之类的。最后给出使用 Python 做图像处理与识别的优势与劣势。
基本图像处理
       使用 PIL 之前需要 import Image 模块:
import Image
       然后你就可以使用Image.open(‘xx.bmp’) 来打开一个位图文件进行处理了。打开文件你不用担心格式,也不用了解格式,无论什么格式,都只要把文件名丢给 Image.open 就可以了。真所谓 bmp、jpg、png、gif……,一个都不能少。
img = Image.open(‘origin.png’)    # 得到一个图像的实例对象 img
1原图
       图像处理中,最基本的就是色彩空间的转换。一般而言,我们的图像都是 RGB 色彩空间的,但在图像识别当中,我们可能需要转换图像到灰度图、二值图等不同的色彩空间。 PIL 在这方面也提供了极完备的支持,我们可以:
new_img = img.convert(‘L’)
把 img 转换为 256 级灰度图像, convert() 是图像实例对象的一个方法,接受一个 mode 参数,用以指定一种色彩模式,mode 的取值可以是如下几种:
· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)
怎么样,够丰富吧?其实如此之处,PIL 还有限制地支持以下几种比较少见的色彩模式:LA (L with alpha), RGBX (true colour with padding) and RGBa (true colour with premultiplied alpha)。
下面看一下 mode 为 ‘1’、’L’、’P’时转换出来的图像:
2 mode = '1'
3 mode = 'L'
4 mode = 'P'
convert() 函数也接受另一个隐含参数 matrix,转换矩阵 matrix 是一个长度为4 或者16 tuple。下例是一个转换 RGB 空间到 CIE XYZ 空间的例子:
    rgb2xyz = (
        0.412453, 0.357580, 0.180423, 0,
        0.212671, 0.715160, 0.072169, 0,
        0.019334, 0.119193, 0.950227, 0 )
    out = im.convert("RGB", rgb2xyz)
       除了完备的色彩空间转换能力外, PIL 还提供了resize()、rotate()等函数以获得改变大小,旋转图片等几何变换能力,在图像识别方面,图像实例提供了一个 histogram() 方法来计算直方图,非常方便实用。
图像增强
       图像增强通常用以图像识别之前的预处理,适当的图像增强能够使得识别过程达到事半功倍的效果。 PIL 在这方面提供了一个名为 ImageEnhance 的模块,提供了几种常见的图像增强方案:
import ImageEnhance
enhancer = ImageEnhance.Sharpness(image)
for i in range(8):
    factor = i / 4.0
    enhancer.enhance(factor).show("Sharpness %f" % factor)
上面的代码即是一个典型的使用 ImageEnhance 模块的例子。 Sharpness 是 ImageEnhance 模块的一个类,用以锐化图片。这一模块主要包含如下几个类:Color、Brightness、Contrast和Sharpness。它们都有一个共同的接口 .enhance(factor) ,接受一个浮点参数 factor,标示增强的比例。下面看看这四个类在不同的 factor 下的效果
5 使用Color 进行色彩增强,factor 取值 [0, 4],步进 0.5
6 用 Birghtness 增强亮度,factor取值[0,4],步进0.5
7用 Contrast 增强对比度, factor 取值 [0,4],步进0.5
8用 Sharpness 锐化图像,factor取值 [0,4],步进0.5
图像 Filter
       PIL 在 Filter 方面的支持是非常完备的,除常见的模糊、浮雕、轮廓、边缘增强和平滑,还有中值滤波、ModeFilter等,简直方便到可以做自己做一个Photoshop。这些 Filter 都放置在 ImageFilter 模块中,ImageFilter主要包括两部分内容,一是内置的 Filter,如 BLUR、DETAIL等,另一部分是 Filter 函数,可以指定不同的参数获得不同的效果。示例如下:
import ImageFilter
im1 = im.filter(ImageFilter.BLUR)
im2 = im.filter(ImageFilter.MinFilter(3))
im3 = im.filter(ImageFilter.MinFilter()) # same as MinFilter(3)
可以看到 ImageFilter 模块的使用非常简单,每一个 Filter 都只需要一行代码就可调用,开发效率非常高。
 
9使用 BLUR
10使用 CONTOUR
11使用 DETAIL
12使用 EMBOSS
13使用 EDGE_ENHANCE
14使用 EDGE_ENHANCE_MORE
15使用 FIND_EDGES
16使用 SHARPEN
17使用 SMOOTH
18使用 SMOOTH_MORE
       以上是几种内置的 Filter 的效果图,除此之外, ImageFilter 还提供了一些 Filter 函数,下面我们来看看这些可以通过参数改变行为的 Filter 的效果:
19使用 Kernel(),参数:size = (3, 3), kernel = (0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5)
20使用 MaxFilter,默认参数
21使用 MinFilter,默认参数
22使用 MedianFilter,默认参数
23使用 ModeFilter,参数 size = 3
24使用 RankFilter,参数 size = 3, rank = 3
小结
       到此,对 PIL 的介绍就告一段落了。总的来说,对于图像处理和识别,PIL 内建了强大的支持,从各种增强算法到 Filter ,都让人无法怀疑使用 Python 的可行性。 Python唯一的劣势在于执行时间过慢,特别是当实现一些计算量大的算法时候,需要极强的耐心。我曾用 Hough Transform(霍夫变换)来查找图像中的直线,纯 Python 的实现处理一个 340 * 100 的图片也要花去数秒时间(P4 3.0G + 1G memory)。但使用 PIL 无需关注图像格式、内建的图像增强算法和 Filter 算法,这些优点使 Python 适合用于构造原型和进行实验,在这两方面Python 比 matlab 更加方便。商业的图像识别产品开发,可以考虑已经被 boost accepted的来自 adobe 的开源 C++ 库 gil,可以兼顾执行性能和开发效率。

Python与图像处理5

阅读数 1394

没有更多推荐了,返回首页