7/27opencv-python学习笔记

对比度增强

限制对比度自适应直方图均衡化

相比全局直方图均衡化,自适应直方图均衡化将图像划分为不重叠的小块,在每一小块进行直方图均衡化,但若小块内有噪声,影响很大,需要通过限制对比度来进行抑制,即限制对比度自适应直方图均衡化。如果限制对比度的阈值设置会40,在局部直方图分布中某个像素值出现次数为45,那么多出的5次像素点会被去掉,平均成其他像素值,如图所示:
在这里插入图片描述
opencv通过createCLAHE()和apply()函数来实现,其对应参数如下:

clahe=cv2.createCLAHE(clipLimit,tileGridSize)
        clipLimit:限制对比度的阈值,默认为40,
                  直方图中像素值出现次数大于该阈值,
                  多余的次数会被重新分配
        tileGridSize:图像会被划分的size, 
                     如tileGridSize=(8,8),默认为(8,8)
    
calhe.apply(img) #对img进行限制对比度自适应直方图均衡化

注意:
1.全局直方图均衡化可能得到是一种全局意义上的均衡化,但是有的时候这种操作并不是很好,会把某些不该调整的部分给调整了。Opencv中还有一种直方图均衡化,它是一种局部直方图均衡化,也就是是说把整个图像分成许多小块(比如按10*10作为一个小块),那么对每个小块进行均衡化。

2.createCLAHE函数原型:createCLAHE([, clipLimit[, tileGridSize]]) -> retval

clipLimit参数表示对比度的大小。

tileGridSize参数表示每次处理块的大小 。

clahe = cv.createCLAHE(5, (8,8))
dst = clahe.apply(gray) #猜测:把clahe这种局部直方图均衡化应用到灰度图gray
代码示例和效果如下:(实际使用中可以先去噪声,再进行对比度增强)

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import math
img = cv.imread(r"D:\7271.png",0)
clahe = cv.createCLAHE(3,(8,8))
dst = clahe.apply(img)
cv.imshow("img",img)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

图像平滑

由于种种原因,图像中难免会存在噪声,需要对其去除。噪声可以理解为灰度值的随机变化,即拍照过程中引入的一些不想要的像素点。噪声可分为椒盐噪声,高斯噪声,加性噪声和乘性噪声等。
参见:https://zhuanlan.zhihu.com/p/52889476
椒盐噪声也称为脉冲噪声,是图像中经常见到的一种噪声,它是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)。椒盐噪声的成因可能是影像讯号受到突如其来的强烈干扰而产生、类比数位转换器或位元传输错误等。例如失效的感应器导致像素值为最小值,饱和的感应器导致像素值为最大值。
噪声主要通过平滑进行抑制和去除,包括基于二维离散卷积的高斯平滑,均值平滑,基于统计学的中值平滑,以及能够保持图像边缘的双边滤波,导向滤波算法等。下面介绍其具体使用

二维离散卷积

理解卷积:

             https://www.zhihu.com/question/22298352/answer/637156871
             https://www.zhihu.com/question/22298352/answer/228543288

图像可以表示为矩阵形式(下图摘自知乎马同学的文章):
在这里插入图片描述
对图像的处理函数(如平滑,或者边缘提取),也可以用一个g矩阵来表示,如:
在这里插入图片描述
注意,我们在处理平面空间的问题,已经是二维函数了,相当于:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
从卷积定义来看,应该是在x和y两个方向去累加(对应上面离散公式中的i和j两个下标),而且是无界的,从负无穷到正无穷。可是,真实世界都是有界的。例如,上面列举的图像处理函数g实际上是个3x3的矩阵,意味着,在除了原点附近以外,其它所有点的取值都为0。考虑到这个因素,上面的公式其实退化了,它只把坐标(u,v)附近的点选择出来做计算了。所以,真正的计算如下所示:
在这里插入图片描述
首先我们在原始图像矩阵中取出(u,v)处的矩阵:
在这里插入图片描述
然后将图像处理矩阵翻转(这个翻转有点意思,可以有几种不同的理解,其效果是等效的:(1)先沿x轴翻转,再沿y轴翻转;(2)先沿x轴翻转,再沿y轴翻转;),如下:

原始矩阵:
在这里插入图片描述
翻转后的矩阵:
在这里插入图片描述
在这里插入图片描述
请注意,以上公式有一个特点,做乘法的两个对应变量a,b的下标之和都是(u,v),其目的是对这种加权求和进行一种约束。这也是为什么要将矩阵g进行翻转的原因。以上矩阵下标之所以那么写,并且进行了翻转,是为了让大家更清楚地看到跟卷积的关系。这样做的好处是便于推广,也便于理解其物理意义。实际在计算的时候,都是用翻转以后的矩阵,直接求矩阵内积就可以了。
以上计算的是(u,v)处的卷积,延x轴或者y轴滑动,就可以求出图像中各个位置的卷积,其输出结果是处理以后的图像(即经过平滑、边缘提取等各种处理的图像)。
再深入思考一下,在算图像卷积的时候,我们是直接在原始图像矩阵中取了(u,v)处的矩阵,为什么要取这个位置的矩阵,本质上其实是为了满足以上的约束。因为我们要算(u,v)处的卷积,而g矩阵是3x3的矩阵,要满足下标跟这个3x3矩阵的和是(u,v),只能是取原始图像中以(u,v)为中心的这个3x3矩阵,即图中的阴影区域的矩阵。推而广之,如果如果g矩阵不是3x3,而是7x7,那我们就要在原始图像中取以(u,v)为中心的7x7矩阵进行计算。由此可见,这种卷积就是把原始图像中的相邻像素都考虑进来,进行混合。相邻的区域范围取决于g矩阵的维度,维度越大,涉及的周边像素越多。而矩阵的设计,则决定了这种混合输出的图像跟原始图像比,究竟是模糊了,还是更锐利了。
比如说,如下图像处理矩阵将使得图像变得更为平滑,显得更模糊,因为它联合周边像素进行了平均处理:
在这里插入图片描述
而如下图像处理矩阵将使得像素值变化明显的地方更为明显,强化边缘,而变化平缓的地方没有影响,达到提取边缘的目的:
在这里插入图片描述

学习图像平滑前,有必要了解下卷积的知识,看完上述内容,对于图像处理中卷积应该了解几个关键词:卷积核,锚点,步长,内积,卷积模式.。
卷积核(kernel):用来对图像矩阵进行平滑的矩阵,也称为过滤器(filter)
锚点:卷积核和图像矩阵重叠,进行内积运算后,锚点位置的像素点会被计算值取代。一般选取奇数卷积核,其中心点作为锚点
步长:卷积核沿着图像矩阵每次移动的长度
内积:卷积核和图像矩阵对应像素点相乘,然后相加得到一个总和,如下图所示。(不要和矩阵乘法混淆)
在这里插入图片描述
卷积模式:卷积有三种模式,FULL, SAME,VALID,实际使用注意区分使用的那种模式。(参考:https://zhuanlan.zhihu.com/p/62760780)
Full:全卷积,full模式的意思是,从filter和image刚相交开始做卷积,白色部分为填0,橙色部分为image, 蓝色部分为filter,filter的运动范围如图所示。
在这里插入图片描述
Same卷积:当filter的锚点(K)与image的边角重合时,开始做卷积运算,可见filter的运动范围比full模式小了一圈,same mode为full mode 的子集,即full mode的卷积结果包括same mode。
在这里插入图片描述
valid卷积:当filter全部在image里面的时候,进行卷积运算,可见filter的移动范围较same更小了,同样valid mode为same mode的子集。valid mode的卷积计算,填充边界中的像素值不会参与计算,即无效的填充边界不影响卷积,所以称为valid mode。
在这里插入图片描述
python的scipy包中提供了convolve2d()函数来实现卷积运算,其参数如下:

from scipy import signal

signal.convolve2d(src,kernel,mode,boundary,fillvalue)
    
src: 输入的图像矩阵,只支持单通的(即二维矩阵)
kernel:卷积核
mode:卷积类型:full, same, valid
boundary:边界填充方式:fill,wrap, symm
fillvalue: 当boundary为fill时,边界填充的值,默认为0

opencv中提供了flip()函数翻转卷积核,filter2D进行same 卷积, 其参数如下:

dst = cv2.flip(src,flipCode)
        src: 输入矩阵
        flipCode:0表示沿着x轴翻转,1表示沿着y轴翻转,-1表示分别沿着x轴,y轴翻转
        dst:输出矩阵(和src的shape一样)
    
    cv2.filter2D(src,dst,ddepth,kernel,anchor=(-1,-1),delta=0,borderType=cv2.BORDER_DEFAULT)
        src: 输入图像对象矩阵
        dst:输出图像矩阵
        ddepth:输出矩阵的数值类型
        kernel:卷积核
        anchor:卷积核锚点,默认(-1,-1)表示卷积核的中心位置
        delat:卷积完后相加的常数
        borderType:填充边界类型

边缘提取

边缘提取,指数字图像处理中,对于图片轮廓的一个处理。对于边界处,灰度值变化比较剧烈的地方,就定义为边缘。也就是拐点,拐点是指函数发生凹凸性变化的点。二阶导数为零的地方。并不是一阶导数,因为一阶导数为零,表示是极值点。
边缘提取:边缘检测的基本思想首先是利用边缘增强算子,突出图像中的局部边缘,然后定义象素的“边缘强度”,通过设置阈值的方法提取边缘点集。由于噪声和模糊的存在,监测到的边界可能会变宽或在某点处发生间断。因此,边界检测包括两个基本内容: (1)用边缘算子提取出反映灰度变化的边缘点集。 (2)在边缘点集合中剔除某些边界点或填补边界间断点,并将这些边缘连接成完整的线。
边缘定义:图像灰度变化率最大的地方(图像灰度值变化最剧烈的地方)。图像灰度在表面法向变化的不连续造成的边缘。一般认为边缘提取是要保留图像的灰度变化剧烈的区域,这从数学上看,最直观的方法就是微分(对于数字图像来说就是差分),在信号处理的角度来看,也可以说是用高通滤波器,即保留高频信号。
边缘信息包含两个方面:1.像素的坐标2.边缘的方向

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值