机器视觉入门:5分钟搞懂像素坐标系与图像坐标系的转换(附Python代码)

# 机器视觉坐标转换实战:从像素到世界的完整链路解析与Python实现 刚接触机器视觉,面对一堆“坐标系”是不是有点头大?像素坐标、图像坐标、相机坐标、世界坐标……这些概念听起来抽象,但在实际项目里,比如让机械臂精准抓取、让自动驾驶汽车识别路标,坐标转换是绕不开的核心技术。很多新手卡在这里,不是因为原理多难,而是缺少一个能把所有环节串起来、并且能立刻上手验证的实战指南。今天,我们就抛开复杂的数学推导,直接从“用”的角度出发,手把手带你打通从图像上一个像素点到真实三维空间中一个点的完整坐标转换链路。我会用最直白的语言解释每个坐标系“是什么”、“为什么需要它”,并附上每一步都可独立运行的Python代码。读完本文,你不仅能彻底理解这背后的逻辑,更能获得一套可以直接嵌入到你项目中的工具代码。 ## 1. 坐标系基础:为什么需要这么多“系”? 在深入转换公式之前,我们必须先理解每个坐标系存在的意义。机器视觉的本质,是通过二维的图像去理解和测量三维的世界。这个过程就像翻译,需要把不同“语言”(坐标系)下的信息,按照一套明确的规则进行转换。 想象一个最简单的场景:你用手机拍了一张桌面上水杯的照片。你的目标是让机械臂去拿起这个水杯。 * **像素坐标系**:这是你的“起点”。照片在计算机里就是一个数字矩阵,每个元素(像素)有它的行号和列号 `(u, v)`。这个坐标系的原点在图像的**左上角**,u轴向右,v轴向下。它只告诉你“水杯在图片的哪个像素位置”,但不知道这个位置对应真实世界的多大尺寸。 * **图像坐标系**:为了建立像素和物理尺寸的联系,我们引入了图像坐标系 `(x, y)`。它的原点通常在图像的**中心**(或主点),单位是**毫米(mm)**。这个坐标系建立了图像平面上的物理尺度。知道了相机镜头的焦距 `f` 和每个像素的物理尺寸 `dx, dy`,我们就能把像素位置换算到图像平面上的物理位置。 * **相机坐标系**:这是一个三维坐标系 `(Xc, Yc, Zc)`,原点在相机的光心。Zc轴沿着光轴指向拍摄场景,Xc轴和Yc轴分别与图像坐标系的x轴和y轴平行。它的作用是将图像平面上的二维点 `(x, y)` 反向投影到相机前方的一条三维空间射线上。**记住一个关键点:从三维的相机坐标到二维的图像坐标,是一个有信息损失的投影过程(丢掉了深度Zc);而反过来,从二维图像坐标恢复三维信息,则需要额外的约束(如双目视觉或已知物体尺寸)。** * **世界坐标系**:这是描述我们真实场景的绝对三维坐标系 `(Xw, Yw, Zw)`。它的原点和方向可以根据需要任意定义,比如定义在房间的某个角落。相机在真实世界中的位置和姿态是任意的,因此需要将相机坐标系下的点,通过旋转和平移,转换到统一的世界坐标系下,这样才能让机械臂等执行机构理解“水杯在真实世界的哪个位置”。 下表清晰地概括了这四个坐标系的核心特征与作用: | 坐标系 | 维度 | 原点位置 | 单位 | 核心作用 | | :--- | :--- | :--- | :--- | :--- | | **像素坐标系** | 2D | 图像左上角 | 像素 (pixel) | 图像数据的直接存储与访问格式。 | | **图像坐标系** | 2D | 图像中心(主点) | 毫米 (mm) | 建立像素与物理尺寸的桥梁,是连接像素与相机三维空间的中间层。 | | **相机坐标系** | 3D | 相机光心 | 毫米 (mm) | 描述以相机为中心的三维空间,是透视投影的几何模型所在。 | | **世界坐标系** | 3D | 场景中任意设定点 | 毫米 (mm) | 描述真实场景的绝对空间,是所有视觉感知结果的最终输出坐标系。 | > 提示:理解坐标转换,本质上就是理解**数据在不同表示层之间的流动**。从采集(像素)、到成像几何建模(图像、相机)、再到与真实世界对齐(世界),每一步转换都对应一个明确的物理或几何意义。 ## 2. 核心转换一:像素坐标系与图像坐标系 这是最基础,也是最先需要掌握的转换。我们直接从公式和代码入手。 **转换原理** 像素坐标 `(u, v)` 到图像坐标 `(x, y)` 的转换,核心是确定两个参数:图像中心(主点)在像素坐标系中的坐标 `(u0, v0)`,以及每个像素在x和y方向上的物理尺寸 `dx` 和 `dy`(单位:mm/pixel)。`dx` 和 `dy` 通常可以从相机的传感器规格书中查到,或者通过相机标定获得。 转换公式非常直观: * `x = (u - u0) * dx` * `y = (v - v0) * dy` 反之,从图像坐标到像素坐标: * `u = x / dx + u0` * `v = y / dy + v0` **Python实战代码** 假设我们有一张分辨率为 `1920x1080` 的图像,相机传感器单个像素的物理尺寸是 `0.00345 mm x 0.00345 mm`(一个常见的尺寸),并且我们假设图像中心就是主点。 ```python import numpy as np def pixel_to_image_coord(u, v, u0, v0, dx, dy): """ 将像素坐标转换为图像坐标(物理坐标,单位:mm) 参数: u, v: 像素坐标 u0, v0: 主点坐标(像素坐标系下) dx, dy: 单个像素的物理尺寸 (mm/pixel) 返回: x, y: 图像坐标 (mm) """ x = (u - u0) * dx y = (v - v0) * dy return x, y def image_to_pixel_coord(x, y, u0, v0, dx, dy): """ 将图像坐标转换为像素坐标 参数: x, y: 图像坐标 (mm) u0, v0, dx, dy: 同上 返回: u, v: 像素坐标(通常需要取整) """ u = x / dx + u0 v = y / dy + v0 return int(round(u)), int(round(v)) # 示例参数 image_width = 1920 image_height = 1080 u0, v0 = image_width / 2, image_height / 2 # 假设主点在图像中心 dx = dy = 0.00345 # mm/pixel # 示例1:将图像左上角(0,0)像素点转换到图像坐标系 x_top_left, y_top_left = pixel_to_image_coord(0, 0, u0, v0, dx, dy) print(f"像素(0,0)对应的图像坐标: ({x_top_left:.4f} mm, {y_top_left:.4f} mm)") # 输出应为负值,因为左上角在中心点的左上方 # 示例2:将图像中心点转换到图像坐标系(结果应接近(0,0)) x_center, y_center = pixel_to_image_coord(u0, v0, u0, v0, dx, dy) print(f"图像中心对应的图像坐标: ({x_center:.4f} mm, {y_center:.4f} mm)") # 示例3:反向转换,验证一致性 u_test, v_test = image_to_pixel_coord(x_top_left, y_top_left, u0, v0, dx, dy) print(f"反向转换回的像素坐标: ({u_test}, {v_test})") ``` 运行这段代码,你会直观地看到像素位置如何被转换到以毫米为单位的物理平面上。这是后续所有三维重建和测量的基石。 ## 3. 核心转换二:图像坐标系与相机坐标系 这一步引入了三维空间。图像坐标系是相机坐标系在成像平面(距离光心焦距 `f` 处)上的投影。 **透视投影模型(小孔成像模型)** 这是机器视觉中最基础的几何模型。根据相似三角形原理,相机坐标系中的一点 `P(Xc, Yc, Zc)` 投影到图像平面上的点 `p(x, y)` 满足: * `x = f * Xc / Zc` * `y = f * Yc / Zc` 这里 `f` 是相机的焦距(单位:mm)。注意,这里的 `(x, y)` 正是我们在上一节得到的图像坐标(单位:mm)。 这个公式告诉我们一个关键事实:**仅凭一个二维图像点 `(x, y)`,我们无法唯一确定其对应的三维点 `(Xc, Yc, Zc)`**,因为深度信息 `Zc` 丢失了。所有位于射线 `(s*x, s*y, s*f)`(s为任意大于0的尺度因子)上的三维点,都会投影到同一个图像点 `(x, y)`。 **从二维图像点反推三维射线** 虽然无法得到唯一的三维点,但我们可以得到该点在相机坐标系下所在的那条射线方向。这对于双目视觉或PnP(Perspective-n-Point)问题至关重要。 ```python def image_to_camera_ray(x, y, f): """ 根据图像坐标点,计算其在相机坐标系下对应的归一化射线方向向量。 参数: x, y: 图像坐标 (mm) f: 相机焦距 (mm) 返回: ray_dir: 归一化的三维方向向量 [Xc, Yc, Zc] """ # 根据透视投影公式反推:Xc/Zc = x/f, Yc/Zc = y/f # 令 Zc = 1(或其他任意值,这里取1方便计算方向),则 Xc = x/f, Yc = y/f Xc = x / f Yc = y / f Zc = 1.0 # 构成三维向量并归一化 ray = np.array([Xc, Yc, Zc]) ray_dir = ray / np.linalg.norm(ray) return ray_dir # 示例参数 focal_length = 50.0 # 假设焦距为50mm # 假设我们在图像坐标系中有一个点 (10mm, 5mm) x_img, y_img = 10.0, 5.0 ray_direction = image_to_camera_ray(x_img, y_img, focal_length) print(f"图像点({x_img}mm,{y_img}mm)对应的相机坐标系射线方向: {ray_direction}") ``` > 注意:这里的 `ray_direction` 只给出了方向。要得到具体的三维坐标,必须知道该点的深度 `Zc`。`Zc` 可以通过双目立体匹配、结构光、激光雷达或已知物体尺寸等方法获得。 ## 4. 核心转换三:相机坐标系与世界坐标系 相机可能被安装在机器人末端、汽车顶部或生产线的支架上,它的位置和朝向(姿态)是任意的。世界坐标系是我们定义的固定参考系。两者之间的转换是一个三维刚体变换,包含旋转和平移。 **旋转矩阵R与平移向量T** 设一个点在世界坐标系下的坐标为 `P_w = [Xw, Yw, Zw]^T`,在相机坐标系下的坐标为 `P_c = [Xc, Yc, Zc]^T`,它们之间的关系是: `P_c = R * P_w + t` 或者写成齐次坐标形式更清晰: `[P_c; 1] = [R, t; 0, 1] * [P_w; 1]` 其中 `R` 是一个 `3x3` 的正交旋转矩阵,`t` 是一个 `3x1` 的平移向量。`R` 和 `t` 合称为相机的外参。 **外参的获取与应用** 相机外参通常通过“手眼标定”或“相机标定”过程来确定。标定时,我们会使用一个已知三维尺寸的标定板(如棋盘格),通过图像识别得到标定板角点在图像上的像素坐标,再结合其已知的世界坐标,求解出 `R` 和 `t`。 ```python def transform_world_to_camera(point_world, R, t): """ 将世界坐标系下的点转换到相机坐标系。 参数: point_world: 世界坐标系下的3D点,形状 (3,) 或 (3,1) R: 3x3旋转矩阵 t: 3x1平移向量 返回: point_camera: 相机坐标系下的3D点 """ point_world = np.array(point_world).reshape(3, 1) point_camera = R @ point_world + t return point_camera.flatten() def transform_camera_to_world(point_camera, R, t): """ 将相机坐标系下的点转换到世界坐标系。 参数: point_camera: 相机坐标系下的3D点 R, t: 外参 返回: point_world: 世界坐标系下的3D点 """ point_camera = np.array(point_camera).reshape(3, 1) # 注意:逆变换是 point_world = R^T * (point_camera - t) point_world = R.T @ (point_camera - t) return point_world.flatten() # 示例:假设一个简单的场景,相机绕Z轴旋转了30度,并沿X轴平移了100mm theta = np.radians(30) # 30度转弧度 # 绕Z轴的旋转矩阵 R = np.array([ [np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.cos(theta), 0], [0, 0, 1] ]) t = np.array([100, 0, 0]).reshape(3, 1) # 平移100mm # 世界坐标系下的一个点 P_w = np.array([50, 20, 500]) # 假设一个深度为500mm的点 # 转换到相机坐标系 P_c = transform_world_to_camera(P_w, R, t) print(f"世界坐标点 {P_w} 在相机坐标系下为: {P_c}") # 再转换回世界坐标系进行验证 P_w_back = transform_camera_to_world(P_c, R, t) print(f"转换回世界坐标系: {P_w_back} (应与原始值接近)") ``` ## 5. 完整链路:从世界坐标到像素坐标 现在,我们把前面所有步骤串联起来,实现从真实世界中的一个三维点,到最终在图像上呈现的像素位置的完整计算。这对应了相机的成像过程。 **综合转换矩阵(相机模型)** 整个过程可以表示为一系列矩阵乘法,通常封装成相机内参矩阵 `K` 和外参矩阵 `[R|t]`。 1. **内参矩阵 K**:包含了焦距 `fx=f/dx`, `fy=f/dy` 和主点 `(u0, v0)` 的信息,负责将**相机坐标系**下的三维点(单位mm)投影到**像素坐标系**。 ``` K = [[fx, 0, u0], [ 0, fy, v0], [ 0, 0, 1]] ``` > 注意:这里 `fx, fy` 是以像素为单位的焦距。因为 `x/dx = (f*Xc/Zc)/dx = (f/dx)*(Xc/Zc) = fx*(Xc/Zc)`。 2. **外参矩阵 [R|t]**:负责将**世界坐标系**下的点转换到**相机坐标系**。 因此,从齐次世界坐标 `[Xw, Yw, Zw, 1]^T` 到齐次像素坐标 `[u, v, 1]^T` 的完整公式为: `s * [u, v, 1]^T = K * [R | t] * [Xw, Yw, Zw, 1]^T` 其中 `s` 是一个非零的尺度因子(实际上就是相机坐标系下的深度 `Zc`)。 **Python实现完整投影** ```python def project_world_to_pixel(point_world, K, R, t): """ 将世界坐标系下的3D点投影到像素坐标系。 参数: point_world: 世界坐标系下的3D点 (3,) K: 3x3相机内参矩阵 R: 3x3旋转矩阵 t: 3x1平移向量 返回: u, v: 投影后的像素坐标 depth: 点在相机坐标系下的深度Zc(可用于筛选可见点) """ point_world_h = np.append(point_world, 1).reshape(4, 1) # 齐次坐标 # 外参矩阵 extrinsic = np.hstack((R, t)) # 转换到相机坐标系 point_camera_h = extrinsic @ point_world_h # 形状 (3,1) Xc, Yc, Zc = point_camera_h.flatten() # 检查深度是否为正(点在相机前方) if Zc <= 0: return None, None, Zc # 投影到归一化图像平面 x_norm = Xc / Zc y_norm = Yc / Zc # 通过内参矩阵转换到像素坐标 pixel_h = K @ np.array([x_norm, y_norm, 1]).reshape(3, 1) u, v = pixel_h[0, 0], pixel_h[1, 0] return int(round(u)), int(round(v)), Zc # 定义相机参数(示例值) fx = fy = 50.0 / 0.00345 # 焦距50mm / 像素尺寸0.00345mm = 约14493 pixels u0, v0 = 960, 540 # 假设主点在图像中心 (1920/2, 1080/2) K = np.array([ [fx, 0, u0], [0, fy, v0], [0, 0, 1] ]) # 使用之前定义的外参 R, t # 世界坐标系下的点 P_w_test = np.array([0, 0, 1000]) # 在世界坐标系原点前方1000mm的点 u_proj, v_proj, depth = project_world_to_pixel(P_w_test, K, R, t) if u_proj is not None: print(f"世界点 {P_w_test} 投影到像素坐标: ({u_proj}, {v_proj}), 深度: {depth:.2f} mm") # 由于相机在X方向平移了100mm,这个点不会正好在图像中心 else: print("点在相机后方,不可见。") ``` 通过这个完整的链路,你就能精确计算出真实世界中任何一个已知三维点,在你相机画面中应该出现在哪个像素位置。这在增强现实(AR)、视觉伺服、三维重建等应用中至关重要。 ## 6. 实战应用:单目视觉尺寸测量 理解了坐标转换,我们来看一个经典应用:在已知物体某个维度真实尺寸的情况下,利用单目相机测量其距离或其他维度尺寸。 **应用场景**:已知一个矩形物体的宽度 `W_world`(单位:mm),并且它在图像中水平放置。我们通过图像处理找到了它在图像中左右边缘的像素坐标 `u_left` 和 `u_right`。如何计算该物体到相机的距离 `Zc`? **原理与步骤** 1. 将左右边缘的像素坐标 `(u_left, v)` 和 `(u_right, v)` 转换到图像坐标系,得到 `x_left` 和 `x_right`。 2. 在图像坐标系下,物体的宽度 `W_image = |x_right - x_left|` (mm)。 3. 根据透视投影的相似三角形关系,有:`W_image / W_world = f / Zc`。 * 推导:`x = f * Xc / Zc`,所以 `Δx = f * ΔXc / Zc`。其中 `Δx = W_image`, `ΔXc = W_world`。 4. 因此,距离 `Zc = f * W_world / W_image`。 ```python def estimate_distance_from_width(u_left, u_right, v, W_world, K, dx): """ 根据已知物体宽度和其在图像中的像素跨度,估计物体到相机的距离。 参数: u_left, u_right: 物体左右边缘的像素u坐标 v: 物体的v坐标(取同一行即可) W_world: 物体的真实宽度 (mm) K: 相机内参矩阵 dx: 像素物理尺寸 (mm/pixel),用于从K中提取f 返回: Zc_est: 估计的物体深度 (mm) """ # 从内参矩阵K中提取以像素为单位的焦距fx fx = K[0, 0] # 计算以mm为单位的焦距 f = fx * dx f = fx * dx # 将像素宽度转换为图像坐标系下的宽度 (mm) # 方法1:通过主点u0和dx计算 u0 = K[0, 2] x_left = (u_left - u0) * dx x_right = (u_right - u0) * dx W_image = abs(x_right - x_left) # 方法2:更直接地,利用 fx。因为 Δu (像素) * dx = Δx (mm),且 fx = f/dx # 所以 f = fx * dx, 且 W_image = Δu * dx # 代入公式 Zc = f * W_world / W_image = (fx * dx) * W_world / (Δu * dx) = fx * W_world / Δu # 因此可以直接用像素差Δu计算,更简洁且避免dx误差: Zc_est_pixel_method = fx * W_world / abs(u_right - u_left) # 使用方法1的公式计算 if W_image > 0: Zc_est = f * W_world / W_image else: Zc_est = None print(f"方法1(使用物理尺寸)估计深度: {Zc_est:.2f} mm") print(f"方法2(直接使用fx和像素差)估计深度: {Zc_est_pixel_method:.2f} mm") # 理论上两者应相等,实际中方法2更常用,因为fx由标定直接得到,精度更高。 return Zc_est_pixel_method # 模拟数据:假设图像中检测到一个物体,左右边缘像素u=700, u=1200,真实宽度为200mm u_l, u_r = 700, 1200 v_mid = 540 true_width = 200.0 # mm Z_estimated = estimate_distance_from_width(u_l, u_r, v_mid, true_width, K, dx) print(f"最终采用的估计距离: {Z_estimated:.2f} mm") ``` 这个例子展示了坐标转换知识如何解决一个具体的实际问题。关键在于理解 `fx`(像素焦距)这个内参的物理意义:它直接关联了物体在图像上的像素跨度与其真实尺寸、实际距离的比例关系。 ## 7. 常见陷阱与调试技巧 理论清晰了,但实际编码和应用中总会遇到各种问题。这里分享几个我踩过的坑和调试方法。 **1. 坐标轴方向混淆** 这是最常见的问题。务必牢记: * **像素坐标系**:原点在**左上角**,v轴**向下**。OpenCV等库的图像处理函数默认使用此坐标系。 * **图像/相机坐标系**:通常遵循右手或左手坐标系,但Y轴方向可能与像素坐标系相反。在推导公式时,要确保符号一致。一个简单的验证方法是:用一个已知的简单场景(如正前方的点)代入你的公式,看计算结果是否符合预期。 **2. 单位不统一** * **焦距 `f`**:内参矩阵 `K` 中的 `fx, fy` 单位是**像素**。而物理焦距 `f` 单位是**毫米**。它们通过 `dx, dy` 关联:`fx = f / dx`。在调用OpenCV的 `calibrateCamera` 等函数时,它返回的内参矩阵 `K` 中的焦距就是像素单位。 * **平移向量 `t`**:其单位应与世界坐标单位一致(通常是毫米)。如果标定板输入的单位是米,那么 `t` 的单位也是米。 **3. 外参矩阵的旋转顺序与意义** 旋转矩阵 `R` 描述了从世界坐标系到相机坐标系的旋转。旋转有多种表示法(欧拉角、轴角、四元数、旋转矩阵)。不同库(如OpenCV, ROS, Eigen)对欧拉角的定义(旋转轴顺序)可能不同。务必使用一致的约定,并在将欧拉角转换为旋转矩阵 `R` 时格外小心。一个实用的调试方法是:计算旋转矩阵的行列式,其值应非常接近 `1`(正交矩阵),且所有特征值的模应接近 `1`。 **4. 投影验证与反向投影** 调试坐标转换代码时,一个黄金法则是:**正向投影后再反向投影,看是否能回到原点(在一定误差内)**。 1. 假设一个世界点 `P_w`。 2. 用你的 `K`, `R`, `t` 将其投影到像素坐标 `(u, v)`。 3. 再假设你通过某种方式(如双目视觉)得到了该点的深度 `Zc`。 4. 利用像素坐标 `(u, v)` 和深度 `Zc`,结合 `K` 和 `R, t` 的逆变换,反算出世界坐标 `P_w'`。 5. 比较 `P_w` 和 `P_w'` 的差异。如果转换正确,差异应非常小。 ```python def reprojection_error_check(P_w, K, R, t, Zc_ground_truth=None): """验证投影和反投影的闭合误差""" # 1. 正向投影 u_proj, v_proj, Zc_calc = project_world_to_pixel(P_w, K, R, t) if u_proj is None: print("点不可见,无法验证。") return # 2. 反向投影(需要深度信息,这里使用计算出的或提供的真实深度) Zc_used = Zc_ground_truth if Zc_ground_truth is not None else Zc_calc # 步骤:像素 -> 归一化相机坐标 -> 相机坐标 -> 世界坐标 # 2.1 像素到归一化相机坐标 uv_h = np.array([u_proj, v_proj, 1]).reshape(3, 1) point_norm = np.linalg.inv(K) @ uv_h # [x_norm, y_norm, 1]^T x_norm, y_norm = point_norm[0, 0], point_norm[1, 0] # 2.2 归一化坐标到相机坐标 (利用深度Zc) Xc = x_norm * Zc_used Yc = y_norm * Zc_used P_c_recon = np.array([Xc, Yc, Zc_used]).reshape(3, 1) # 2.3 相机坐标到世界坐标 P_w_recon = transform_camera_to_world(P_c_recon, R, t) # 3. 计算误差 error = np.linalg.norm(P_w - P_w_recon) print(f"原始世界点: {P_w.flatten()}") print(f"反投影世界点: {P_w_recon.flatten()}") print(f"重投影误差 (欧氏距离): {error:.6f} mm") return error # 使用前面的示例点进行验证 reprojection_error_check(P_w_test.reshape(3,1), K, R, t) ``` 如果误差很大,就需要逐步检查每一步的转换:内参 `K` 是否正确?外参 `R`, `t` 的旋转平移方向是否符合你的设定?深度值 `Zc` 是否准确? 掌握坐标转换,就掌握了机器视觉空间感知的钥匙。它不像深度学习模型那样有那么多“黑盒”,每一步都有清晰的几何意义。多动手写代码验证,用简单的数据(比如让相机正对着世界坐标系原点)去测试你的每一个函数,直到对每个数字的来龙去脉都了然于胸。在实际项目中,大部分时间可能花在如何稳定、精确地获取那些转换参数(内参、外参)上,但只要你底层原理扎实,调试和解决问题就有了明确的方向。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

Python内容推荐

python-opencv 机器视觉 质心,形心 坐标 颜色分拣

python-opencv 机器视觉 质心,形心 坐标 颜色分拣

python-opencv 机器视觉 质心,形心 坐标 颜色分拣 ,程序功能为区分物体颜色,算出物体在图像中的坐标,使用了十字,菱形,方形,X形去噪处理

机器视觉 python 实验报告

机器视觉 python 实验报告

实验一 数字图像的基本操作及灰度调整 (1)利用 opencv-python 读取一幅彩色图像,并读取图像的基本信息; (2)对彩色图像进行灰度化处理;对灰度图像进行二值化处理; (3)对图像进行几何变换(缩放,平移,翻转); (4)储存处理后的图像。 实验二 数字图像的空间域滤波 (1)线性点运算中比较不同 a 值下图像增强的效果; (2)非线性点运算中比较不同γ值下图像增强的效果; (3)实现基于直方图均衡化的图像增强,包括灰度图像和彩色图像。 实验三 数字图像的形态学处理及边缘检测 1.用 OpenCV 实现数字图像的形态学运算,提取图像分量信息最本质的形状特征,不同运算操作的能实现的目的; 2.用 OpenCV 编写一个程序实现基于微分算子的边缘检测,并比较各微分检测算子的优劣;要求给出膨胀、腐蚀、开、闭、梯度等运算操作的效果图。 实验四 基于分水岭算法的图像分割方法 1.利用 opencv-python 读取灰度图像,并进行噪声消除; 2.对图像进行形态学处理,区分背景区域和未知区域; 3.使用距离变换获取确定的前景色,并对确定的确定前景图像进行标注;

python机器视觉免费学习资源

python机器视觉免费学习资源

python机器视觉免费学习资源

使用python去除图片白色像素的实例

使用python去除图片白色像素的实例

今天小编就为大家分享一篇使用python去除图片白色像素的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

基于python tensorflow opencv图像处理入门程序代码

基于python tensorflow opencv图像处理入门程序代码

基于python tensorflow opencv图像处理入门程序代码

基于python_机器视觉_双目测距_设计与实现

基于python_机器视觉_双目测距_设计与实现

基于python_机器视觉_双目测距_设计与实现

Python图像灰度变换及图像数组操作

Python图像灰度变换及图像数组操作

主要介绍了Python图像灰度变换及图像数组操作的相关资料,需要的朋友可以参考下

ROF图像降噪处理python程序

ROF图像降噪处理python程序

python编写的ROF图像降噪程序,代码全面,亲测可行,降噪效果优与一般的图像降噪方法,对图像处理研究者有一定帮助。

python机器视觉学习opencv实验作业,OpenCV图像滤波,投影,车牌字符,Python-OpenCV宽度测量,缺陷检测

python机器视觉学习opencv实验作业,OpenCV图像滤波,投影,车牌字符,Python-OpenCV宽度测量,缺陷检测

python机器视觉学习opencv实验作业 OpenCV-Python安装 实验二、OpenCV图像滤波 实验四、投影 实验5车牌字符 实验6、Python-OpenCV宽度测量 实验七、缺陷检测

基于Python的机器视觉实验教学平台设计.zip

基于Python的机器视觉实验教学平台设计.zip

基于Python的机器视觉实验教学平台设计

数字图像处理实验(Python版本)--20221

数字图像处理实验(Python版本)--20221

3. Opencv 版本:3.x 版本应该都可以 1.数字图像的表示和类别 2.OpenCV 图像文件格式 1.下面给出示例程序 1.熟悉并学会 opencv-

python 图片二值化处理(处理后为纯黑白的图片)

python 图片二值化处理(处理后为纯黑白的图片)

主要介绍了python 图片二值化处理(处理后为纯黑白的图片),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

基于python的图像增强与去噪算法设计与实现

基于python的图像增强与去噪算法设计与实现

基于python的图像增强与去噪算法设计与实现

基于 DDPM 的光伏功率时序场景生成方法研究(Python代码实现)

基于 DDPM 的光伏功率时序场景生成方法研究(Python代码实现)

内容概要:本文系统研究了基于去噪概率扩散模型(DDPM)的光伏功率时序场景生成方法,提出了一种利用Python实现的高精度、强波动性光伏出力场景生成框架。文章深入解析了DDPM的核心机制,包括前向扩散过程与反向去噪过程的数学原理,并结合真实光伏功率数据进行模型训练与采样,有效捕捉了光照强度、气象条件等外部因素导致的功率波动特性。相较于传统的蒙特卡洛模拟和生成对抗网络(GAN)等方法,该方法在保持时间序列相关性、统计分布一致性和场景多样性方面表现出更强的能力,特别适用于高比例可再生能源接入背景下的电力系统规划、运行调度与风险评估。此外,文档还整合了大量相关科研资源,涵盖W-GAN、条件GAN、联邦学习、电动汽车承载力评估等多个前沿方向,构建了一个面向新能源场景生成与电力系统优化的综合性技术生态体系。; 适合人群:具备一定Python编程能力和机器学习理论基础,从事新能源发电预测、电力系统优化、智能算法应用等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于电力系统中光伏出力不确定性的精细化建模与多场景生成,支撑含高比例可再生能源的调度决策、规划分析与风险评估;②为学术研究提供可复现、易扩展的DDPM模型代码框架,推动扩散模型在能源领域时间序列生成任务中的落地与创新;③结合文中提供的Matlab/Python开源资源,拓展至风电功率预测、负荷场景生成、电动汽车接入优化等交叉研究方向,促进多学科融合创新。; 阅读建议:建议读者结合文档中提供的完整代码资源(可通过公众号“荔枝科研社”获取)进行动手实践,优先透彻理解DDPM的算法流程与关键模块设计后再迁移至具体应用场景。同时可参考文中列出的相关论文复现项目,逐步构建完整的科研知识体系和技术积累路径。

复现电表数据隐私保护下的联邦学习行业电力负荷预测框架(Python代码实现)

复现电表数据隐私保护下的联邦学习行业电力负荷预测框架(Python代码实现)

内容概要:本文提出了一种面向电表数据隐私保护的联邦学习行业电力负荷预测框架,通过Python代码实现,解决了多参与方在数据孤岛和隐私受限条件下难以协同建模的问题。该框架基于联邦学习机制,允许多个电力用户或企业在不共享原始用电数据的前提下,共同训练高性能的负荷预测模型。文中详细介绍了系统架构设计、本地模型训练流程、全局参数聚合策略以及差分隐私等隐私保护技术的融合方法,有效保障了数据安全性,同时提升了行业级负荷预测的准确性与泛化能力,适用于电力公司、工业园区等多方协作的分布式预测场景。; 适合人群:具备一定Python编程基础和机器学习知识,从事电力系统分析、能源管理、智能电网或数据隐私保护相关研究的研发人员及高校研究生。; 使用场景及目标:①应用于跨企业、跨区域的电力负荷协同预测任务;②解决传统集中式预测因数据隐私问题导致的模型训练障碍;③推动联邦学习在能源领域的实际落地,实现安全、高效、合规的行业智能化升级。; 阅读建议:读者应结合提供的Python代码进行动手实践,重点理解联邦学习的通信机制、本地模型更新方式与全局聚合逻辑,并可通过构建多客户端仿真环境来验证框架的收敛性、预测性能及隐私保护效果。

机器视觉入门教程

机器视觉入门教程

非常详细的教程,自动化及视觉工程师入门必看的教程,也可作为高校研究所用。

图像处理与机器视觉-实验一

图像处理与机器视觉-实验一

本人报告独自撰写,请读者勿泄露其中个人信息相关,十分感谢。

图像处理、分析与机器视觉

图像处理、分析与机器视觉

此为图像处理、分析与机器视觉的随书代码

机器视觉读图片代码

机器视觉读图片代码

机器视觉读图片代码,机器视觉课程的课后大作业

机器视觉笔记

机器视觉笔记

本人在看B站上机器视觉视频教程是记得笔记,主要是基于TensorFlow和opencv,编程环境使用的是jupyter notebook

最新推荐最新推荐

recommend-type

python批量截取视频某一帧图片可控制图片大小

用python tkinter开发的一个可以批量截取MP4视频的小工具,有界面可以直接操作(需要python环境)
recommend-type

Python视频编辑库MoviePy的使用

主要介绍了Python视频编辑库MoviePy的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
recommend-type

moviepy:使用Python进行视频编辑

moviepy:使用Python进行视频编辑
recommend-type

python+ffmpeg批量去视频开头的方法

今天小编就为大家分享一篇python+ffmpeg批量去视频开头的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
recommend-type

python进行视频字幕视频和合成

利用讯飞的语音转写api进行转写、movieby模块进行音频截取,FFMPEG进行合并。需要申请讯飞的api,免费有5个小时
recommend-type

学生成绩管理系统C++课程设计与实践

资源摘要信息:"学生成绩信息管理系统-C++(1).doc" 1. 系统需求分析与设计 在进行学生成绩信息管理系统开发前,首先需要进行系统需求分析,这是确定系统开发目标与范围的过程。需求分析应包括数据需求和功能需求两个方面。 - 数据需求分析: - 学生成绩信息:需要收集学生的姓名、学号、课程成绩等数据。 - 数据类型和长度:明确每个数据项的数据类型(如字符串、整型等)和长度,例如学号可能是字符串类型且长度为一定值。 - 描述:详细描述每个数据项的意义,以确保系统能够准确处理。 - 功能需求分析: - 列出功能列表:用户界面应提供清晰的操作指引,列出所有可用功能。 - 查询学生成绩:系统应能通过学号或姓名查询学生的成绩信息。 - 增加学生成绩信息:允许用户添加未保存的学生成绩信息。 - 删除学生成绩信息:能够通过学号或姓名删除已经保存的成绩信息。 - 修改学生成绩信息:通过学号或姓名修改已有的成绩记录。 - 退出程序:提供安全退出程序的选项,并确保所有修改都已保存。 2. 系统设计 系统设计阶段主要完成内存数据结构设计、数据文件设计、代码设计、输入输出设计、用户界面设计和处理过程设计。 - 内存数据结构设计: - 使用链表结构组织内存中的数据,便于动态增删查改操作。 - 数据文件设计: - 选择文本文件存储数据,便于查看和编辑。 - 代码设计: - 根据功能需求,编写相应的函数和模块。 - 输入输出设计: - 设计简洁明了的输入输出提示信息和操作流程。 - 用户界面设计: - 用户界面应为字符界面,方便在命令行环境下使用。 - 处理过程设计: - 设计数据处理流程,确保每个操作都有明确的处理逻辑。 3. 系统实现与测试 实现阶段需要根据设计阶段的成果编写程序代码,并进行系统测试。 - 程序编写: - 完成系统设计中所有功能的程序代码编写。 - 系统测试: - 设计测试用例,通过测试用例上机测试系统。 - 记录测试方法和测试结果,确保系统稳定可靠。 4. 设计报告撰写 最后,根据系统开发的各个阶段,撰写详细的设计报告。 - 系统描述:包括问题说明、数据需求和功能需求。 - 系统设计:详细记录内存数据结构设计、数据文件设计、代码设计、输入/输出设计、用户界面设计、处理过程设计。 - 系统测试:包括测试用例描述、测试方法和测试结果。 - 设计特点、不足、收获和体会:反思整个开发过程,总结经验和教训。 时间安排: - 第19周(7月12日至7月16日)完成项目。 - 7月9日8:00到计算机学院实验中心(三楼)提交程序和课程设计报告。 指导教师和系主任(或责任教师)需要在文档上签名确认。 系统需求分析: - 使用表格记录系统需求分析的结果,包括数据项、数据类型、数据长度和描述。 - 分析数据项如学生成绩信息、状态器、链表节点等,确定其属性和行为。 以上就是文档中提到的学生成绩信息管理系统开发的关键知识点。开发此类系统需要熟练掌握C++编程基础,了解面向对象的程序设计思想,以及熟悉文件操作和链表等数据结构的应用。此外,良好的软件开发流程意识、测试意识和文档撰写能力也是必不可少的。
recommend-type

别再手动拖拽了!用Lumerical脚本批量创建FDTD仿真结构(附完整代码)

# 告别低效建模:Lumerical脚本自动化实战指南 在光子学仿真领域,时间就是科研生命线。当同行还在GUI界面里反复点击菜单时,你已经用脚本批量生成了20组参数化结构——这不是未来场景,而是每位FDTD用户都应该掌握的基础生产力革命。本文将彻底改变你与Lumerical的交互方式,从手动拖拽的农耕时代,跃迁到自动化建模的工业文明。 ## 1. 为何脚本建模是必然选择 2019年Nature Photonics的一项研究显示,科研工作者在仿真工具上平均浪费37%的时间在重复性操作上。对于需要参数扫描的纳米光学结构设计,这个数字可能更高。手动创建10个不同尺寸的纳米柱阵列意味着: -
recommend-type

Java邮件解析任务中,如何安全高效地提取HTML邮件内容并避免硬编码、资源泄漏和类型转换异常?

<think>我们被要求优化一段Java代码,该代码用于处理邮件(特别是来自特定发件人的构建通知邮件)。代码的主要问题包括: 1. 重复获取邮件内容:在检查MIME类型后,多次调用`msg[i].getContent()`,这可能导致性能问题或流关闭异常。 2. 类型转换问题:直接将邮件内容转换为`Multipart`而不进行类型检查,可能引发`ClassCastException`。 3. 代码结构问题:逻辑嵌套过深,可读性差,且存在重复代码(如插入邮件详情的操作在两个地方都有)。 4. 硬编码和魔法值:例如在解析HTML表格时使用了硬编码的索引(如list3.get(10)),这容易因邮件
recommend-type

RH公司应收账款管理优化策略研究

资源摘要信息:"本文针对RH公司的应收账款管理问题进行了深入研究,并提出了改进策略。文章首先分析了应收账款在企业管理中的重要性,指出其对于提高企业竞争力、扩大销售和充分利用生产能力的作用。然后,以RH公司为例,探讨了公司应收账款管理的现状,并识别出合同管理、客户信用调查等方面的不足。在此基础上,文章提出了一系列改善措施,包括完善信用政策、改进业务流程、加强信用调查和提高账款回收力度。特别强调了建立专门的应收账款回收部门和流程的重要性,并建议在实际应用过程中进行持续优化。同时,文章也意识到企业面临复杂多变的内外部环境,因此提出的策略需要根据具体情况调整和优化。 针对财务管理领域的专业学生和从业者,本文提供了一个关于应收账款管理问题的案例研究,具有实际指导意义。文章还探讨了信用管理和征信体系在应收账款管理中的作用,强调了它们对于提升企业信用风险控制和市场竞争能力的重要性。通过对比国内外企业在应收账款管理上的差异,文章总结了适合中国企业实际环境的应收账款管理方法和策略。" 根据提供的文件内容,以下是详细的知识点: 1. 应收账款管理的重要性:应收账款作为企业的一项重要资产,其有效管理关系到企业的现金流、财务健康以及市场竞争力。不良的应收账款管理会导致资金链断裂、坏账损失增加等问题,严重影响企业的正常运营和长远发展。 2. 应收账款的信用风险:在信用交易日益频繁的商业环境中,企业必须对客户信用进行评估,以便采取合理的信用政策,降低信用风险。 3. 合同管理的薄弱环节:合同是应收账款管理的法律基础,严格的合同管理能够保障企业权益,减少因合同问题导致的应收账款风险。 4. 客户信用调查:了解客户的信用状况对于预测和控制应收账款风险至关重要。企业需要建立有效的客户信用调查机制,识别和筛选信用良好的客户。 5. 应收账款回收策略:企业应建立有效的账款回收机制,包括定期的账款跟进、逾期账款的催收等。同时,建立专门的应收账款回收部门可以提升回收效率。 6. 应收账款管理流程优化:通过改进企业内部管理流程,如简化审批流程、提高工作效率等措施,能够提升应收账款的管理效率。 7. 应收账款管理策略的调整和优化:由于企业的内外部环境复杂多变,因此制定的管理策略需要根据实际情况进行动态调整和持续优化。 8. 信用管理和征信体系的作用:建立和完善企业内部信用管理体系和征信体系,有助于企业更好地控制信用风险,并在市场竞争中占据有利地位。 9. 对比国内外应收账款管理实践:通过研究国内外企业在应收账款管理上的不同做法和经验,可以借鉴先进的管理理念和方法,提升国内企业的应收账款管理水平。 综上所述,本文深入探讨了应收账款管理的多个方面,为RH公司乃至其他同类型企业提供了应收账款管理的改进方向和策略,对于财务管理专业的教育和实践都具有重要的参考价值。
recommend-type

新手别慌!用BingPi-M2开发板带你5分钟搞懂Tina Linux SDK目录结构

# 新手别慌!用BingPi-M2开发板带你5分钟搞懂Tina Linux SDK目录结构 第一次拿到BingPi-M2开发板时,面对Tina Linux SDK里密密麻麻的文件夹,我完全不知道从哪下手。就像走进一个陌生的大仓库,每个货架上都堆满了工具和零件,却找不到操作手册。这种困惑持续了整整两天,直到我意识到——理解目录结构比死记硬背每个文件更重要。 ## 1. 为什么SDK目录结构如此重要 想象你正在组装一台复杂的模型飞机。如果所有零件都混在一个箱子里,你需要花大量时间寻找每个螺丝和面板。但如果有分门别类的隔层,标注着"机身部件"、"电子设备"、"紧固件",组装效率会成倍提升。Ti