pyplot模块介绍opencv的python实现

本文介绍如何使用Matplotlib的subplot函数创建子图,并展示了如何在不同的子图中显示图像直方图和原始图像。同时,通过imshow函数演示了不同色彩空间的图像显示效果。

subplot函数

subplot(2, 3, 4),函数表示在当前的两行三列的窗口的第四个位置上,添加一个窗口,见示例代码如下

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('../data/1.jpg', 0)

plt.figure('original')
plt.subplot(2, 3, 4)  
plt.hist(img.ravel(), 256)

plt.subplot(231)  # 如果行数和列数不大于10,可以省略行数和列数和窗口序号的逗号
plt.hist(img.ravel(), 256)
plt.show()

imshow函数

该函数有两个参数,第一个参数是图像信息,可以是各种形式的数值
第二个参数表示色彩空间,默认值是null,默认使用RGB(A)色彩空间
代码示例如下

import cv2
import numpy as np
import matplotlib.pyplot as plt

img_bgr = cv2.imread('../data/1.jpg', 0)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
plt.figure('original')
plt.subplot(121)
plt.imshow(img_bgr)  # 第二个参数默认使用RGB色彩空间
plt.axis('off')  # 表示关闭坐标轴的显示
plt.subplot(122)
plt.imshow(img_rgb)
plt.axis('off')
plt.show()  # 一直显示知道交互用户自己关闭

生活需要不断做选择,这些看不见的看得见的选择组成我们的人生
你希望拥有过一个怎么样的人生和生活其实决定选择权完全取决于你
我是个孩子,我还在前行,直到后来我才发现,其实好人需要更多的克制

<think>好的,用户现在让我用OpenCVPython实现圆弧拟合。之前他已经了解了圆弧拟合的基本概念和方法,现在需要具体的代码实现。我需要先回顾一下之前提到的步骤,然后确定如何在Python中应用这些方法。 首先,用户可能需要的是用最小二乘法或者几何优化的方法来拟合圆弧。不过,OpenCV本身可能没有直接的圆弧拟合函数,但可以用一些现有的函数或者结合numpy来实现。记得之前提到过代数拟合(最小二乘)和非线性优化两种方法,用户可能希望看到这两种方法的实现,或者至少一种有效的方法。 接下来,考虑OpenCV中常用的函数。例如,cv2.fitEllipse可以拟合椭圆,如果数据点接近圆弧,拟合椭圆后可以近似为圆。不过这可能不够精确,因为椭圆参数可能需要转换成圆的参数,但可能是一个快速的方法。另外,用户可能需要更精确的圆弧拟合,这时候可能需要自己实现最小二乘法。 另一个方法是使用scipy的优化库来进行非线性最小二乘优化,但这可能超出了OpenCV的范围。不过用户明确提到要用OpenCVPython,所以可能需要结合numpy和OpenCV的绘图功能。 首先,我需要确定用户的需求:是否希望使用纯OpenCV函数,还是可以结合其他库如numpy和scipy。可能用户希望尽可能用OpenCV,但实际中可能需要numpy来处理矩阵运算。 然后,考虑实现步骤。根据之前的介绍,代数拟合的步骤包括构建线性方程组,使用最小二乘求解D、E、F,然后转换为圆心和半径。这部分可以用numpy的线性代数模块实现。而几何优化可能需要使用scipy中的优化函数,如leastsq或curve_fit,但用户可能希望避免额外的依赖。 所以,可能需要先实现代数拟合的最小二乘法,然后可能提到几何优化作为改进方法。同时,用户可能还需要如何用OpenCV绘制拟合后的圆弧,这需要计算起点和终点角度,并用cv2.ellipse函数来绘制,因为OpenCV没有直接画圆弧的函数,但可以指定起始和结束角度,以及椭圆参数,如果是圆的话,长轴和短轴相等。 接下来,我需要考虑代码的结构。首先生成一些测试数据点,可能是在某个圆弧上的点,加上一些噪声。然后应用代数拟合方法计算圆心和半径,然后绘制这些点和拟合的圆弧。 可能的步骤: 1. 生成模拟数据点,加入噪声。 2. 使用代数最小二乘法拟合圆心和半径。 3. 计算起始和终止角度,可能需要将点转换到极坐标,找出最小和最大角度。 4. 使用OpenCV绘制拟合的圆弧。 需要注意的是,拟合出的圆是否正确,如何处理数据点中的异常值,可能需要RANSAC来改进鲁棒性,但用户可能暂时只需要基础实现。 可能的代码结构: - 导入库:cv2, numpy, matplotlib(用于显示) - 生成数据点:在某个圆心和半径下生成角度范围内的点,添加噪声。 - 定义拟合函数:实现代数最小二乘拟合,得到圆心和半径。 - 计算起始和结束角度:将点转换到极坐标,找到角度范围。 - 绘制结果:用OpenCV绘制圆和圆弧,或者用matplotlib显示。 此外,需要注意OpenCV的坐标系统和图像的显示,可能需要创建一个空白图像,在上面画点和圆弧。 现在,具体到代码实现: 代数拟合部分,根据之前的步骤,将方程变形为x² + y² + Dx + Ey + F = 0,构建矩阵A,其中每行是[x, y, 1],右侧是-(x² + y²)。然后求解A的伪逆,得到D, E, F,进而得到圆心和半径。 然后,计算每个点相对于圆心的角度,用numpy的arctan2函数,排序后找到起始和终止角度。 绘制时,由于OpenCV的cv2.ellipse函数可以接受中心点、轴长(如果是圆,则两个轴相等)、旋转角度(0)、起始和结束角度,以及是否闭合。所以可以用这个函数来画圆弧。 不过,测试数据生成时,可能需要注意点的生成方式,例如生成在某个圆弧上的点,带有随机噪声。 最后,验证拟合结果的准确性,可能通过计算误差或者可视化检查。 可能的错误点:在构建线性方程组时,是否正确处理了方程的形式;极角计算是否正确;以及起始和结束角度的处理,尤其是当角度超过180度或负值时,需要调整到0-360度范围,或者根据点的分布来正确确定。 另外,用户可能需要处理实际数据,而不仅仅是模拟数据,但示例代码中使用模拟数据可以方便演示。 总结代码步骤: 1. 导入必要的库。 2. 创建模拟圆弧数据点。 3. 使用最小二乘法拟合圆参数。 4. 计算起始和终止角度。 5. 绘制点和拟合的圆弧。 现在将这些步骤转化为具体的Python代码,并确保使用OpenCV进行绘制。</think>以下是使用 OpenCVPython 实现圆弧拟合的示例代码,包含**代数拟合(最小二乘法)**和**圆弧绘制**的完整流程: --- ### **代码实现** ```python import cv2 import numpy as np import matplotlib.pyplot as plt # 生成模拟圆弧数据点(带噪声) def generate_arc_points(center, radius, start_angle, end_angle, num_points=50, noise=5): angles = np.linspace(np.deg2rad(start_angle), np.deg2rad(end_angle), num_points) x = center[0] + radius * np.cos(angles) + np.random.normal(0, noise, num_points) y = center[1] + radius * np.sin(angles) + np.random.normal(0, noise, num_points) return np.column_stack((x, y)).astype(np.float32) # 最小二乘法拟合圆弧 def fit_circle_least_squares(points): x = points[:, 0] y = points[:, 1] A = np.vstack([x, y, np.ones_like(x)]).T b = -(x**2 + y**2) D, E, F = np.linalg.lstsq(A, b, rcond=None)[0] a = -D / 2 b = -E / 2 r = np.sqrt(a**2 + b**2 - F) return (a, b), r # 计算圆弧的起始和终止角度(相对于圆心) def calculate_arc_angles(points, center): dx = points[:, 0] - center[0] dy = points[:, 1] - center[1] angles = np.degrees(np.arctan2(dy, dx)) # 转换为角度 [-180, 180] angles = np.where(angles < 0, angles + 360, angles) # 转换为 [0, 360) start_angle = np.min(angles) end_angle = np.max(angles) return start_angle, end_angle # 主程序 if __name__ == "__main__": # 生成模拟数据 true_center = (300, 300) true_radius = 150 points = generate_arc_points(true_center, true_radius, 30, 270, noise=10) # 拟合圆弧 fitted_center, fitted_radius = fit_circle_least_squares(points) start_angle, end_angle = calculate_arc_angles(points, fitted_center) # 创建空白图像 img = np.zeros((600, 600, 3), dtype=np.uint8) # 绘制原始数据点 for pt in points: cv2.circle(img, tuple(map(int, pt)), 2, (0, 255, 0), -1) # 绘制拟合的圆弧(使用椭圆函数模拟圆弧) cv2.ellipse( img, tuple(map(int, fitted_center)), (int(fitted_radius), int(fitted_radius)), 0, # 旋转角度 start_angle, end_angle, (0, 0, 255), 2 ) # 显示结果 plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.title("Arc Fitting with OpenCV") plt.show() ``` --- ### **代码说明** 1. **生成模拟数据**: - `generate_arc_points` 生成带噪声的圆弧点集,参数包括圆心、半径、起止角度和噪声强度。 2. **最小二乘法拟合**: - `fit_circle_least_squares` 通过代数方法求解圆心和半径,核心是构建线性方程组并使用 `np.linalg.lstsq` 求解。 3. **角度计算**: - `calculate_arc_angles` 将数据点转换为极坐标系,计算起始和终止角度,确保角度范围在 [0°, 360°)。 4. **可视化**: - 使用 OpenCV 的 `cv2.ellipse` 绘制圆弧,通过指定相同的长轴和短轴长度模拟圆形。 --- ### **效果演示** - **绿色点**:带噪声的原始数据点。 - **红色圆弧**:拟合结果,圆心和半径通过最小二乘法计算得到。 --- ### **改进建议** 1. **抗噪优化**:若数据含大量离群点,可集成 **RANSAC 算法**(示例见下方代码片段)。 2. **几何优化**:使用 `scipy.optimize.least_squares` 进一步优化圆心和半径(需安装 SciPy)。 ```python # RANSAC 示例(需安装 scikit-learn) from sklearn.linear_model import RANSACRegressor def fit_circle_ransac(points): model = RANSACRegressor(min_samples=3, residual_threshold=10) x, y = points[:, 0], points[:, 1] A = np.vstack([x, y, np.ones_like(x)]).T b = -(x**2 + y**2) model.fit(A, b) D, E, F = model.estimator_.coef_ a = -D / 2 b = -E / 2 r = np.sqrt(a**2 + b**2 - F) return (a, b), r ``` --- 通过上述代码,可快速实现圆弧拟合并在图像中可视化结果。根据实际需求选择代数拟合或鲁棒性更强的 RANSAC 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值