OpenCV学习<一>
二.图像处理
2.1灰度图和HSV 颜色空间
import cv2
import matplotlib.pyplot as plt
import numpy as np
img=cv2.imread('../photo/cat.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow("img_gray",img_gray)
cv2.imshow("img_hsv",img_hsv)
while cv2.waitKey(0) != -1 :
cv2.destroyAllWindows()
cv2.imwrite('../save/cat_2_1_img_gray.jpg',img_gray)
cv2.imwrite('../save/cat_2_1_img_hsv.jpg', img_hsv)
break
2.1.1灰度图
相较于彩色图而言,使用灰度图最直接的原因就是减少计算量,包含色彩的图片,特征量,计算量会成指数倍数增加,比如一个点,灰度的话,就256个维度而已,但是如果算上RGB色彩的话,那就是1600万以上维度。
函数: cv.cvtColor(img,type)
作用:将图像从一个色彩空间转换为另一个色彩空间。
参数:img:处理的图像
type:转换的类型,灰度图为COLOR_BGR2GRAY
![](https://i-blog.csdnimg.cn/blog_migrate/0b18aab9dd336111a05e132dfec4a800.png)
![](https://i-blog.csdnimg.cn/blog_migrate/89f0b8d7e345ab2c8b4808a0381d9e82.png)
2.1.2HSV颜色空间
函数: cv.cvtColor(img,type)
作用:将图像从一个色彩空间转换为另一个色彩空间。
参数:img:处理的图像
type:转换的类型,HSV图为COLOR_BGR2HSV
![](https://i-blog.csdnimg.cn/blog_migrate/b23c504b2dbb01d51326b77a982f8d7f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c3988d384f2e00dad8963d380e5b9801.png)
在 HSV 颜色空间下,比 BGR 更容易跟踪某种颜色的物体,常用于分割指定颜色的物体。
HSV 表达彩色图像的方式由三个部分组成:
Hue(色调、色相)
Saturation(饱和度、色彩纯净度)
Value(明度)
用下面这个圆柱体来表示 HSV 颜色空间,圆柱体的横截面可以看做是一个极坐标系 ,H 用极坐标的极角表示,S 用极坐标的极轴长度表示,V 用圆柱中轴的高度表示。
![](https://i-blog.csdnimg.cn/blog_migrate/03742d8a229d455dcdba41c05686fb4e.jpeg)
Hue 用角度度量,取值范围为0~360°,表示色彩信息,即所处的光谱颜色的位置。,表示如下:
![](https://i-blog.csdnimg.cn/blog_migrate/a35f84d0e3cb379748f35c64f7c0ab2d.jpeg)
颜色圆环上所有的颜色都是光谱上的颜色,从红色开始按逆时针方向旋转,Hue=0 表示红色,Hue=120 表示绿色,Hue=240 表示蓝色等等。
在 GRB中 颜色由三个值共同决定,比如黄色为即 (255,255,0);在HSV中,黄色只由一个值决定,Hue=60即可。
HSV 圆柱体的半边横截面(Hue=60):
![](https://i-blog.csdnimg.cn/blog_migrate/5ec91f7dd519efecb00ae854ec7effc3.jpeg)
其中水平方向表示饱和度,饱和度表示颜色接近光谱色的程度。饱和度越高,说明颜色越深,越接近光谱色饱和度越低,说明颜色越浅,越接近白色。饱和度为0表示纯白色。取值范围为0~100%,值越大,颜色越饱和。
竖直方向表示明度,决定颜色空间中颜色的明暗程度,明度越高,表示颜色越明亮,范围是 0-100%。明度为0表示纯黑色(此时颜色最暗)。
可以通俗理解为:
在Hue一定的情况下,饱和度减小,就是往光谱色中添加白色,光谱色所占的比例也在减小,饱和度减为0,表示光谱色所占的比例为零,导致整个颜色呈现白色。
明度减小,就是往光谱色中添加黑色,光谱色所占的比例也在减小,明度减为0,表示光谱色所占的比例为零,导致整个颜色呈现黑色。
2.2图像阈值处理和图像平滑处理
import cv2
import matplotlib.pyplot as plt
import numpy as np
img=cv2.imread('../photo/cat.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
2.2.1图像阈值处理
函数:ret,dst = cv2.threshold(src,thresh,maxval,type)
作用:阈值分割是一种广泛应用的分割技术,利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域 (目标区域和背景区域)的组合,选取一个比较合理的阈值,以确定图像中每个像素点应该属于目标区域还是背景区域,从而产生相应的二值图像。
参数:
src: 输入图,只能输入单通道图像,通常来说为灰度图
dst: 输出图
thresh: 阈值
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
cv2.THRESH_BINARY_INV THRESH_BINARY的反转
cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
![](https://i-blog.csdnimg.cn/blog_migrate/63473b2b2deaa790b51fb1f85ef4d1ab.png)
2.2.2图像平滑处理
2.2.2.1均值滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../photo/lenaNoise.png')
img_blur = cv2.blur(img,(3,3))
cv2.imshow('img', img)
cv2.imshow('img_blur', img_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
函数:result = cv2.blur(src,ksize)
作用:使用规范化框滤镜模糊图像。该函数使用内核平滑图像,实际上就是模糊处理图像
参数:src:处理的图像
ksize:表示核大小。核必须是大于1的奇数,如3、5、7等。
![](https://i-blog.csdnimg.cn/blog_migrate/34cdadd08219d7ad96751bf5fbf6e13d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9ebff10fc9df3c071b8b78b3f6b9f6a9.png)
均值滤波是指任意一点的像素值,都是周围
![](https://i-blog.csdnimg.cn/blog_migrate/ca5c7ff6701a4a450935deaf41f9f6f5.gif)
个像素值的均值。例如下图中,红色点的像素值是其周围蓝色背景区域像素值之和除25,25=5x5 是蓝色区域的大小。
![](https://i-blog.csdnimg.cn/blog_migrate/8ee1d68b0628e87f233c452801564c14.png)
均值滤波详细的计算方法如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/49f32399fa7971cc75226dddb03e7fef.png)
其中5x5的矩阵称为核,针对原始图像内的像素点,采用核进行处理,得到结果图像,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/428f5d9ac47b51e34653445c6704b1d7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1942386932c59e8d35e6e2c3b0fd0bf7.png)
提取 1/25 可以将核转换为如下形式:
![](https://i-blog.csdnimg.cn/blog_migrate/7ba5035c8a50fba2f49b49b702740870.png)
2.2.2.2中值滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../photo/lenaNoise.png')
img_medianBlur = cv2.medianBlur(img,3)
cv2.imshow('img', img)
cv2.imshow('img_medianBlur', img_medianBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()
函数:dst = cv2.medianBlur(src,ksize)
作用:使用规范化框滤镜模糊图像。该函数使用内核平滑图像,实际上就是模糊处理图像
参数:src :表示源图像;
ksize :表示核大小。核必须是大于1的奇数,如3、5、7等。
在使用邻域平均法去噪的同时也使得边界变得模糊。而中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。选一个含有奇数点的窗口
![](https://i-blog.csdnimg.cn/blog_migrate/9af12de8e2fdabfa7a4e5fc68618ede3.gif)
,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。计算过程如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/9c7a4e5242c6a6a4ea025167a8fb069e.png)
2.2.2.3高斯滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../photo/lenaNoise.png')
img_GaussianBlur = cv2.GaussianBlur(img,(3,3),0)
cv2.imshow('img', img)
cv2.imshow('img_GaussianBlur', img_GaussianBlur)
cv2.waitKey(0)
cv2.destroyAllWindows()
函数:dst = cv2.GaussianBlur(src, ksize, sigmaX)
作用:使用规范化框滤镜模糊图像。该函数使用内核平滑图像,实际上就是模糊处理图像
参数:
src: 表示原始图像;
ksize: 表示核大小;
sigmaX: 表示X方向方差。直接赋值0即可
![](https://i-blog.csdnimg.cn/blog_migrate/1b2d79a0f35f952682a5f67f4903284d.png)
注:核大小(N, N)必须是奇数,X方向方差主要控制权重。
1)核大小为 3x3
![](https://i-blog.csdnimg.cn/blog_migrate/6a5808adaab9c432d906d72b6bf229aa.gif)
2)核大小为 5x5
![](https://i-blog.csdnimg.cn/blog_migrate/68f4c383786ab267cb70050bbd65a129.gif)
为了克服简单局部平均法的弊端(图像模糊),目前已提出许多保持边缘、细节的局部平滑算法。它们的出发点都集中在如何选择邻域的大小、形状和方向、参数加平均及邻域各店的权重系数等。
图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的权重。高斯平滑与简单平滑不同,它在对邻域内像素进行平均时,给予不同位置的像素不同的权值,下图的所示的 3x3 和 5x5 邻域的高斯模板。
(1)核大小为 3x3
![](https://i-blog.csdnimg.cn/blog_migrate/31f3645c144a44a42ea0471075920120.gif)
(1)核大小为 5x5
![](https://i-blog.csdnimg.cn/blog_migrate/ddbcd47fa327b839b75a446d4647e7e0.gif)
高斯滤波让临近的像素具有更高的重要度,对周围像素计算加权平均值,较近的像素具有较大的权重值。如下图所示,中心位置权重最高为0.4。
![](https://i-blog.csdnimg.cn/blog_migrate/e7e1ac5773e96a85997e872029b8c447.png)
2.2.2.4方框滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('../photo/lenaNoise.png')
img_boxFilter = cv2.boxFilter(img,-1,(3,3),1)
cv2.imshow('img', img)
cv2.imshow('img_boxFilter', img_boxFilter)
cv2.waitKey(0)
cv2.destroyAllWindows()
函数:dst = cv2.boxFilter( src, ddepth, ksize, anchor, normalize, borderType )
作用:使用规范化框滤镜模糊图像。该函数使用内核平滑图像,实际上就是模糊处理图像
参数:
dst:返回值,表示经过方框滤波处理后的结果。
src:需要被处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。图像深度可以是 CV_8U、 CV_16U、CV_16S、CV_32F 或者 CV_64F 中的一种。
ddepth:处理后结果图像的深度,一般使用-1表示与原始图像使用相同的图像深度。
ksize:滤波核的大小。滤波核大小是指在滤波处理过程中所选择的邻域图像的高度和宽度。例如,滤波核的值可以为(3,3),表示以3×3大小的邻域均值作为图像均值滤波处理的结果,如下图2-1所示。
![](https://i-blog.csdnimg.cn/blog_migrate/1c0c155135967010c937392cb09c8805.png)
图2-1 3×3大小的滤波核
anchor:锚点,默认值为(-1, -1),表示当前计算均值的点位于核的中心点位置。该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
normalize:表示在滤波时是否进行归一化(这里指将计算结果规范化为当前像素值范围内的值)处理,该参数是一个逻辑值,可能为真(值为 1)或假(值为 0)
当参数normalize=0时,表示不需要进行归一化处理,直接使用邻域像素值的和。
当参数normalize=1时,表示要进行归一化处理,要用邻域像素值的和除以面积。
![](https://i-blog.csdnimg.cn/blog_migrate/8533644287f68b7cfa80e8a2f8985e4a.png)
与均值滤波不同的是,方框滤波不会计算像素的均值。在均值滤波中,滤波结果的像素值是任意一个点的邻域平均值,等于各邻域像素值之和除以邻域面积。而在方框滤波中,可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。
以5×5的邻域为例,在进行方框滤波时,如果计算的是邻域像素值的均值,则滤波关系如图1-1所示;如果计算的是邻域像素值之和,则滤波关系如图1-2所示。
![](https://i-blog.csdnimg.cn/blog_migrate/0d95b8b2a8f4b9e3e0e98dee69eb839a.png)
图1-1 方框滤波关系示例–计算邻域像素值均值
![](https://i-blog.csdnimg.cn/blog_migrate/2775e4f0eb2a0c7bef4ce1d2249020c0.png)
图1-2 方框滤波关系示例–计算邻域像素值之和
根据上述关系,如果计算的是领域像素值的均值,则使用的卷积核如图1-3所示
![](https://i-blog.csdnimg.cn/blog_migrate/638df1c3f02949faf2cc050f8c539385.png)
图1-3 计算邻域像素值均值所用的卷积核示例
如果计算的是邻域像素值之和,则使用的卷积核如图1-4所示:
![](https://i-blog.csdnimg.cn/blog_migrate/6fbc89d8783dbe1223d55cdcbdd6eedc.png)
图1-4 计算邻域像素值之和所用的卷积核示例