经过指定点的直线检测

目录

方法0:

方法1

方法2


方法0:

import cv2
import numpy as np

def detect_lines_through_point(image, point_a, theta_step=1, epsilon=1):
    # 转换为灰度图像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 使用Canny边缘检测
    edges = cv2.Canny(gray, 50, 150)
    # 获取边缘点的坐标
    y_coords, x_coords = np.where(edges > 0)
    if len(x_coords) == 0 or len(y_coords) == 0:
        return []
    
    x0, y0 = point_a  # 指定点a的坐标
    thetas = np.deg2rad(np.arange(0, 180, theta_step))  # 角度范围及步长
    cos_t = np.cos(thetas)
    sin_t = np.sin(thetas)
    
    # 计算点a对应的所有rho值
    rho_a = x0 * cos_t + y0 * sin_t
    
    # 向量化计算所有边缘点的rho值
    x_col = x_coords.reshape(-1, 1)
    y_col = y_coords.reshape(-1, 1)
    rho_points = x_col * cos_t + y_col * sin_t
    
    # 判断是否满足直线方程(考虑误差epsilon)
    matches = np.abs(rho_points - rho_a) <= epsilon
    accumulator = np.sum(matches, axis=0)
    
    # 寻找得票最多的theta
    best_theta_idx = np.argmax(accumulator)
    best_theta = thetas[best_theta_idx]
    
    # 计算直线端点(延长至图像边界)
    a = np.cos(best_theta)
    b = np.sin(best_theta)
    x0, y0 = point_a
    height, width = image.shape[:2]
    
    # 计算直线与图像边界的交点
    if b != 0:
        # 直线斜率存在
        x1 = 0
        y1 = int((rho_a[best_theta_idx] - x1 * a) / b)
        x2 = width
        y2 = int((rho_a[best_theta_idx] - x2 * a) / b)
        # 确保交点位于图像内
        pts = []
        if y1 >= 0 and y1 < height:
            pts.append((x1, y1))
        if y2 >= 0 and y2 < height:
            pts.append((x2, y2))
        if len(pts) < 2:
            y1 = 0
            x1 = int((rho_a[best_theta_idx] - y1 * b) / a)
            if x1 >= 0 and x1 < width:
                pts.append((x1, y1))
            y2 = height - 1
            x2 = int((rho_a[best_theta_idx] - y2 * b) / a)
            if x2 >= 0 and x2 < width:
                pts.append((x2, y2))
        if len(pts) >= 2:
            (x_start, y_start), (x_end, y_end) = pts[:2]
        else:
            return []
    else:
        # 垂直线处理
        x_start = int(rho_a[best_theta_idx] / a)
        y_start = 0
        x_end = x_start
        y_end = height - 1
    
    return [(x_start, y_start, x_end, y_end)]

# 示例用法
image = cv2.imread('your_image.jpg')
if image is None:
    raise FileNotFoundError("Image not found")

point_a = (100, 100)  # 替换为你的指定点坐标
detected_lines = detect_lines_through_point(image, point_a, theta_step=1, epsilon=2)

# 绘制检测到的直线
for line in detected_lines:
    x_start, y_start, x_end, y_end = line
    cv2.line(image, (x_start, y_start), (x_end, y_end), (0, 255, 0), 2)

cv2.imshow('Detected Line', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

方法1

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

# 给定的点 A(x1, y1)
x1, y1 = 200, 150  # 例如指定的点是(200, 150)

# 读取图像并转为灰度图
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)

# 应用 Canny 边缘检测
edges = cv2.Canny(image, 50, 150)

# 使用 Hough 变换检测直线
# 这将返回检测到的直线的极坐标表示 (rho, theta)
lines = cv2.HoughLines(edges, 1, np.pi / 180, 150)

# 创建一个副本来显示结果
output_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)

# 画出检测到的直线
if lines is not None:
    for line in lines:
        rho, theta = line[0]
        
        # 计算直线的两个端点(极坐标转直角坐标)
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho
        x1 = int(x0 + 1000 * (-b))
        y1 = int(y0 + 1000 * (a))
        x2 = int(x0 - 1000 * (-b))
        y2 = int(y0 - 1000 * (a))

        # 确保直线通过指定的点 A(x1, y1)
        # 计算该点在直线方程中的位置(调整线的截距)
        # 如果直线需要调整,重新计算斜率和截距使其通过A(x1, y1)

        # 计算斜率 m 和截距 b
        if x2 - x1 != 0:
            m = (y2 - y1) / (x2 - x1)
            b_adjusted = y1 - m * x1
            # 通过新的斜率和截距绘制调整后的直线
            x_line_start = 0
            y_line_start = int(m * x_line_start + b_adjusted)
            x_line_end = image.shape[1]
            y_line_end = int(m * x_line_end + b_adjusted)
            cv2.line(output_image, (x_line_start, y_line_start), (x_line_end, y_line_end), (0, 0, 255), 2)

# 显示最终结果
plt.imshow(cv2.cvtColor(output_image, cv2.COLOR_BGR2RGB))
plt.title('Line Detection with Point A')
plt.show()

方法2

import cv2
import numpy as np

# 给定的点 A(x1, y1)
x1, y1 = 200, 150  # 例如指定的点是(200, 150)

# 读取图像并转为灰度图
image = cv2.imread('your_image.jpg', cv2.IMREAD_GRAYSCALE)

# 检查图像是否正确加载
if image is None:
    print("图像加载失败,请检查路径")
    exit()

# 应用 Canny 边缘检测
edges = cv2.Canny(image, 50, 150)

# 使用 Hough 变换检测直线(霍夫变换返回的是极坐标表示)
lines = cv2.HoughLines(edges, 1, np.pi / 180, 150)

# 创建一个副本来显示结果
output_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)

# 如果检测到直线,绘制它们
if lines is not None:
    for line in lines:
        rho, theta = line[0]

        # 计算直线的两个端点(极坐标转直角坐标)
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho
        x2 = int(x0 + 1000 * (-b))
        y2 = int(y0 + 1000 * (a))
        x1_line = int(x0 - 1000 * (-b))
        y1_line = int(y0 - 1000 * (a))

        # 确保直线通过指定的点 A(x1, y1)
        # 计算直线的斜率 m 和截距 b
        if x2 - x1_line != 0:
            m = (y2 - y1_line) / (x2 - x1_line)
            b_adjusted = y1 - m * x1

            # 使用新的斜率 m 和截距 b 绘制直线
            x_line_start = 0
            y_line_start = int(m * x_line_start + b_adjusted)
            x_line_end = image.shape[1]
            y_line_end = int(m * x_line_end + b_adjusted)

            # 绘制调整后的直线(通过指定点 A(x1, y1))
            cv2.line(output_image, (x_line_start, y_line_start), (x_line_end, y_line_end), (0, 0, 255), 2)

# 绘制指定点 A
cv2.circle(output_image, (x1, y1), 5, (0, 255, 0), -1)

# 显示结果图像
cv2.imshow('Line Detection through Point A', output_image)

# 等待按键并关闭
cv2.waitKey(0)
cv2.destroyAllWindows()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AI算法网奇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值