You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV:如何创建任意角度的腐蚀核以提取特定方向直线

通用角度腐蚀核实现方案

问题背景

我有一张包含水平、垂直、对角线、交叉对角线等多种角度直线的图像,现有代码可通过预设核矩阵筛选固定方向的直线,但无法处理任意角度的直线。需要修改代码中的TO DO区域,创建一个可自定义角度的通用腐蚀核,简化不同方向直线的处理流程。

输入图像:
输入图像

输出示例(以90度垂直直线为例):
输出示例

修改后的完整代码

import cv2
import numpy as np
%matplotlib inline 
from matplotlib import pyplot as plt

# 定义Jupyter环境下的图像显示函数
def showimage(title,myimage):
    # 彩色图像转换OpenCV的BGR格式为RGB
    if (myimage.ndim>2):  
        myimage = myimage[:,:,::-1]  
         
    fig, ax = plt.subplots(figsize=(6,6))
    ax.imshow(myimage, cmap = 'gray', interpolation = 'bicubic')
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴刻度
    plt.title(title)
    plt.show()

# 加载图像
imfile = 'multilines.jpg'
image = cv2.imread(imfile)  
showimage('Original',image)

# 转为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Canny边缘检测
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

### 原固定方向核(保留作为参考,可注释)
kernel_h = np.array([[0, 0, 0],
                   [1, 1, 1],
                   [0, 0, 0]], dtype=np.uint8)

kernel_v = np.array([[0, 1, 0],
                   [0, 1, 0],
                   [0, 1, 0]], dtype=np.uint8)

kernel_d = np.array([[1, 0, 0],
                     [0, 1, 0],
                     [0, 0, 1]], dtype=np.uint8)

kernel_crossd = np.array([[0, 0, 1],
                     [0, 1, 0],
                     [1, 0, 0]], dtype=np.uint8)

# 注释原固定核选择,改用通用角度核
# kernel = kernel_h; tag = 'Horizontal'
# kernel = kernel_v; tag = 'Vertical'
# kernel = kernel_d; tag = 'Diagonal'
# kernel = kernel_crossd; tag = 'Cross-diagonal'

# TO DO begins ----------------------
# 生成通用角度依赖的腐蚀核
theta_deg = 90  # 可修改为任意角度(单位:度),0度为水平向右,逆时针旋转为正
theta = np.deg2rad(theta_deg)

# 定义3x3大小的核
kernel_size = 3
kernel_angle = np.zeros((kernel_size, kernel_size), dtype=np.uint8)
center = (kernel_size // 2, kernel_size // 2)

# 计算角度对应的方向向量,取整得到偏移量
dx = np.cos(theta)
dy = np.sin(theta)
offset_x = int(round(dx))
offset_y = int(round(dy))

# 填充核的三个点:中心 + 对称的两个端点
kernel_angle[center[0], center[1]] = 1  # 中心像素
if offset_x != 0 or offset_y != 0:
    # 第一个端点
    x1 = center[0] + offset_y
    y1 = center[1] + offset_x
    # 第二个端点(与第一个端点关于中心对称)
    x2 = center[0] - offset_y
    y2 = center[1] - offset_x
    # 确保坐标在核范围内(避免越界)
    if 0 <= x1 < kernel_size and 0 <= y1 < kernel_size:
        kernel_angle[x1, y1] = 1
    if 0 <= x2 < kernel_size and 0 <= y2 < kernel_size:
        kernel_angle[x2, y2] = 1

kernel = kernel_angle ; tag = f'Generic angle-based ({theta_deg} degrees)'
# TO DO ends ------------------------

print(f'{tag} erosion applied.')

# 腐蚀操作提取目标直线
erosion_lines = cv2.erode(edges, kernel, iterations=1)
showimage('After erosion',erosion_lines)

# 反转颜色得到白底黑线条的结果
result = cv2.bitwise_not(erosion_lines)

# 显示最终结果
showimage('Final',result)

实现说明

  • 角度定义:以水平向右为0度,逆时针旋转为正方向,直接修改theta_deg即可设置任意角度(如30°、60°、135°等)
  • 核生成逻辑:以3x3核的中心为原点,根据角度计算方向向量,取整后确定直线上的另外两个对称端点,将这三个位置设为1,其余为0,形成对应角度的直线型腐蚀核
  • 兼容性:生成的核与原固定方向核完全匹配(如0°对应水平核、90°对应垂直核、45°对应对角线核),同时支持任意角度的直线筛选

内容的提问来源于stack exchange,提问作者hbaromega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:52:34