做建网站的公司,手机网站快速排名,太平洋在线建站系统,和田做网站的联系电话引言
本文是使用python进行图像基本处理系列的第三部分#xff0c;在本人之前的文章里介绍了一些非常基本的图像分析操作#xff0c;见文章《使用Numpy和Opencv完成图像的基本数据分析Part I》和《使用Numpy和Opencv完成图像的基本数据分析 Part II》#xff0c;下面我们将…
引言
本文是使用python进行图像基本处理系列的第三部分在本人之前的文章里介绍了一些非常基本的图像分析操作见文章《使用Numpy和Opencv完成图像的基本数据分析Part I》和《使用Numpy和Opencv完成图像的基本数据分析 Part II》下面我们将继续介绍一些有关图像处理的好玩内容。
本文介绍的内容基本反映了我本人学习的图像处理课程中的内容并不会加入任何工程项目中的图像处理内容本文目的是尝试实现一些基本图像处理技术的基础知识出于这个原因本文继续使用 SciKit-Image,numpy数据包执行大多数的操作此外还会时不时的使用其他类型的工具库比如图像处理中常用的OpenCV等
本系列分为三个部分分别为part I、part II以及part III。刚开始想把这个系列分成两个部分但由于内容丰富且各种处理操作获得的结果是令人着迷因此不得不把它分成三个部分。系列所有的源代码地址GitHub-Image-Processing-Python。
在上一篇文章中我们已经完成了以下一些基本操作。为了跟上今天的内容回顾一下之前的基本操作
导入图像并观察其属性拆分图层灰度处理对像素值使用逻辑运算符使用逻辑运算符进行掩码
现在开始本节的内容
强度变换|Intensity Transformation
首先导入一张图像作为开始
%matplotlibinlineimport imageio
import matplotlib.pyplot as plt
import warnings
import matplotlib.cbook
warnings.filterwarnings(ignore,categorymatplotlib.cbook.mplDeprecation)picimageio.imread(img/parrot.jpg)plt.figure(figsize(6,6))
plt.imshow(pic);
plt.axis(off); 图像底片|Image Negative
强度变换函数在数学上定义为
S T(r)
其中r是输入图像的像素S是输出图像的像素T是一个转换函数它将r的每个像素值映射到s中对应的像素值。 负变换即恒等变换的逆。在负变换中输入图像的每个像素值从L-1中减去并映射到输出图像上。 在这种情况下完成以下转换
S (L-1)-r
因此每个像素值都减去255。这样的操作导致的结果是较亮的像素变暗较暗的图像变亮类似于图像底片。
negative 255- pic # neg (L-1) - imgplt.figure(figsize (6,6))
plt.imshow(negative);
plt.axis(off); 对数变换|Log transformation
对数转换可以通过以下公式定义
s c *log(r 1)
其中s和r是输出和输入图像的像素值c是常数。输入图像的每个像素值都会加1之后再进行对数操作这是因为如果图像中的像素值为0时log(0)的结果等于无穷大。因此为了避免这种情况的发生输入图像中的每个像素值都加1使最小像素值至少为1。
在对数变换过程中与较高像素值相比图像中的低像素被扩展。较高的像素值在对数变换中被压缩这导致图像增强。
对数变换中的c值调整了我们想要的增强程度
%matplotlibinlineimport imageio
import numpyasnp
import matplotlib.pyplotaspltpicimageio.imread(img/parrot.jpg)
graylambdargb:np.dot(rgb[...,:3],[0.299,0.587,0.114])
graygray(pic)
log transform
- s c*log(1r)So, we calculate constant c to estimate s
- c (L-1)/log(1|I_max|)max_np.max(gray)def log_transform():
return(255/np.log(1max_))*np.log(1gray)plt.figure(figsize(5,5))
plt.imshow(log_transform(),cmapplt.get_cmap(namegray))
plt.axis(off);伽马校正| Gamma Correction
伽马校正或通常简称为伽玛是用于对视频或静止图像系统中的亮度或三刺激值进行编码和解码的非线性操作伽玛校正也称为幂律变换。首先图像的像素值大小范围必须从0~255被缩放至0~1.0。然后通过应用以下等式获得伽马校正后的输出图像
Vo Vi ^(1 / G)
其中Vi是我们的输入图像G是设置的伽玛值然后将输出图像Vo缩放回0-255范围。
对于伽马值而言G 1有时被称为编码伽玛并且利用该压缩幂律非线性进行编码的过程被称为伽马压缩 Gamma值小于1会将图像移向光谱的较暗端。
相反伽马值G 1被称为解码伽马并且膨胀幂律非线性的应用被称为伽马展开。Gamma值大于1将使图像显得更亮。将伽玛值设置为G 1时对输入图像没有影响
import imageio
import matplotlib.pyplotasplt# Gamma encoding
picimage io.imread(img/parrot.jpg)
gamma2.2# Gamma 1 ~ Dark ; Gamma 1 ~ Brightgamma_correction((pic/255)**(1/gamma))
plt.figure(figsize(5,5))
plt.imshow(gamma_correction)
plt.axis(off);伽马校正的原因|Reason for Gamma Correction
我们应用伽马校正的原因是由于我们的眼睛感知颜色和亮度这一过程与数码相机中的传感器的工作原理不同。当数码相机上的传感器获得两倍的光子量时信号会加倍。但是我们人类的眼睛的工作原理与这不同当我们的眼睛感知两倍的光量时视野中只有一小部分显得更亮。
因此数码相机在亮度之间具有线性关系而我们人类的眼睛具有非线性关系。为了解释这种关系我们应用伽玛校正。
还有一些其他的线性变换函数比如
对比度拉伸Contrast Stretching强度切片Intensity-Level Slicing位平面切片Bit-Plane Slicing
卷积|Convolution
在上一篇文章中对卷积操作作了简要讨论。当计算机看到图像时它看到不是一整幅图像它的眼里看到的只是一个像素值数组。假设读取一个32X32大小的彩色图像根据图像的分辨率和大小计算机它将看到一个32 x 32 x 3维的数字数组其中3表示RGB值或三通道。
假设现在我们有一个PNG格式的彩色图像它的大小是480 x 480。将其读入后其表示数组将是480 x 480 x 3维。数组中的所有的每个数字值范围都在0到255之间它描述的是那个点的像素强度。
就像我们刚才提到的那样假设输入图像是一个32 x 32 x 3的像素值数组解释卷积的最佳方法是想象一个闪烁在图像左上方的手电筒。假设手电筒照射区域大小为3 x 3。
现在让我们假设这个手电筒滑过输入图像的所有区域。在机器学习术语中这个手电筒被称为过滤器filter或内核kernel或者有时被称为权重weights 或 掩模mask它所照射的区域称为 感受野receptive field。
现在此过滤器也是一个数字数组数组中的数字称为权重或参数在这里要着重注意一点此过滤器的深度必须与输入图像的深度相同即通道数相同因此此过滤器的尺寸为3 x 3 x 3。
图像内核 或过滤器是一个小矩阵用于应用我们可能在Photoshop或Gimp中找到的效果例如模糊、锐化、轮廓或浮雕等。此外它们还被用于在机器学习中进行图像特征提取CNN这是一种用于确定图像最重要部分的技术。更多相关信息请查看Gimp关于使用Image kernel的文档我们可以该文档中找到最常见的内核列表 。
现在让我们将过滤器放在图像的左上角。当滤波器围绕输入图像滑动或卷积时它将滤波器中的值乘以图像的原始像素值也称为计算元素乘法。这些乘法操作最后都会求和所以卷积操作后只得到一个数字值。请记住此数字仅代表过滤器位于图像的左上角。
现在我们对输入图像上的每个位置重复此过程移动过滤器使其与图像矩阵的每个像素值进行卷积操作这个过程需要设置移动步幅依此类推完成整幅图像的卷积操作。输入图中的每个唯一位置都会生成一个数字。步幅的取值一般为1也可以取其它大小的值但我们关心的是它是否适合输入图像。 过滤器滑过输入图像上的所有位置后我们会发现我们剩下的是一个30 x 30 x 1的数组我们将其称为激活图 或特征图。将3 x 3过滤器可以放在32 x 32输入图像上可以得到30 x 30大小的阵列原因是有300个不同的位置这900个数字映射到30 x 30阵列。我们可以通过以下方式计算卷积图像后图像的大小
卷积(N-F)/ S 1
其中N和F分别代表输入图像大小和卷积核大小S代表步幅或步长。因此对于上述情况输出图像的大小将是
32-31 1 30
假设我们有一个3x3滤波器在5x5大小的矩阵上进行卷积根据等式我们应该得到一个3x3矩阵现在让我们看一下 此外我们实际上使用的过滤器不止一个过滤器的数量自己设定假设过滤器的数量设置为n则我们的输出将是28x28xn大小其中n是特征图的数量 。
通过使用更多的过滤器我们能够更好地保留空间维度信息。
然而对于图像矩阵边界上的像素卷积核的一些元素移动时会出现在图像矩阵之外因此不具有来自图像矩阵的任何对应元素。在这种情况下我们可以消除这些位置的卷积运算最终输出矩阵大小将会小于输入图像或者我们可以对输入图像矩阵进行填充padding以保证输出图像大小维度不变。
为了保持本系列的简洁而保持内容的完整性本文提供了全部的资源链接在其中更详细地解释了有关内容。
下面让我们首先将一些自定义卷积核个数的窗口应用于图像中这可以通过平均每个像素值与附近的像素值来处理图像
%%time
import numpy as np
import imageio
import matplotlib.pyplot as plt
from scipy.signal import convolve2ddef Convolution(image, kernel):
conv_bucket []
for d in range(image.ndim):
conv_channel convolve2d(image[:,:,d], kernel, modesame, boundarysymm)
conv_bucket.append(conv_channel)
returnnp.stack(conv_bucket, axis2).astype(uint8)kernel_sizes [9,15,30,60]
fig, axsplt.subplots(nrows1, ncolslen(kernel_sizes), figsize(15,15));pic imageio.imread(img:/parrot.jpg)for k, ax in zip(kernel_sizes, axs):kernel np.ones((k,k))kernel /np.sum(kernel)
ax.imshow(Convolution(pic, kernel));
ax.set_title(Convolved By Kernel: {}.format(k));
ax.set_axis_off();
Wall time: 43.5 s更多内容可以在此查看其中已经深入讨论了各种类型的内核并展示了它们之间的差异。
原文链接 本文为云栖社区原创内容未经允许不得转载。