[深度学习]Part1 Python学习进阶Ch24图像处理OpenCV(24.14~24.23)——【DeepBlue学习笔记】

2023-05-16

本文仅供学习使用

Python高级——Ch24图像处理OpenCV(24.14~24.23)

  • 24. 图像处理OpenCV
    • 24.14 轮廓查找与绘制
      • 24.14.1 查找轮廓——cv2.findContours()
      • 24.14.2 绘制轮廓——cv2.drawContours()
      • 24.14.3 访问轮廓
    • 24.15 轮廓特征属性及应用
      • 24.15.1 凸包
      • 24.15.2 使用特定形状的轮廓包围
      • 24.15.3 点与轮廓的距离及位置关系
      • 24.15.4 轮廓的矩
      • 24.15.5 形状匹配---比较两个形状或轮廓间的相似度`cv2.matchShapes()`
      • 24.15.6 HSV颜色空间
    • 24.16 分水岭算法及图像修补
    • 24.17 GrabCut & FloodFill图像分割
    • 24.18 角点检测简介
    • 24.19 特征检测与匹配
    • 24.20 运动物体检测
    • 24.21 运动物体跟踪(meanShift & CamShift)
    • 24.22 简单人脸检测实例
    • 24.23 简单人脸识别实例


24. 图像处理OpenCV

24.14 轮廓查找与绘制

什么是轮廓: 轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度,提取轮廓就是提取
这些具有相同颜色或者灰度的曲线,或者说是连通域,轮廓在形状分析和物体的检测和识别中非常有用。

注意事项:
①为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理或者 Canny 边界检测
查找轮廓的函数会修改原始图像。如果在找到轮廓之后还想使用原始图像的话,应该将原始图像存储到其他变量中img.copy()
③在OpenCV 中,查找轮廓就像在黑色背景中找白色物体,要找的物体应该是白色而背景应该是黑色

常用函数:
cv2.findContours()——查找轮廓
cv2.drawContours()——绘制轮廓

24.14.1 查找轮廓——cv2.findContours()

cv2.findContours(image, mode, method[, contours[, hierarchy[,offset]]]) → contours, hierarchy
image: 输入图像, 8位单通道图像(一般为二值图)
contours: 检测到的轮廓, 每个轮廓存储为一个点向量, 即Point类型的vector表示
hierarchy: 可选的输出向量, 包含图像的拓扑信息。其作为轮廓数量的表示, 包含了许多元素, 每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0]~hierarchy[i][3], 分别表示后一轮廓前一轮廓父轮廓内嵌轮廓的索引编号, 如果没有对应项, 设置为负数
mode: 轮廓检索模式, 取值如下:

cv2.RETR_EXTERNAL=0——表示只检测最外层轮廓
cv2.RETR_LIST=1——提取所有轮廓并放置在list中, 轮廓不建立等级关系
cv2.RETR_CCOMP=2——提取所有轮廓并组织为双层结构
cv2.RETR_TREE =3——提取所有轮廓并重新建立网状轮廓结构

method: 轮廓的近似方法:

cv2._CHAIN_APPROX_NONE 连续存储所有的轮廓点,任何两个相邻的点都是水平、垂直或者斜相邻的。 max(abs(x1-x2),abs(y2-y1)=1;
·cv2.CHAIN_APPROX_SIMPLE 压缩存储,对于水平,垂直或者斜向的线段,只会保存端点。比如一个四边形,只会存储四个顶点。
CHAIN_APPROX_TC89_L1 CHAIN_QPPROX_TC89_KCOS 使用Teh-Chin链逼近算法中的一个,LINK_RUNS 与上述的算法完全不同,连接所有的水平层次的轮廓。

offset: 每个轮廓的可选偏移量, 默认值Point()

在这里插入图片描述

import numpy as np
import cv2

image_path = r'D:/datas2/yellowmoon.png'
img = cv2.imread(image_path)
# cv2.imshow('img', img)
# cv2.waitKey(0)

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow('img_gray', img_gray)
# cv2.waitKey(0)


_, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# cv2.imshow('thresh', thresh)
# cv2.waitKey(0)

contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
colors = [[255, 0, 0],
          [0, 255, 0],
          [0, 0, 255],
          [255, 255, 255],
          [255, 255, 255],
          [255, 255, 0]]
for idx, cnt in enumerate(contours):
    cv2.drawContours(img, cnt, -1, colors[idx],thickness=3)
cv2.imshow('draw',img)
cv2.waitKey(0)

24.14.2 绘制轮廓——cv2.drawContours()

cv2.drawContours(image, contours, contourIdx, color, thickness[, linelype[, hierarchyl, maxLevel[,offsetl]]]]) → None
image: 目标图像, Mat类型对象即可
contours: 所有的输入轮廓, 每个轮廓存储为一个点向量
contourIdx: 轮廓绘制指示变量(索引), 若为负值, 则表示绘制所有轮廓
color: 绘制轮廓的颜色
thickness: 轮廓线条的粗细, 默认值1, 如果为负值, 则绘制轮廓内部, 可选宏 CV_FILLED
lineType: 线条类型, 默认值8
hierarcy: 可选的层次结构信息, 默认值noArray()
maxLevel: 表示用于绘制轮廓的最大等级, 默认值INT_MAX
offset: 可选的轮廓偏移参数, 默认值Point()

在这里插入图片描述

24.14.3 访问轮廓

  1. 访问每一个轮廓:
import numpy as np
import cv2

image_path = r'D:/datas2/yellowmoon.png'
img = cv2.imread(image_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 1
for i in range(0,len (contours)):
    #cv2.drawContours(img,contours[i],-1,(0,255,0),5)
    cv2.drawContours(img,contours,i,(0,255,0),5)
    cv2.imshow('draw',img)
    cv2.waitKey(0)

# 2
for cnt in contours:
    cv2.drawContours(img,cnt,-1,(0,255,0),5) 
    cv2.imshow('draw',img)
    cv2.waitKey(0)
  
  1. 访问每一个轮廓的所有点
import numpy as np
import cv2

image_path = r'D:/datas2/yellowmoon.png'
img = cv2.imread(image_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 访问每个轮廓的每个点

# 1
for i in range(0,len (contours)):
    for j in range(0,len (contours[i])):
        cv2.drawContours(img,contours[i],j,(0,255,0),3)
        cv2.imshow('draw',img)
        cv2.waitKey(0)
cv2.imshow('draw',img)
cv2.waitKey(0)

# 2
for cnt in contours:
    for j in range(0,len (cnt)):
        cv2.drawContours(img,cnt,j,(0,255,0),3)
        cv2.imshow('draw',img)
        cv2.waitKey(0)

len(contours)——所有轮廓的个数
len(contours[i])——第i个轮廓所有点的个数

24.15 轮廓特征属性及应用

24.15.1 凸包

(待补充)

24.15.2 使用特定形状的轮廓包围

在实际应用中, 经常会有将检测到的轮廓用多边形表示出来的需求, 提取包围轮廓的多边形也方便我们做进一步分析, 轮廓包围主要有一下几种:
◼ 轮廓外接矩形
◼ 轮廓最小外接矩形(旋转)
◼ 轮廓最小包围圆形
◼ 轮廓拟合椭圆
◼ 轮廓逼近多边形曲线

轮廓外接矩形——cv2.boundingRect()

cv2.boundingRect(points) → retval
points: 输入的二维点集
返回值: Rect类矩形对象(x,y,w,h)

import numpy as np
import cv2

image_path = r'D:/datas2/yellowmoon.png'
img = cv2.imread(image_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
colors = [[255, 0, 0],
          [0, 255, 0],
          [0, 0, 255],
          [255, 255, 255],
          [255, 255, 255],
          [255, 255, 0]]
for idx, cnt in enumerate(contours):
    cv2.drawContours(img, cnt, -1, colors[idx], thickness=5)
    # 获取外接矩形
    x, y, w, h = cv2.boundingRect(cnt)
    cv2.rectangle(img, (x, y), (x+w, y+h), colors[idx])
    cv2.imshow('draw',img)
    cv2.waitKey(0)

在这里插入图片描述

轮廓最小外接矩形-——cv2.minAreaRect()

cv2.minAreaRect(points) → retval
points: 输入的二维点集
返回值: RotatedRect类矩形对象, 外接旋转矩形主要成员有center、size、 angle
在opencv中,坐标的原点在左上角,与x轴平行的方向为角度为0,逆时针旋转角度为负,顺时针旋转角度为正。而RotatedRect类是以矩形的哪一条边与x轴的夹角作为角度的呢?angle 是水平轴(x轴)逆时针旋转,与碰到的第一个边的夹角,而opencv默认把这个边的边长作为width,angle的取值范围必然是负的
在这里插入图片描述
reval = cv2.minAreaRect(cnt) # 中心点坐标,(w,h),angle
box = cv2.boxPoints(reval) # 矩形4个点的坐标集合,分别是左上角,右上角,左下角,右下角

import numpy as np
import cv2

image_path = r'D:/datas2/yellowmoon.png'
img = cv2.imread(image_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

contours,_ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
colors = [[255, 0, 0],
          [0, 255, 0],
          [0, 0, 255],
          [255, 255, 255],
          [255, 255, 255],
          [255, 255, 0]]
for idx, cnt in enumerate(contours):
    cv2.drawContours(img, cnt, -1, colors[idx], thickness=5)
    # 最小外接矩形
    reval = cv2.minAreaRect(cnt)# 中心点坐标,(w,h),angle
    box = cv2.boxPoints(reval)# 矩形4个点的坐标集合,分别是左上角,右上角,左下角,右下角
    box = np.int0(box)
    cv2.drawContours(img, [box], -1, colors[idx])
    # cv2.rectangle(img, box[0], box[2], colors[idx])

cv2.imshow('draw',img)
cv2.waitKey(0)

在这里插入图片描述
轮廓最小外接圆——cv2.minEnclosingCircle()

cv2.minEnclosingCircle(points) → center,radius
points: 输入的二维点集
center: Point2f&类型的center, 圆的输出圆心
radius: float&类型, 表示圆的输出半径

轮廓椭圆拟合——cv2.fitEllipse()

cv2.fitEllipse(points) → retval
points: 输入的二维点集, 可以填Mat类型或std::vector
返回值: RotatedRect类旋转矩形对象

逼近多边形曲线——cv2.approxPolyDP()

cv2.approxPolyDP(curve,epsilon,closed[,approxCurve]) → retval
curve: 输入的二维点集或轮廓
approxCurve: 多边形逼近的结果, 其类型和输入二维点集类型一致
epsilon: 逼近的精度, 为原始曲线和近似曲线间的最大值
closed: 如果其为真, 则近似的曲线为封闭曲线, 否则近似的曲线不封闭

计算轮廓面积——cv2.contourArea()

cv2.contourArea(contour[,oriented]) → retval
contour: 输入的二维点集或轮廓
oriented: 默认值false, 表示返回面积为绝对值, 否则带符号
返回值: double类型返回轮廓面积

计算轮廓长度(周长或者曲线长度)——cv2.arcLength()

cv2.arcLength(curve,closed) → retval
curve: 输入的二维点集或轮廓
colsed: 用于指示曲线是否封闭的标识符, 默认值true, 表示曲线封闭
返回值: double类型返回轮廓长度

注:cv2.contourArea()&& cv2.arcLength()可用于轮廓删选

24.15.3 点与轮廓的距离及位置关系

计算点与轮廓的距离及位置关系——cv2.pointPolygonTest()

cv2.pointPolygonTest(contour,pt,measureDist) → retval
contour: 所需检测的轮廓对象
pt: Point2f 类型的pt, 待判定位置的点
measureDist: 是否计算距离的标志, 当其为true时, 计算点到轮廓的最短距离, 当其为false时, 只判定轮廓与点的位置关系, 具体关系如下:
①返回值为-1, 表示点在轮廓外部
②返回值为0, 表示点在轮廓上
③返回值为1, 表示点在轮廓内部

注意∶如果你不需要知道具体距离,建议你将第三个参数设为 False,这样速度会提高2到3倍。

24.15.4 轮廓的矩

  1. 零阶矩
    根据矩的定义,二维图像的灰度用 f ( x , y ) f(x,y) f(x,y) 表示,零阶矩 m 00 {{m}_{00}} m00 ,表示的是图像灰度的总和:
    m 00 = ∬ f ( x , y ) d x d y {{m}_{00}}=\iint{f(x,y)dxdy} m00=f(x,y)dxdy
  2. 一阶矩
    图像的一阶矩 m 10 {{m}_{10}} m10 m 01 {{m}_{01}} m01 表示用来确定图像的灰度中心,根据中心矩的定义很容易计算出, μ 10 = 0 , μ 01 = 0 {{\mu }_{10}}=0,{{\mu }_{01}}=0 μ10=0,μ01=0
    x ˉ = m 10 m 00 , y ˉ = m 01 m 00 \bar{x}=\frac{{{m}_{10}}}{{{m}_{00}}},\bar{y}=\frac{{{m}_{01}}}{{{m}_{00}}} xˉ=m00m10,yˉ=m00m01,其中 m 10 = ∑ x ∑ y x f ( x , y ) {{m}_{10}}=\sum\limits_{x}{\sum\limits_{y}{xf(x,y)}} m10=xyxf(x,y) m 01 = ∑ x ∑ y y f ( x , y ) {{m}_{01}}=\sum\limits_{x}{\sum\limits_{y}{yf(x,y)}} m01=xyyf(x,y)
  3. 二阶矩
    二阶矩有三个, m 11 , m 02 , m 20 {{m}_{11}},{{m}_{02}},{{m}_{20}} m11,m02,m20,也成为惯性矩。它们可以确定物体的几个特性:
    ① 二阶中心矩用来确定目标物体的主轴,长轴和短轴分别对应最大和最小的二阶中心矩。可以计算主轴方向角。
    图像椭圆: 由一阶、二阶矩可以确定一个与原图像惯性等价的图像椭圆。所谓图像椭圆是一个与原图像的二阶矩及原图像的灰度总和均相等的均匀椭圆。使得主轴与图像的主轴方向重合,一边分析图像性质。
    m 11 = ∑ x ∑ y x y f ( x , y ) {{m}_{11}}=\sum\limits_{x}{\sum\limits_{y}{xyf(x,y)}} m11=xyxyf(x,y)
    m 02 = ∑ x ∑ y y 2 f ( x , y ) {{m}_{02}}=\sum\limits_{x}{\sum\limits_{y}{{{y}^{2}}f(x,y)}} m02=xyy2f(x,y)
    m 20 = ∑ x ∑ y x 2 f ( x , y ) {{m}_{20}}=\sum\limits_{x}{\sum\limits_{y}{{{x}^{2}}f(x,y)}} m20=xyx2f(x,y)
  4. 三阶矩及以上
    对于三阶或三阶以上矩,使用图像在轴或轴上的投影比使用图像本身的描述更方便。
    三阶矩:投影扭曲,描述了图像投影的扭曲程度。扭曲是一个经典统计量,用来衡量关于均值对称分布的偏差程度。
    四阶矩:投影峰度,峰度是一个用来测量分布峰度的经典统计量。可以计算峰度系数。当峰度系数为0时,表示高斯分布;当峰度系数小于0时,表示平坦的少峰分布;当峰度系数大于0时,表示狭窄的多峰分布。
  5. Hu矩
    直接用原点矩或中心矩作为图像的特征,不能保证特征同时具有平移、旋转和比例不变性。事实上,如果仅用中心矩表示图像的特征,则特征仅具有平移不变性如果利用归一化中心矩,则特征不仅具有平移不变性,而且还具有比例不变性,但具有旋转不变性。要同时具有平移、旋转和比例变换不变性,直接使用原点矩或中心矩是不行的。为此提出了不变矩,他给出了连续函数矩的定义和关于矩的基本性质,证明了有关矩的平移不变性、旋转不变性以及比例不变性等性质,具体给出了具有平移不变性、旋转不变性和比例不变性的七个不变矩的表达式。
    不变矩(Invariant Moments)是一处高度浓缩的图像特征,具有平移、灰度、尺度、旋转不变性。M.K.Hu在1961年首先提出了不变矩的概念。下面是几个图像的不变矩:
    一幅 M × N M\times N M×N 的数字图像 f ( i , j ) f(i,j) f(i,j) ,其中 p + q p+q p+q 阶几何矩 m p q {{m}_{pq}} mpq 和中心距 μ p q {{\mu }_{pq}} μpq 为:
    m p q = ∑ i = 1 M ∑ j = 1 N x p y q f ( i , j ) {{m}_{pq}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{x}^{p}}{{y}^{q}}f(i,j)}} mpq=i=1Mj=1Nxpyqf(i,j)
    μ p q = ∑ x = 1 M ∑ y = 1 N ( i − i ˉ ) p ( j − j ˉ ) q f ( i , j ) {{\mu }_{pq}}=\sum\limits_{x=1}^{M}{\sum\limits_{y=1}^{N}{{{(i-\bar{i})}^{p}}{{(j-\bar{j})}^{q}}f(i,j)}} μpq=x=1My=1N(iiˉ)p(jjˉ)qf(i,j)
    其中 f ( i , j ) f(i,j) f(i,j) 为图像在坐标点 ( i , j ) (i,j) (i,j) 处的灰度值。 i ˉ = m 10 m 00 , j ˉ = m 01 m 00 \bar{i}=\frac{{{m}_{10}}}{{{m}_{00}}},\bar{j}=\frac{{{m}_{01}}}{{{m}_{00}}} iˉ=m00m10,jˉ=m00m01
    若将 m 00 {{m}_{00}} m00 看做是图像的 灰度质量,则 ( i ˉ , j ˉ ) (\bar{i},\bar{j}) (iˉ,jˉ) 为图像的质心坐标,那么中心距 μ p q {{\mu }_{pq}} μpq 反映的是图像灰度相对于其灰度质心的分布情况。可以用几何矩来表示中心距,0~3阶中心距与几何矩的关系如下:
    { μ 00 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 0 ( j − j ˉ ) 0 f ( i , j ) = m 00 μ 10 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 1 ( j − j ˉ ) 0 f ( i , j ) = 0 μ 01 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 0 ( j − j ˉ ) 1 f ( i , j ) = 0 μ 11 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 1 ( j − j ˉ ) 1 f ( i , j ) = m 11 − y ˉ m 10 μ 20 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 2 ( j − j ˉ ) 0 f ( i , j ) = m 20 − y ˉ m 01 μ 02 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 0 ( j − j ˉ ) 2 f ( i , j ) = m 02 − y ˉ m 01 μ 30 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 3 ( j − j ˉ ) 0 f ( i , j ) = m 30 − x ˉ m 02 + 2 x ˉ 2 m 10 μ 12 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 1 ( j − j ˉ ) 2 f ( i , j ) = m 12 − 2 y ˉ m 11 − x ˉ m 02 + 2 y ˉ 2 m 10 μ 21 = ∑ i = 1 M ∑ j = 1 N ( i − i ˉ ) 2 ( j − j ˉ ) 1 f ( i , j ) = m 21 − 2 x ˉ m 11 − y ˉ m 02 + 2 x ˉ 2 m 01 \left\{ \begin{matrix} {{\mu }_{00}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{0}}{{(j-\bar{j})}^{0}}f(i,j)}}={{m}_{00}} \\ {{\mu }_{10}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{1}}{{(j-\bar{j})}^{0}}f(i,j)}}=0 \\ {{\mu }_{01}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{0}}{{(j-\bar{j})}^{1}}f(i,j)}}=0 \\ {{\mu }_{11}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{1}}{{(j-\bar{j})}^{1}}f(i,j)}}={{m}_{11}}-\bar{y}{{m}_{10}} \\ {{\mu }_{20}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{2}}{{(j-\bar{j})}^{0}}f(i,j)}}={{m}_{20}}-\bar{y}{{m}_{01}} \\ {{\mu }_{02}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{0}}{{(j-\bar{j})}^{2}}f(i,j)}}={{m}_{02}}-\bar{y}{{m}_{01}} \\ {{\mu }_{30}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{3}}{{(j-\bar{j})}^{0}}f(i,j)}}={{m}_{30}}-\bar{x}{{m}_{02}}+2{{{\bar{x}}}^{2}}{{m}_{10}} \\ {{\mu }_{12}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{1}}{{(j-\bar{j})}^{2}}f(i,j)}}={{m}_{12}}-2\bar{y}{{m}_{11}}-\bar{x}{{m}_{02}}+2{{{\bar{y}}}^{2}}{{m}_{10}} \\ {{\mu }_{21}}=\sum\limits_{i=1}^{M}{\sum\limits_{j=1}^{N}{{{(i-\bar{i})}^{2}}{{(j-\bar{j})}^{1}}f(i,j)}}={{m}_{21}}-2\bar{x}{{m}_{11}}-\bar{y}{{m}_{02}}+2{{{\bar{x}}}^{2}}{{m}_{01}} \\ \end{matrix} \right. μ00=i=1Mj=1N(iiˉ)0(jjˉ)0f(i,j)=m00μ10=i=1Mj=1N(iiˉ)1(jjˉ)0f(i,j)=0μ01=i=1Mj=1N(iiˉ)0(jjˉ)1f(i,j)=0μ11=i=1Mj=1N(iiˉ)1(jjˉ)1f(i,j)=m11yˉm10μ20=i=1Mj=1N(iiˉ)2(jjˉ)0f(i,j)=m20yˉm01μ02=i=1Mj=1N(iiˉ)0(jjˉ)2f(i,j)=m02yˉm01μ30=i=1Mj=1N(iiˉ)3(jjˉ)0f(i,j)=m30xˉm02+2xˉ2m10μ12=i=1Mj=1N(iiˉ)1(jjˉ)2f(i,j)=m122yˉm11xˉm02+2yˉ2m10μ21=i=1Mj=1N(iiˉ)2(jjˉ)1f(i,j)=m212xˉm11yˉm02+2xˉ2m01
    而数字图像是一个二维的离散信号,对上述公式进行离散化之后,其中C与R分别表示图像的列与行。
    m p q = ∑ i = 1 C ∑ j = 1 R x p y q f ( x , y )   p , q = 0 , 1 , 2 , . . . {{m}_{pq}}=\sum\limits_{i=1}^{C}{\sum\limits_{j=1}^{R}{{{x}^{p}}{{y}^{q}}f(x,y)\text{ }p,q=0,1,2,...}} mpq=i=1Cj=1Rxpyqf(x,y) p,q=0,1,2,...
    0阶矩( m 00 {{m}_{00}} m00):目标区域的质量
    1阶矩( m 10 , m 01 {{m}_{10}},{{m}_{01}} m10,m01):目标区域的质心
    2阶矩( m 11 , m 02 , m 20 {{m}_{11}},{{m}_{02}},{{m}_{20}} m11,m02,m20):目标区域的旋转半径
    3阶矩( m 03 , m 12 , m 21 , m 30 {{m}_{03}},{{m}_{12}},{{m}_{21}},{{m}_{30}} m03,m12,m21,m30):目标区域的方位和斜度,反应目标的扭曲但是目标区域往往伴
    随着空间变换(平移,尺度,旋转),所以需要在普通矩的基础上构造出具备不变性的矩组——hu矩。
    中心矩:构造平移不变性——由零阶原点矩和一阶原点矩,我们可以求得目标区域的质心坐标: x ˉ = m 10 m 00 , y ˉ = m 01 m 00 \bar{x}=\frac{{{m}_{10}}}{{{m}_{00}}},\bar{y}=\frac{{{m}_{01}}}{{{m}_{00}}} xˉ=m00m10,yˉ=m00m01
    由求得的质心坐标,我们可以构造出中心矩,质心为中心构建中心矩,矩的计算是目标区域中的点相对于目标区域的质心,而与目标区域的位置无关,及具备了平移不变性。
    μ p q = ∑ x = 1 C ∑ y = 1 R ( x − x ˉ ) p ( y − y ˉ ) q f ( x , y )   p , q = 0 , 1 , 2 , . . . {{\mu }_{pq}}=\sum\limits_{x=1}^{C}{\sum\limits_{y=1}^{R}{{{(x-\bar{x})}^{p}}{{(y-\bar{y})}^{q}}f(x,y)}}\text{ }p,q=0,1,2,... μpq=x=1Cy=1R(xxˉ)p(yyˉ)qf(x,y) p,q=0,1,2,...
    归一化中心矩:构造尺度不变性——为抵消尺度变化对中心矩的影响,利用零阶中心矩u00对各阶中心距进行归一化处理,得到归一
    化中心矩,其中: r = p + q + 2 2 , p + q = 2 , 3 , . . . r=\frac{p+q+2}{2},p+q=2,3,... r=2p+q+2,p+q=2,3,...
    η p q = μ p q μ 00 r {{\eta }_{pq}}=\frac{{{\mu }_{pq}}}{{{\mu }_{00}}^{r}} ηpq=μ00rμpq
    利用二阶和三阶规格中心矩可以导出下面7个不变矩组( Φ 1 ∼ Φ 7 {{\Phi }_{1}}\sim{{\Phi }_{7}} Φ1Φ7),它们在图像平移、旋转和比例变化时保持不变。
    { Φ 1 = η 20 + η 02 Φ 2 = ( η 20 − η 02 ) 2 + 4 η 11 2 Φ 3 = ( η 20 − 3 η 12 ) 2 + 3 ( η 21 − η 03 ) 2 Φ 4 = ( η 30 + η 12 ) 2 + ( η 21 + η 03 ) 2 Φ 5 = ( η 30 + 3 η 12 ) ( η 30 + η 12 ) [ ( η 30 + η 12 ) 2 − 3 ( η 21 + η 03 ) 2 ] + ( 3 η 21 − η 03 ) ( η 21 + η 03 ) [ 3 ( η 30 + η 12 ) 2 − ( η 21 + η 03 ) 2 ] Φ 6 = ( η 20 − η 02 ) [ ( η 30 + η 12 ) 2 − ( η 21 + η 03 ) 2 ] + 4 η 11 ( η 30 + η 12 ) ( η 21 + η 03 ) Φ 7 = ( 3 η 21 − η 03 ) ( η 30 + η 12 ) [ ( η 30 + η 12 ) 2 − 3 ( η 21 + η 03 ) 2 ] + ( 3 η 21 − η 03 ) ( η 21 + η 03 ) [ 3 ( η 30 + η 12 ) 2 − ( η 21 + η 03 ) 2 ] \left\{ \begin{matrix} {{\Phi }_{1}}={{\eta }_{20}}+{{\eta }_{02}} \\ {{\Phi }_{2}}={{({{\eta }_{20}}-{{\eta }_{02}})}^{2}}+4{{\eta }_{11}}^{2} \\ {{\Phi }_{3}}={{({{\eta }_{20}}-3{{\eta }_{12}})}^{2}}+3{{({{\eta }_{21}}-{{\eta }_{03}})}^{2}} \\ {{\Phi }_{4}}={{({{\eta }_{30}}+{{\eta }_{12}})}^{2}}+{{({{\eta }_{21}}+{{\eta }_{03}})}^{2}} \\ {{\Phi }_{5}}=({{\eta }_{30}}+3{{\eta }_{12}})({{\eta }_{30}}+{{\eta }_{12}})[{{({{\eta }_{30}}+{{\eta }_{12}})}^{2}}-3{{({{\eta }_{21}}+{{\eta }_{03}})}^{2}}]+(3{{\eta }_{21}}-{{\eta }_{03}})({{\eta }_{21}}+{{\eta }_{03}})[3{{({{\eta }_{30}}+{{\eta }_{12}})}^{2}}-{{({{\eta }_{21}}+{{\eta }_{03}})}^{2}}] \\ {{\Phi }_{6}}=({{\eta }_{20}}-{{\eta }_{02}})[{{({{\eta }_{30}}+{{\eta }_{12}})}^{2}}-{{({{\eta }_{21}}+{{\eta }_{03}})}^{2}}]+4{{\eta }_{11}}({{\eta }_{30}}+{{\eta }_{12}})({{\eta }_{21}}+{{\eta }_{03}}) \\ {{\Phi }_{7}}=(3{{\eta }_{21}}-{{\eta }_{03}})({{\eta }_{30}}+{{\eta }_{12}})[{{({{\eta }_{30}}+{{\eta }_{12}})}^{2}}-3{{({{\eta }_{21}}+{{\eta }_{03}})}^{2}}]+(3{{\eta }_{21}}-{{\eta }_{03}})({{\eta }_{21}}+{{\eta }_{03}})[3{{({{\eta }_{30}}+{{\eta }_{12}})}^{2}}-{{({{\eta }_{21}}+{{\eta }_{03}})}^{2}}] \\ \end{matrix} \right. Φ1=η20+η02Φ2=(η20η02)2+4η112Φ3=(η203η12)2+3(η21η03)2Φ4=(η30+η12)2+(η21+η03)2Φ5=(η30+3η12)(η30+η12)[(η30+η12)23(η21+η03)2]+(3η21η03)(η21+η03)[3(η30+η12)2(η21+η03)2]Φ6=(η20η02)[(η30+η12)2(η21+η03)2]+4η11(η30+η12)(η21+η03)Φ7=(3η21η03)(η30+η12)[(η30+η12)23(η21+η03)2]+(3η21η03)(η21+η03)[3(η30+η12)2(η21+η03)2]

矩的计算——cv2.moments()

cv2.moments(arrayl,binaryImage])) → retval
array: 输入参数, 可以是光栅图像或二维数组
binaryImage: 默认值false, 非零像素取其本身值, 若为true, 则非零像素取1
返回值: Moments类的对象, 返回对应的轮廓的空间矩/中心矩和归一化中心矩(最高3阶)

24.15.5 形状匹配—比较两个形状或轮廓间的相似度cv2.matchShapes()

cv2.matchShapes(contour1,contour2,method,parameter) → retval
contour1: 所需比较的轮廓1
contour2: 所需比较的轮廓2
method: 轮廓比较的方法

method = CV_CONTOURS_MATCH_I1 I 1 ( A , B ) = ∑ i = 1 , . . . , 7 ∣ 1 m i A − 1 m i B ∣ {{I}_{1}}(A,B)=\sum\limits_{i=1,...,7}{\left| \frac{1}{m_{i}^{A}}-\frac{1}{m_{i}^{B}} \right|} I1(A,B)=i=1,...,7miA1miB1
method = CV_CONTOURS_MATCH_I2 I 2 ( A , B ) = ∑ i = 1 , . . . , 7 ∣ m i A − m i B ∣ {{I}_{2}}(A,B)=\sum\limits_{i=1,...,7}{\left| m_{i}^{A}-m_{i}^{B} \right|} I2(A,B)=i=1,...,7miAmiB
method = CV_CONTOURS_MATCH_I3 I 3 ( A , B ) = max ⁡ i = 1 , . . . , 7   ∣ m i A − m i B ∣ ∣ m i A ∣ {{I}_{3}}(A,B)=\underset{i=1,...,7}{\mathop{\max }}\,\frac{\left| m_{i}^{A}-m_{i}^{B} \right|}{\left| m_{i}^{A} \right|} I3(A,B)=i=1,...,7maxmiAmiAmiB
其中: m i A = s i g n ( h i A ) ⋅ log ⁡ h i A , m i B = s i g n ( h i B ) ⋅ log ⁡ h i B m_{i}^{A}=sign(h_{i}^{A})\cdot \log h_{i}^{A},m_{i}^{B}=sign(h_{i}^{B})\cdot \log h_{i}^{B} miA=sign(hiA)loghiA,miB=sign(hiB)loghiB h i A , h i B h_{i}^{A},h_{i}^{B} hiA,hiB为矩阵A、B的Hu矩

parameter: 比较方法的特殊参数(目前不支持)

注意: cv2.matchShapes()函数比较轮廓相似度是基于Hu矩来计算的, 结果越小相似度越高。Hu矩是归一化中心矩的线性组合, 是为了获取图像某个特征的矩函数(对应变化如平移、缩放、旋转、镜像)

24.15.6 HSV颜色空间

HSV颜色空间与人眼所看色彩较接近, 故常用于颜色检测与识别。其中H(色调)、S(饱和度)、V(亮度)

H—不同的颜色(红色/绿色/蓝色)—范围: 0~360
S—颜色深浅(浅红/深红)—范围: 0.0~1.0
V—颜色亮暗(暗红/亮红)—范围: 0.0~1.0

OpenCV默认的HSV范围分别是: H: 0~180, S: 0~255, V: 0~255

  1. 颜色空间转换——cv2.cvtColor()
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
import cv2
import numpy as np

img = cv2.imread('D:/datas2/logo.png')
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([100,43,46],dtype='uint8')
high =  np.array([124,255,255],dtype='uint8')
mask = cv2.inRange(img_hsv,lower,high)
cv2.imshow('mask',mask)
cv2.waitKey(0)

在这里插入图片描述

  1. 颜色区间范围删选——cv2.inRange()

cv2.inRange(src,lowerb,upperb[,dst]) → dst
src: 输入原图或数组
lowerb: 低边界或者颜色阈值
upperb: 高边界或者颜色阈值
dst: 输出目标图像, 需要和原图一样的size并且类型需为CV_8U

  1. 滑动条HSV参数debug工具
    (待补充)

24.16 分水岭算法及图像修补

(待补充)

24.17 GrabCut & FloodFill图像分割

(待补充)

24.18 角点检测简介

(待补充)

24.19 特征检测与匹配

(待补充)

24.20 运动物体检测

(待补充)

24.21 运动物体跟踪(meanShift & CamShift)

(待补充)

24.22 简单人脸检测实例

(待补充)

24.23 简单人脸识别实例

(待补充)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[深度学习]Part1 Python学习进阶Ch24图像处理OpenCV(24.14~24.23)——【DeepBlue学习笔记】 的相关文章

  • 互联网大厂SQL真题(三)

    题目 xff1a 近一个月发布的视频中热度最高的top3视频 问题 xff1a 找出近一个月发布的视频中热度最高的top3视频 注 xff1a 热度 61 a 视频完播率 43 b 点赞数 43 c 评论数 43 d 转发数 新鲜度 xff
  • Spark三种常见JOIN方式

    Spark join 基本原理 Spark join的基本实现流程如下图所示 xff0c Spark将参与Join的两张表抽象为流式表 StreamTable 和查找表 BuildTable xff0c 通常系统会默认设置StreamTab
  • 遛一遛8266的定时器

    一 xff1a 简述 硬件为ESP LAUNCHER开发板 使用GPIO12 要求是某一定时间指示灯状态发生改变 ESP8266定时功能的实现有两种方式 xff1a 软件定时器和硬件定时器 软件定时器的接口在 ESP8266 NONOS S
  • MYSQL8.0以上版本忘记ROOT密码

    MYSQL8 0 43 忘记Root密码 xff1a 1 以超级管理员打开cmd xff0c 关闭mysql服务2 跳过权限验证登录mysql3 在新的窗口中登录mysql4 切换到mysql xff0c 将密码置空 5 设置加密规则并更新
  • 深度学习【13】tensorflow保存graph和参数为pb文件

    from tensorflow python framework graph util import convert variables to constants graph 61 convert variables to constant
  • plsql查询数据显示为乱码解决方法

    使用plsql查询数据显示为乱码 xff1a 查看数据库编码 xff1a 通过网上搜索 xff0c 发现需要设置环境变量 xff0c 添加以下环境变量 xff1a LANG 61 zh CN GBK NLS LANG 61 34 SIMPL
  • 对抗网络之目标检测应用:A-Fast-RCNN

    对抗网络之目标检测应用 xff1a A Fast RCNN 论文 xff1a A Fast RCNN Hard Positive Generation via Adversary for Object Detection 点击下载 Caff
  • make -j20 出现以下报错: Ensure Jack server is installed and started

    如果出现的报错是 xff1a build core ninja mk 148 recipe for target 39 ninja wrapper 39 failed 综上所述 xff0c 其实就是 xff1a Android7 0 xff
  • QT中 窗口部件的 背景图片 的设置

    QT中 窗口部件的 背景图片 的设置 分类 xff1a QT 2013 04 08 11 06 359人阅读 评论 0 收藏 举报 目录 43 如何设置对话框的自定义的背景颜色 xff1f 2010 03 14 14 34 11 分类 xf
  • 刷LeetCode的一些心得(0基础大龄转码上谷歌)

    我之前就是完全0基础 大龄转码 xff0c 刷题上千然后进谷歌的 这里0基础指的是没学过编程语言 xff0c 没学过数据结构和算法 xff0c 一上来就直接做题那种 第一道题two sum xff0c 我显然不会做 我的笨方法就是看答案 x
  • 在Centos8 中使用Stratis管理本地存储(一)

    导读Stratis是RHEL8 Centos8中提供的一个新的本地存储管理工具 xff0c 它将有助于在块设备上创建分层存储 在RHEL8 Centos8中 xff0c 可以通过安装两个软件包获得Stratis 在RHEL7 xff0c 我
  • ncat命令使用实例

    导读Ncat工具功能类似于cat命令 xff0c 但用于网络 它是一个命令行的工具 xff0c 用于跨网络读取 写入和重定向数据 它被设计成一个可靠的后端工具 xff0c 可以与脚本或其他程序一起使用 ncat可以是端口扫描工具 xff0c
  • Ubuntu 20.04 使用realmd加入AD域

    导读本文展示如何使用 realmd sssd将 Ubuntu 20 04加入到 Active Directory 域 本文还进一步为通过 AD 登录的域用户配置 sudo 规则 设置主机名和DNS 下面命令用来设置正确的主机名和dns服务器
  • Linux下合并文件

    导读 我们在先前的文章中介绍过 cat 命令 的使用 xff0c 了解到该 命令 用于获取文件内容并将其输出到屏幕或其他设备中 事实上 xff0c cat 命令的最初目的是连接文件 xff0c 所以我们可以用它来合并文件 我们在先前的文章中
  • 私有云有哪些优势?

    导读从RightScale 2017的报告中我们发现 xff0c 平均每家公司正在使用1 8个公有云和2 3个私有云 xff0c 同时正在准备使用1 8个公有云和2 1和私有云 从这项数据中我们不难发现 xff0c 公司对于私有云的使用程度
  • 通过sonic-ci-helper插件与Sonic平台结合实现多设备批量安装应用

    一 sonic ci helper 插件 sonic ci helper 是为对接Jenkins CI流程建设的小助手 下载地址 xff1a Sonic Download Center 两种安装方式 xff1a xff08 1 xff09
  • 在Centos8 中使用Stratis管理本地存储(二)

    本文介绍如何通过向现有Stratis池中添加新磁盘和添加缓存磁盘 下面将介绍添加 删除 快照等内容 系统环境 Centos8 向Stratis池中添加其他磁盘 在Stratis管理下 xff0c 将新的块设备添加到现有池非常容易 在上一篇文
  • ubuntu升级后,停留在tty1界面,进不去桌面

    ubuntu升级后 xff0c 提示输入用户名 密码 xff0c 出现以下界面 xff1a 无法显示桌面 输入startx xff0c 即可进入桌面
  • Debian 无法拉取 https 源 -----清华源Debind-stretch

    已经配置好的清华源tsinghua sources Debind stretch可以直接docker pull 无法拉取 https 源 Debian 的软件源配置文件是 etc apt sources list 将系统自带的该文件做个备份
  • 阿里云弹性计算资源

    1 弹性计算 1 1 轻量级应用服务器 针对轻量级应用而生 xff0c 共享容器化的服务器 xff0c 使用个人网站 中小企业网站 个人博客等应用 1 2 企业级服务器 xff08 ECS xff09 企业场景对业务稳定性的要求高 xff0

随机推荐