OpenCV自学笔记十五:图像轮廓

目录

1、查找并绘制轮廓

2、矩特征

3、Hu矩

4、轮廓拟合

5、凸包


1、查找并绘制轮廓

在OpenCV中,可以使用`cv2.findContours()`函数来查找图像中的轮廓,并使用`cv2.drawContours()`函数将轮廓绘制到图像上。下面是一个示例代码:

import cv2

# 读取图像并转换为灰度图像

image = cv2.imread('image.jpg')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 进行边缘检测

edges = cv2.Canny(gray, 50, 150)

# 查找轮廓

contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓

cv2.drawContours(image, contours, -1, (0, 255, 0), 2)

# 显示结果

cv2.imshow("Contours", image)

cv2.waitKey(0)

cv2.destroyAllWindows()

在这个示例中,我们首先使用`cv2.imread()`函数读取一张图像,并将其转换为灰度图像,以便进行边缘检测。

然后,我们使用`cv2.Canny()`函数对灰度图像进行边缘检测,该函数可以根据指定的阈值自动检测图像中的边缘。

接下来,我们使用`cv2.findContours()`函数查找边缘图像中的轮廓。`cv2.findContours()`函数返回两个值:轮廓列表和层级信息。这里我们选择了`RETR_EXTERNAL`表示只检测最外层的轮廓,以及`CHAIN_APPROX_SIMPLE`表示使用简化的轮廓表示方法。

最后,我们使用`cv2.drawContours()`函数将轮廓绘制到原始图像上。该函数需要传入原始图像、轮廓列表、要绘制的轮廓索引(-1表示绘制所有轮廓)、绘制的颜色和线宽等参数。

最后,使用`cv2.imshow()`函数显示绘制了轮廓的图像。

2、矩特征

在OpenCV中,可以使用`cv::moments()`函数来计算图像的矩特征。该函数接受一个二值化的图像作为输入,并返回一个`Moments`结构体,其中包含了计算得到的各种矩特征。

以下是一个使用OpenCV计算矩特征的简单示例:

#include <opencv2/opencv.hpp>

int main() {

// 读取图像

cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);

// 对图像进行二值化处理

cv::Mat binaryImage;

cv::threshold(image, binaryImage, 128, 255, cv::THRESH_BINARY);

// 计算图像的矩特征

cv::Moments moments = cv::moments(binaryImage);

// 输出矩特征

std::cout << "M00: " << moments.m00 << std::endl; // 零阶矩

std::cout << "M10: " << moments.m10 << std::endl; // 一阶矩

std::cout << "M01: " << moments.m01 << std::endl; // 一阶矩

std::cout << "M20: " << moments.m20 << std::endl; // 二阶矩

std::cout << "M02: " << moments.m02 << std::endl; // 二阶矩

// 其他高阶矩...

return 0;

}

在上述示例中,首先使用`cv::imread()`函数读取图像,并将其转换为灰度图像。然后,使用`cv::threshold()`函数对图像进行二值化处理,生成一个二值图像。接下来,使用`cv::moments()`函数计算二值图像的矩特征,并将结果保存在`Moments`结构体中。最后,输出一些矩特征的值。

3、Hu矩

Hu矩(Hu Moments)是一种描述图像形状的统计特征,由M. K. Hu在1962年提出。它是基于图像的中心矩计算得到的,具有旋转、平移和缩放不变性。

以下是使用OpenCV在Python中计算图像的Hu矩的示例代码:

import cv2

import numpy as np

# 读取图像

image = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)

# 对图像进行二值化处理

_, binaryImage = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)

# 计算图像的矩特征

moments = cv2.moments(binaryImage)

# 计算Hu矩

huMoments = cv2.HuMoments(moments)

huMoments = -np.sign(huMoments) * np.log10(np.abs(huMoments)) # 转换为对数形式

# 输出Hu矩

for i in range(7):

print("Hu{}: {}".format(i+1, huMoments[i][0]))

在上述示例中,我们首先使用`cv2.imread()`函数读取图像,并将其转换为灰度图像。然后,使用`cv2.threshold()`函数对图像进行二值化处理,生成一个二值图像。接下来,使用`cv2.moments()`函数计算二值图像的矩特征,并将结果保存在`moments`变量中。然后,使用`cv2.HuMoments()`函数计算Hu矩,并将结果保存在`huMoments`变量中。最后,通过遍历数组,输出每个Hu矩的值。

需要注意的是,Python中的OpenCV返回的Hu矩是以浮点数形式表示的,如果需要转换为通常的对数形式,可以使用`np.sign()`和`np.log10()`函数进行转换。

4、轮廓拟合

OpenCV中的轮廓拟合是指将检测到的图像轮廓近似地拟合为简单的几何形状,如直线、圆等。该功能可以用于形状分析、对象识别和边缘检测等应用。

在OpenCV中,有多种方法可用于轮廓拟合,常用的方法包括最小包围矩形、最小外接圆和多边形拟合。

1. 最小包围矩形:使用`cv2.minAreaRect()`函数计算轮廓的最小包围矩形,该矩形可以不与轮廓完全重合。

2. 最小外接圆:使用`cv2.minEnclosingCircle()`函数计算轮廓的最小外接圆,该圆将完全包含住轮廓。

3. 多边形拟合:使用`cv2.approxPolyDP()`函数对轮廓进行多边形拟合,可以通过指定一个精度参数来控制拟合精度。

下面是一个示例代码,展示了如何使用OpenCV进行轮廓拟合:

​
import cv2

# 读取图像并灰度化

image = cv2.imread("image.jpg")

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 边缘检测

edges = cv2.Canny(gray, 50, 150)

# 寻找轮廓

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

# 遍历每个轮廓

for contour in contours:

# 最小包围矩形

rect = cv2.minAreaRect(contour)

box = cv2.boxPoints(rect)

box = np.int0(box)

cv2.drawContours(image, [box], 0, (0, 255, 0), 2)

# 最小外接圆

(x, y), radius = cv2.minEnclosingCircle(contour)

center = (int(x), int(y))

radius = int(radius)

cv2.circle(image, center, radius, (0, 0, 255), 2)

# 多边形拟合

epsilon = 0.01 * cv2.arcLength(contour, True)

approx = cv2.approxPolyDP(contour, epsilon, True)

cv2.drawContours(image, [approx], 0, (255, 0, 0), 2)

# 显示结果图像

cv2.imshow("Contours", image)

cv2.waitKey(0)

cv2.destroyAllWindows()

​

在上述示例中,首先读取图像并将其转换为灰度图像。然后通过Canny边缘检测算法找到图像的边缘。接下来使用`cv2.findContours()`函数寻找轮廓。

在遍历每个轮廓时,我们分别使用`cv2.minAreaRect()`函数计算最小包围矩形,并使用`cv2.boxPoints()`函数将矩形转换为四个角点。然后使用`cv2.minEnclosingCircle()`函数计算最小外接圆的圆心和半径。最后,通过`cv2.approxPolyDP()`函数对轮廓进行多边形拟合,可以通过调整精度参数来控制拟合的精度。

最后,我们使用`cv2.drawContours()`函数将拟合结果绘制在原始图像上,并显示结果图像。

5、凸包

OpenCV中的凸包(Convex Hull)是指能够完全包围给定点集的最小凸多边形。它可以用于计算点集的外形以及检测图像中的手势、物体边界等应用。

在OpenCV中,可以使用`cv2.convexHull()`函数来计算给定点集的凸包。该函数接受一个点集作为输入,并返回一个表示凸包的点集或轮廓。

下面是一个示例代码,展示了如何使用OpenCV计算凸包:

import cv2

import numpy as np

# 读取图像并灰度化

image = cv2.imread("image.jpg")

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 边缘检测

edges = cv2.Canny(gray, 50, 150)

# 寻找轮廓

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

# 遍历每个轮廓

for contour in contours:

# 计算凸包

hull = cv2.convexHull(contour)

# 绘制凸包

cv2.drawContours(image, [hull], 0, (0, 255, 0), 2)

# 显示结果图像

cv2.imshow("Convex Hull", image)

cv2.waitKey(0)

cv2.destroyAllWindows()

在上述示例中,首先读取图像并将其转换为灰度图像。然后通过Canny边缘检测算法找到图像的边缘。接下来使用`cv2.findContours()`函数寻找轮廓。

在遍历每个轮廓时,我们使用`cv2.convexHull()`函数计算凸包。最后,使用`cv2.drawContours()`函数将凸包绘制在原始图像上,并显示结果图像。

需要注意的是,`cv2.convexHull()`函数可以接受不同的参数和标志,用于控制凸包计算的精度和输出形式。根据具体需求,可以使用不同的参数进行调整。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ironmao

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

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

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

打赏作者

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

抵扣说明:

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

余额充值