opencv基础函数(2)

OpenCv图像的几何变换

  • cv2.resize实现图像的缩放和大小变换
cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) -> dst
#scr:变换操作的输入图像
#dsize: 输出图像的大小,二元元组 (width, height)
#dst:变换操作的输出图像,可选项
#fx, fy:x 轴、y 轴上的缩放比例,实型,可选项
#interpolation:插值方法,整型,可选项
#cv2.INTER_LINEAR:双线性插值(默认方法)
#cv2.INTER_AREA:使用像素区域关系重采样,缩小图像时可以避免波纹出现
#cv2.INTER_NEAREST:最近邻插值
#cv2.INTER_CUBIC:4x4 像素邻域的双三次插值
#cv2.INTER_LANCZOS4:8x8 像素邻域的Lanczos插值
#返回值:dst,变换操作的输出图像,ndarray 多维数组
  • cv2.flip将图像沿水平方向、垂直方向、或水平/垂直方向同时进行翻转
cv2.flip(src, flipCode[, dst]) -> dst
#scr:变换操作的输入图像
#flipCode:控制参数,整型(int),flipCode>0 水平翻转,
#flipCode=0 垂直翻转,flipCode<0 水平和垂直翻转
#dst:变换操作的输出图像,可选项
  • cv2.warpAffine图像的仿射变换
    仿射变换:从一个二维坐标系变换到另一个二维坐标系,属于线性变换。通过已知3对坐标点可以求得变换矩阵
    仿射变换(Affine Transformation)是指在向量空间中进行一次线性变换(乘以一个矩阵)和一次平移(加上一个向量),变换到另一个向量空间的过程
    仿射变换代表的是两幅图之间的映射关系,仿射变换矩阵为2x3的矩阵,如下图中的矩阵M,其中的B起着平移的作用,而A中的对角线决定缩放,反对角线决定旋转或错切
    公式推导1
    原像素点坐标(x,y),经过仿射变换后的点的坐标是T,则矩阵仿射变换基本算法原理:
    公式推导2
    所以仿射变换是一种二维坐标(x,y)到二维坐标(u,v)之间的线性变换,其数学表达式如下:
    公式推导3
    这个矩阵是2×3的,但是这会改变原始图像的维度,为此,增加一个维度,构造齐次变换矩阵3×3
    公式推导4
    这就保持了图像的平直性和平行性
    平直性:直线、圆弧不变
    平行性:平行关系不变,直线相对位置不变,但是夹角可能会改变
    仿射变化需要一个转换矩阵,但是由于仿射变换比较复杂,一般很难直接找到这个矩阵,opencv提供了根据源图像和目标图像上三个对应的点来自动创建变换矩阵,矩阵维度为 2x3
    这个函数是:cv2.getAffineTransform(pos1,pos2)
    最后这个矩阵会被传给函数 cv2.warpAffine()来实现仿射变换
#pts1和pts2包含在原图像和目标图像上各选择三个点
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[50, 100], [200, 50], [100, 250]])
MA = cv2.getAffineTransform(pts1, pts2)#计算变换矩阵MA
dst = cv2.warpAffine(img, MA, (width,height))#实现仿射变换

补充:使用cv2.warpAffine也可以完成图像的平移和旋转,使用方法略

  • cv2.warpPerspective图像的投影变换
pointSrc = np.float32([[0,0], [w-1,0], [0,h-100], [w-1, h-100]])#原始图像中4点坐标
pointDst = np.float32([[180,50], [w-180,50], [0,h-100], [w-1, h-100]])#变换图像中4点坐标
MP = cv2.getPerspectiveTransform(pointSrc, pointDst)#计算投影变换矩阵M
imgP = cv2.warpPerspective(img, MP, (512, 512))#用变换矩阵M进行投影变换

cv2.getPerspectiveTransform根据图像中不共线的4个点在变换前后的对应位置求得(3x3)变换矩阵
cv2.warpPerspective使用该(3x3)变换矩阵即可求出变换后的图像

OpenCv图像的灰度变换与阈值处理

  • cv2.threshold对图像进行二值化处理
    函数 threshold() 可以将灰度图像转换为二值图像,图像完全由像素 0 和 255 构成,呈现出只有黑白两色的视觉效果
    灰度阈值化通过选取的灰度阈值 thresh,将每个像素的灰度值与阈值进行比较,将灰度大于阈值的像素点置为最大灰度,小于阈值的像素点置为最小灰度,得到二值图像,可以突出图像轮廓,把目标从背景中分割出来
cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dst
#scr:变换操作的输入图像,nparray 二维数组,必须是单通道灰度图像!
#thresh:阈值,取值范围 0~255
#maxval:填充色,取值范围 0~255,一般取 255
#type:变换类型:
#cv2.THRESH_BINARY:大于阈值时置 255,否则置 0
#cv2.THRESH_BINARY_INV:大于阈值时置 0,否则置 255
#cv2.THRESH_TRUNC:大于阈值时置为阈值 thresh,否则不变(保持原色)
#cv2.THRESH_TOZERO:大于阈值时不变(保持原色),否则置 0
#cv2.THRESH_TOZERO_INV:大于阈值时置 0,否则不变(保持原色)
#cv2.THRESH_OTSU:使用 OTSU 算法选择阈值
#返回值 retval:返回二值化的阈值
#返回值 dst:返回阈值变换的输出图像

注意:
1.函数 cv2.threshold 进行固定阈值的二值化处理;函数 cv2.adaptiveThreshold 为自适应阈值的二值化处理函数,可以通过比较像素点与周围像素点的关系动态调整阈值
2.确切地说,只有 type 为 cv2.THRESH_BINARY 或 cv2.THRESH_BINARY_INV 时输出为二值图像,其它变换类型时进行阈值处理但并不是二值处理

  • OTSU方法(大津算法)
    阈值处理本质上是对像素进行分类的统计决策问题。
    OTSU方法又称大津算法,使用最大化类间方差(intra-class variance)作为评价准则,基于对图像直方图的计算,可以给出类间最优分离的最优阈值。
    任取一个灰度值 T,可以将图像分割为两个集合 F 和 B,集合 F、B 的像素数的占比分别为 pF、pB,集合 F、B 的灰度值均值分别为 mF、mB,图像灰度值为 m,定义类间方差为: I C V = p F ∗ ( m F − m ) 2 + p B ​ ∗ ( m B ​ − m ) 2 ICV = pF∗(mF−m)^{2} + pB​∗(mB​−m)^{2} ICV=pF(mFm)2+pB(mBm)2
    使类间方差 ICV 最大化的灰度值 T 就是最优阈值。
    因此,只要遍历所有的灰度值,就可以得到使 ICV 最大的最优阈值 T。
    OpenCV 提供了函数 cv.threshold 可以对图像进行阈值处理,将参数 type 设为 cv.THRESH_OTSU,就可以使用使用 OTSU 算法进行最优阈值分割。

OpenCv图像滤波

  • 图像卷积
    在OpenCV中,允许用户自定义卷积核实现卷积操作,使用自定义卷积核实现卷积操作的函数是cv2.filter2D
dst=cv2.filter2D(src,ddepth,kernel,anchor,delta,borderType)
#dst是返回值,表示进行方框滤波后得到的处理结果。
#src是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。
#图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F或者CV_64F中的一种。
#ddepth是处理结果图像的图像深度,一般使用-1表示与原始图像使用相同的图像深度。
#kernel是卷积核,是一个单通道的数组。如果想在处理彩色图像时,
#让每个通道使用不同的核,则必须将彩色图像分解后使用不同的核完成操作。
#anchor是锚点,其默认值是(-1,-1),表示当前计算均值的点位于核的中心点位置。
#该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
#delta是修正值,它是可选项。如果该值存在,会在基础滤波的结果上加上该值作为最终的滤波处理结果。
#borderType是边界样式,该值决定了以何种情况处理边界,通常使用默认值即可。

在一般情况下,使用cv.filter2D时,对于参数锚点anchor,修正值delta,边界样式borderType,直接采用其默认值即可。

线性滤波
  • 均值滤波
    在OpenCV中,实现均值滤波的函数是cv2.blur
dst=cv2.blur(src,ksize,anchor,borderType)
#dst是返回值,表示进行均值滤波后得到的处理结果。
#src 是需要处理的图像,即原始图像。它可以有任意数量的通道,并能对各个通道独立处理。
#图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一种。
#ksize是滤波核的大小,指在均值处理过程中,其邻域图像的高度和宽度。
#需要注意,滤波核的宽度、高度应设为正奇数元组。
#anchor是锚点,其默认值是(-1,-1),表示当前计算均值的点位于核的中心点位置。
#该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
#borderType是边界样式,该值决定了以何种方式处理边界。
#一般情况下不需要考虑该值的取值,直接采用默认值即可。

通常情况下,使用均值滤波函数时,对于锚点anchor和边界样式borderType,直接采用其默认值即可。

  • 方框滤波
    在OpenCV中,实现方框滤波的函数是cv2.boxFilter
dst=cv2.boxFilter(src,ddepth,ksize,anchor,normalize,borderType)
#dst是返回值,表示进行方框滤波后得到的处理结果。
#src是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。
#图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一种。
#ddepth是处理结果图像的图像深度,一般使用-1表示与原始图像使用相同的图像深度。
#ksize是滤波核的大小,指在滤波处理过程中所选择的邻域图像的高度和宽度。
#需要注意,滤波核的宽度、高度应设为正奇数元组。
#anchor是锚点,其默认值是(-1,-1),表示当前计算均值的点位于核的中心点位置。
#该值使用默认值即可,在特殊情况下可以指定不同的点作为锚点。
#normalize 表示在滤波时是否进行归一化(这里指将计算结果规范化为当前像素值范围内的值)处理,
#该参数是一个逻辑值,可能为真(值为1)或假(值为0):
#1.当参数normalize=1时,表示要进行归一化处理,要用邻域像素值的和除以面积。
#此时方框滤波与均值滤波效果相同。
#2.当参数normalize=0时,表示不需要进行归一化处理,直接使用邻域像素值的和。
#当normalize=0时,因为不进行归一化处理,因此滤波得到的值很可能超过当前像素值范围的最大值,
#从而被截断为最大值。这样,就会得到一幅纯白色的图像。
#borderType是边界样式,该值决定了以何种方式处理边界。

通常情况下,在使用方框滤波函数时,对于参数anchor、normalize和borderType,直接采用其默认值即可。

  • 高斯滤波
    在OpenCV中,实现高斯滤波的函数是cv2.GaussianBlur
dst=cv2.GaussianBlur(src,ksize,sigmaX,sigmaY,borderType)
#dst是返回值,表示进行高斯滤波后得到的处理结果。
#src是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。
#图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一种。
#ksize是滤波核的大小,指在滤波处理过程中其邻域图像的高度和宽度。
#需要注意,滤波核的宽度、高度应设为正奇数元组。
#sigmaX是卷积核在水平方向上(X 轴方向)的标准差,其控制的是权重比例。
#sigmaY是卷积核在垂直方向上(Y轴方向)的标准差。如果将该值设置为0,则只采用sigmaX的值
#如果sigmaX和sigmaY都是0,则通过ksize.width和ksize.height计算得到。其中:
#sigmaX=0.3*[(ksize.width-1)*0.5-1] +0.8
#sigmaY=0.3*[(ksize.height-1)*0.5-1]+0.8
#borderType是边界样式,该值决定了以何种方式处理边界。
#一般情况下,不需要考虑该值,直接采用默认值即可。

在该函数中,sigmaY和borderType是可选参数。sigmaX是必选参数,但是可以将该参数设置为0,让函数自己去计算sigmaX的具体值。

非线性滤波
  • 中值滤波
    在OpenCV中,实现中值滤波的函数是cv2.medianBlur
dst=cv2.medianBlur(src,ksize)
#dst是返回值,表示进行中值滤波后得到的处理结果。
#src是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。
#图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一种。
#ksize是滤波核的大小,指在滤波处理过程中其邻域图像的高度和宽度。
#需要注意,核大小必须是比1大的奇数,比如3、5、7等。 
  • 双边滤波
    在OpenCV中,实现双边滤波的函数是cv2.bilateralFilter
dst=cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType)
#dst是返回值,表示进行双边滤波后得到的处理结果。
#src是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道独立处理。
#图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一种。
#d是在滤波时选取的空间距离参数,这里表示以当前像素点为中心点的直径。
#如果该值为非正数,则会自动从参数 sigmaSpace 计算得到。
#如果滤波空间较大(d>5),则速度较慢。
#因此,在实时应用中,推荐d=5。对于较大噪声的离线滤波,可以选择d=9。
#sigmaColor是滤波处理时选取的颜色差值范围,该值决定了周围哪些像素点能够参与到滤波中来。
#与当前像素点的像素值差值小于 sigmaColor 的像素点,能够参与到当前的滤波中。
#该值越大,就说明周围有越多的像素点可以参与到运算中。
#该值为0时,滤波失去意义;该值为255时,指定直径内的所有点都能够参与运算。
#sigmaSpace是坐标空间中的sigma值。它的值越大,说明有越多的点能够参与到滤波计算中来。
#当d>0时,无论sigmaSpace的值如何,d都指定邻域大小;否则,d与 sigmaSpace的值成比例。
#borderType是边界样式,该值决定了以何种方式处理边界。
#一般情况下,不需要考虑该值,直接采用默认值即可。

为了简单起见,可以将两个sigma(sigmaColor和sigmaSpace)值设置为相同的。如果它们的值比较小(例如小于10),滤波的效果将不太明显;如果它们的值较大(例如大于150),则滤波效果会比较明显,会产卡通效果。
在该函数中,参数borderType是可选参数,其余参数全部为必选参数。

图像金字塔

图像金字塔是一种以多分辨率来解释图像的结构,常用于图像分割、图像压缩和机器视觉。
在需要处理同一图像的不同分辨率的子图时,需要创建一组具有不同分辨率的原始图像。把最大的图像放在底部,最小的放在顶部,看起来就像一座金字塔,称为图像金字塔。
图像金字塔是一系列来源于同一张原始图像、以金字塔形状排列的分辨率逐步降低的图像集合。
金字塔的底部是原始图像的高分辨率的表示,顶部是低分辨率的近似。
OpenCV 为向下采样和向上采样提供了两个函数:cv2.pyrDown 和 cv2.pyrUp。

cv2.pyrDown(src, dst=None, dstsize=None, borderType=None) -> dst#向下采样
cv2.pyrUp(src, dst=None, dstsize=None, borderType=None) -> dst#向上采样
OpenCV 为向下采样和向上采样提供了两个函数:cv2.pyrDown 和 cv2.pyrUp。
```python
cv2.pyrDown(src, dst=None, dstsize=None, borderType=None) -> dst#向下采样
cv2.pyrUp(src, dst=None, dstsize=None, borderType=None) -> dst#向上采样
  • 39
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z7ziXxi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值