OpenCV中的图像处理中

本文深入探讨了OpenCV中的图像处理技术,包括图像金字塔、轮廓提取及其特征如矩、面积、周长和凸包。详细讲解了轮廓查找函数cv2.findContours的使用,以及轮廓的矩、面积和周长计算。此外,还介绍了直方图的概念,如统计直方图、直方图均衡化和CLAHE。直方图在图像分析和增强中起着关键作用,通过直方图反向投影可以实现目标检测和分割。
摘要由CSDN通过智能技术生成

图像金字塔

一般情况下,我们要处理是一副具有固定分辨率的图像。但是有些情况下,我们需要对同一图像的不同分辨率的子图像进行处理。比如,我们要在一幅图像中查找某个目标,比如脸,我们不知道目标在图像中的尺寸大小。这种情况下,我们需要创建创建一组图像,这些图像是具有不同分辨率的原始图像。我
们把这组图像叫做图像金字塔(简单来说就是同一图像的不同分辨率的子图集合)。如果我们把最大的图像放在底部,最小的放在顶部,看起来像一座金字塔,故而得名图像金字塔。
有两类图像金字塔:高斯金字塔和拉普拉斯金字塔。
高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图像中 5 个像素的高斯加权平均值。这样操作一次一个 MxN 的图像就变成了一个 M/2xN/2 的图像。所以这幅图像的面积就变为原来图像面积的四分之一。这被称为 Octave。连续进行这样的操作我们就会得到一个分辨率不断下降的图像金字塔。我们可以使用函数cv2.pyrDown() 和 cv2.pyrUp() 构建图像金字塔。
函数 cv2.pyrDown() 从一个高分辨率大尺寸的图像向上构建一个金子塔(尺寸变小,分辨率降低)。

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('voice.png',0)
print("resize之前img",img.shape)
img_resize = cv2.resize(img,None,fx=0.5,fy=0.5)
print("resize之后img",img_resize.shape)
lower_reso = img.copy()
for i in range(4):
    lower_reso = cv2.pyrDown(lower_reso)

higher_reso = lower_reso.copy()

for i in range(4):
    higher_reso = cv2.pyrUp(higher_reso)

cv2.imshow("img",img)
cv2.imshow("lower_reso",lower_reso)
cv2.imshow("higher_reso",higher_reso)
print("pyrDown img",lower_reso.shape)
print("higher_reso",higher_reso.shape)
cv2.waitKey(0)

在这里插入图片描述
在这里插入图片描述

OpenCV中的轮廓

什么是轮廓

轮廓可以简单认为成将连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。
• 为了更加准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理或者 Canny 边界检测。
• 查找轮廓的函数会修改原始图像。如果你在找到轮廓之后还想使用原始图像的话,你应该将原始图像存储到其他变量中。
• 在 OpenCV 中,查找轮廓就像在黑色背景中超白色物体。你应该记住,要找的物体应该是白色而背景应该是黑色。

让我们看看如何在一个二值图像中查找轮廓:
函数 cv2.findContours() 有三个参数。
输入参数:
image:输入的二值图像,即要查找轮廓的图像,通常为灰度图像或二值图像(只包含黑色和白色两种颜色)。
mode:表示轮廓的检索模式。有四种可选模式,分别为cv2.RETR_EXTERNAL、cv2.RETR_LIST、cv2.RETR_CCOMP和cv2.RETR_TREE。
其中:
cv2.RETR_EXTERNAL表示只检测外部轮廓,cv2.RETR_LIST表示检测所有的轮廓并将它们存储在列表中
cv2.RETR_CCOMP表示检测所有轮廓并将它们组织成两层
cv2.RETR_TREE表示检测所有轮廓并将它们组织成树形结构。
method:表示轮廓的近似方法。有三种可选方法,分别为cv2.CHAIN_APPROX_NONE、cv2.CHAIN_APPROX_SIMPLE和cv2.CHAIN_APPROX_TC89_L1。其中,cv2.CHAIN_APPROX_NONE表示存储所有的轮廓点,cv2.CHAIN_APPROX_SIMPLE表示仅存储轮廓的端点,cv2.CHAIN_APPROX_TC89_L1表示使用Teh-Chinl算法对轮廓进行逐段近似。

下面返回参数:
contours:表示输出的轮廓,通常是一个Python列表,每个元素表示一个轮廓。默认值为None。
hierarchy:表示轮廓的层级关系,可以用来确定轮廓之间的包含关系等信息。通常也是一个Python列表,每个元素对应一个轮廓。默认值为None。
offset:表示轮廓点的偏移量,通常不需要设置。默认值为(0,0)。
下面代码:

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('29.PNG')
imggray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(imggray,127,255,0)

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

cv2.drawContours(img,contours,-1,(255,0,0),3)

cv2.imshow("cv2.CHAIN_APPROX_NONE",img)

cv2.waitKey(0)

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(img,contours,-1,(0,255,0),3)

cv2.imshow("cv2.CHAIN_APPROX_SIMPLE",img)

cv2.waitKey(0)

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

#索引0 同级下一个轮廓
#索引1 同级前一个轮廓
#索引2 下级第一个子节点
#索引3 上级的父子节点
print(hierarchy)

num = 0
for cnt in contours:
    x, y, w, h = cv2.boundingRect(cnt)
    numtext = str(num)
    cv2.putText(img, numtext, (x,y), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
    num = num + 1

cv2.imshow("cv2.CHAIN_APPROX_SIMPLE",img)

cv2.waitKey(0)


在这里插入图片描述
在这里插入图片描述

轮廓特征

矩 轮廓面积 轮廓周长

cv2.moments() 返回一个包含多个矩的字典类型数据,其中包括图像的重心、图像的面积以及一些形状描述量。

这些量可以用于许多不同的应用程序,例如图像处理、计算机视觉、机器学习等。下面是一些常见的用法示例:

1 计算重心
重心是通过计算轮廓的像素坐标平均值来获得的,可以用来识别物体的位置或形状。以下是计算重心的示例代码:

M = cv2.moments(contour)
if M["m00"] != 0:
    cx = int(M["m10"] / M["m00"])
    cy = int(M["m01"] / M["m00"])

2 计算图像面积
可以使用 cv2.contourArea() 函数来计算图像的面积,也可以使用 cv2.moments() 函数来计算。以下是使用 cv2.moments() 函数计算图像面积的示例代码:

M = cv2.moments(contour)
area = M["m00"]

3 计算图像的形状描述量
cv2.moments() 函数还可以用于计算图像的形状描述量,例如中心距、标准化中心距、中心矩等。这些描述量可以用于识别物体的形状。以下是计算中心矩的示例代码:

M = cv2.moments(contour)
if M["m00"] != 0:
    mu20 = M["mu20"] / M["m00"]
    mu02 = M["mu02"] / M["m00"]
    mu11 = M["mu11"] / M["m00"]

cv2.moments() 函数返回一个字典对象,包含了计算得到的图像对象的几何矩信息。该字典包含以下 24 个键值对:

“m00”:对象的零阶矩(面积);
“m10”:对象的一阶矩(X 轴方向上的质心);
“m01”:对象的一阶矩(Y 轴方向上的质心);
“m20”:对象的二阶矩(X 轴方向上的二阶矩);
“m11”:对象的二阶矩(X、Y 轴方向上的二阶矩);
“m02”:对象的二阶矩(Y 轴方向上的二阶矩);
“m30”:对象的三阶矩(X 轴方向上的三阶矩);
“m21”:对象的三阶矩(X、Y 轴方向上的三阶矩);
“m12”:对象的三阶矩(Y、X 轴方向上的三阶矩);
“m03”:对象的三阶矩(Y 轴方向上的三阶矩);
“mu20”:对象的二阶中心矩(X 轴方向上的二阶中心矩);
“mu11”:对象的二阶中心矩(X、Y 轴方向上的二阶中心矩);
“mu02”:对象的二阶中心矩(Y 轴方向上的二阶中心矩);
“mu30”:对象的三阶中心矩(X 轴方向上的三阶中心矩);
“mu21”:对象的三阶中心矩(X、Y 轴方向上的三阶中心矩);
“mu12”:对象的三阶中心矩(Y、X 轴方向上的三阶中心矩);
“mu03”:对象的三阶中心矩(Y 轴方向上的三阶中心矩);
“nu20”:对象的归一化二阶中心矩(X 轴方向上的归一化二阶中心矩);
“nu11”:对象的归一化二阶中心矩(X、Y 轴方向上的归一化二阶中心矩);
“nu02”:对象的归一化二阶中心矩(Y 轴方向上的归一化二阶中心矩);
“nu30”:对象的归一化三阶中心矩(X 轴方向上的归一化三

轮廓面积使用cv2.contourArea()
轮廓周长使用cv2.arcLength()

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('29.PNG')
imggray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(imggray,127,255,0)

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

#索引0 同级下一个轮廓
#索引1 同级前一个轮廓
#索引2 下级第一个子节点
#索引3 上级的父子节点
print(hierarchy)

num = 0
for cnt in contours:
    #矩
    M = cv2.moments(cnt)
    cx =
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值