OpenCV—(你在找的)外接圆、外接矩形

目录

简介

代码实现

外接圆

外接矩阵


简介

在计算机视觉和图像处理中,使用外接圆和外接矩形绘制的目的是进行特定对象或区域的边界框标记,从而更容易识别、跟踪或测量这些对象。这些外接形状不仅提供了重要的定位和尺寸信息,还有助于减少处理的数据量,从而提高算法的效率。

代码实现

外接圆

cv2.circle()是OpenCV库中用于绘制圆的函数基本语法如下:

cv2.circle(image, center, radius, color, thickness, lineType, shift)

  • image: 这是要在其上绘制圆的图像。通常,你会将原始图像传递给这个参数,并且该函数将在原始图像上进行绘制,而不是创建一个新图像
  • center: 这是一个包含圆心坐标的元组 (x, y),其中 (x, y) 表示圆心的像素坐标。圆心是圆的中心点。

  • radius: 这是圆的半径,通常是一个正整数。它定义了圆的大小。

  • color: 这是绘制圆的颜色,通常是一个包含三个整数值的元组 (B, G, R),其中 B、G 和 R 分别表示蓝、绿和红通道的颜色强度。例如,(0, 255, 0) 表示绿色。

  • thickness(可选): 这是绘制圆的线宽度,通常是一个正整数。如果 thickness 为正,表示绘制实心圆,如果为负或零,表示绘制一个带有指定宽度的圆边框。通常,使用正整数值。

  • lineType(可选): 这是线的类型。默认情况下,它是8,表示八连接线。你通常不需要更改此参数,除非你需要特定类型的线。

  • shift(可选): 这是用于坐标位移的可选参数。通常不需要使用这个参数。

代码实现:

# 导入OpenCV库
import cv2

# 从文件加载图像(请确保文件存在于当前工作目录或提供正确的路径)
phone = cv2.imread('apple_phone.png')

# 转换图像为灰度图,以便后续处理
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)

# 应用阈值化,将图像转换为二值图像
# 阈值化将像素值大于 120 的像素置为 255(白色),小于等于 120 的像素置为 0(黑色)
ret, phone_thresh = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)

# 查找图像中的轮廓
# phone_thresh 是二值图像,RETR_TREE 表示检测所有轮廓,并构建轮廓的层次结构
# CHAIN_APPROX_NONE 表示不进行轮廓近似,保留所有轮廓上的点
image, contours, hierarchy = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

# 选择一个特定的轮廓(这里选择第 6 个轮廓,Python中的索引从0开始)
cnt = contours[5]

# 获取包围轮廓的最小圆
(x, y), r = cv2.minEnclosingCircle(cnt)

# 在原始图像上绘制最小外接圆
# (int(x), int(y)) 是圆心坐标,int(r) 是半径
# (0, 255, 0) 是圆的颜色,2 是绘制圆的线宽
phone_circle = cv2.circle(phone, (int(x), int(y)), int(r), (0, 255, 0), 2)

# 显示包含外接圆的图像
cv2.imshow('apple_phone.png', phone_circle)

# 显示图像,等待 10 秒后关闭窗口
cv2.waitKey(10000)

# 关闭所有打开的窗口
cv2.destroyAllWindows()

运行效果:

外接矩阵

cv2.rectangle() 是OpenCV库中用于绘制矩形的函数,它的基本语法如下:

cv2.rectangle(image, pt1, pt2, color, thickness, lineType, shift)

  • image: 这是要在其上绘制矩形的图像。通常,你会将原始图像传递给这个参数,并且该函数将在原始图像上进行绘制,而不是创建一个新图像。

  • pt1: 这是矩形的左上角坐标,通常是一个包含两个整数值的元组 (x1, y1),其中 (x1, y1) 表示左上角的像素坐标。

  • pt2: 这是矩形的右下角坐标,通常是一个包含两个整数值的元组 (x2, y2),其中 (x2, y2) 表示右下角的像素坐标。

  • color: 这是绘制矩形的颜色,通常是一个包含三个整数值的元组 (B, G, R),其中 B、G 和 R 分别表示蓝、绿和红通道的颜色强度。例如,(0, 255, 0) 表示绿色。

  • thickness(可选): 这是绘制矩形的线宽度,通常是一个正整数。如果 thickness 为正,表示绘制实心矩形,如果为负或零,表示绘制一个带有指定宽度的矩形边框。通常,使用正整数值。

  • lineType(可选): 这是线的类型。默认情况下,它是8,表示八连接线。你通常不需要更改此参数,除非你需要特定类型的线。

  • shift(可选): 这是用于坐标位移的可选参数。通常不需要使用这个参数。

代码实现:

# 导入OpenCV库
import cv2

# 从文件加载图像(请确保文件存在于当前工作目录或提供正确的路径)
phone = cv2.imread('apple_phone.png')

# 转换图像为灰度图,以便后续处理
phone_gray = cv2.cvtColor(phone, cv2.COLOR_BGR2GRAY)

# 应用阈值化,将图像转换为二值图像
# 阈值化将像素值大于 120 的像素置为 255(白色),小于等于 120 的像素置为 0(黑色)
ret, phone_thresh = cv2.threshold(phone_gray, 120, 255, cv2.THRESH_BINARY)

# 查找图像中的轮廓
# phone_thresh 是二值图像,RETR_TREE 表示检测所有轮廓,并构建轮廓的层次结构
# CHAIN_APPROX_NONE 表示不进行轮廓近似,保留所有轮廓上的点
image, contours, hierarchy = cv2.findContours(phone_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

# 选择一个特定的轮廓(在此示例中选择第7个轮廓,索引从0开始)
cnt = contours[6]

# 计算轮廓的最小外接矩形
x, y, w, h = cv2.boundingRect(cnt)

# 在图像上绘制矩形
phone_rectangle = cv2.rectangle(phone, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 显示带有矩形的图像
cv2.imshow('phone_rectangle', phone_rectangle)

# 等待10秒后关闭窗口
cv2.waitKey(10000)

# 关闭所有打开的窗口
cv2.destroyAllWindows()

运行结果:

### 如何使用 OpenCV 计算椭圆的外接矩形OpenCV 中,可以通过 `cv2.fitEllipse` 函数拟合一个椭圆到一组点上,并返回该椭圆的相关参数。为了获取这个椭圆的外接矩形,可以利用这些参数进一步计算其边界框。 以下是具体实现方法: #### 1. 拟合椭圆并提取参数 函数 `cv2.fitEllipse(points)` 可以用于拟合椭圆,其中输入是一个二维点集数组。它会返回一个元组 `(center, axes, angle)`,分别表示椭圆中心坐标、轴长度以及旋转角度[^1]。 ```python import numpy as np import cv2 # 假设 points 是一组轮廓点 points = np.array([[x1, y1], [x2, y2], ...]) # 替换为实际数据 ellipse = cv2.fitEllipse(points) (center, (width, height), angle) = ellipse ``` #### 2. 构造外接矩形 一旦得到了椭圆的信息,就可以通过构造一个围绕它的最小面积矩形来获得外接矩形。这一步可以直接调用 `cv2.boundingRect()` 或者更精确地使用 `cv2.minAreaRect()` 来得到旋转后的矩形。 对于非旋转版本(直角矩形),可采用以下代码: ```python rect = cv2.boundingRect(np.int32([points])) (x, y, w, h) = rect print(f"Bounding Rectangle: Top-left corner ({x}, {y}), Width={w}, Height={h}") ``` 如果需要考虑旋转情况,则应改用 `cv2.minAreaRect()` 方法: ```python rotated_rect = cv2.minAreaRect(points) box_points = cv2.boxPoints(rotated_rect) box_points = np.int0(box_points) print("Rotated Bounding Box Points:", box_points) ``` 上述两部分结合起来能够满足不同场景下对外接矩形的需求。 #### 完整示例代码 下面提供了一个完整的例子展示如何从给定的一系列点出发到它们所形成形状的最佳匹配椭圆及其对应的外接矩形。 ```python import cv2 import numpy as np def draw_ellipse_and_bounding_box(image_path): img = cv2.imread(image_path, 0) _, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:] if not contours: print("No contours detected.") return None cnt = max(contours, key=cv2.contourArea) ellipse = cv2.fitEllipse(cnt) center, axes, angle = ellipse result_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2.ellipse(result_img, ellipse, (0, 255, 0), 2) # Draw fitted ellipse rotated_rect = cv2.minAreaRect(cnt) box_points = cv2.boxPoints(rotated_rect) box_points = np.int0(box_points) cv2.drawContours(result_img,[box_points],0,(255,0,0),2) # Draw min area rectangle straight_rect = cv2.boundingRect(cnt) x,y,w,h = straight_rect cv2.rectangle(result_img,(x,y),(x+w,y+h),(0,0,255),2) # Draw bounding rectangle return result_img result = draw_ellipse_and_bounding_box('your_image.png') if result is not None: cv2.imshow('Result', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 此脚本读入一幅灰度图,在二值化之后查最大连通域作为目标对象,接着绘制出相应的椭圆与两种类型的包围盒。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值