获取接触图像边缘的线的点
Get points of a line that touch the edge of the image
我需要帮助才能获得在图像矩阵中绘制直线的真正“起点”和“终点”。在下面的示例中,检测到的线使用 y0 和 y1 显示。
import numpy as np
from skimage.transform import hough_line, hough_line_peaks
from skimage.feature import canny
from skimage import data
import matplotlib.pyplot as plt
from matplotlib import cm
# Constructing test image
image = np.zeros((200, 200))
idx = np.arange(0, 200)
image[idx, idx//2] = 255
imgOriginal = image.copy()
# Classic straight-line Hough transform
# Set a precision of 0.5 degree.
tested_angles = np.linspace(-np.pi / 2, np.pi / 2, 360)
h, theta, d = hough_line(image, theta=tested_angles)
# Generating figure 1
fig, axes = plt.subplots(1, 3, figsize=(15, 6))
ax = axes.ravel()
ax[0].imshow(image, cmap=cm.gray)
ax[0].set_title('Input image')
ax[0].set_axis_off()
ax[1].imshow(np.log(1 + h),
extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]],
cmap=cm.gray, aspect=1/1.5)
ax[1].set_title('Hough transform')
ax[1].set_xlabel('Angles (degrees)')
ax[1].set_ylabel('Distance (pixels)')
ax[1].axis('image')
ax[2].imshow(image, cmap=cm.gray)
origin = np.array((0, image.shape[1]))
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle)
print('y0 = {} y1 = {}'.format(y0, y1))
ax[2].plot(origin, (y0, y1), '-r')
ax[2].set_xlim(origin)
ax[2].set_ylim((image.shape[0], 0))
ax[2].set_axis_off()
ax[2].set_title('Detected lines')
plt.tight_layout()
plt.show()
此代码导致:
我想要的是在真实的图像矩阵中得到以下几个点:
这很可能是 (0,0) 和 (199, 100)
总而言之,我想将 y0 和 y1 转换为我的 numpy 矩阵中的实数点。
你的问题本质上是找到两条直线的交点。一条是您给定的线,另一条是图像边缘定义的线。
这可以按照解释的方式完成 here。我借用了第一个答案中的代码。定义这些函数 -
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
raise Exception('lines do not intersect')
d = (det(*line1), det(*line2))
x = det(d, xdiff) / div
y = det(d, ydiff) / div
return x, y
按如下方式更改循环 -
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle)
print('y0 = {} y1 = {}'.format(y0, y1))
ax[2].plot(origin, (y0, y1), '-r')
l1 = ((origin[0], y0), (origin[1], y1))
l2 = ((0, 200), (200, 200))
print(line_intersection(l1, l2))
这显然是假设感兴趣的线总是与图像的下边缘相交。如果该线与右边缘相交,则必须相应地修改 l2
。在实践中,我建议找到与两条边的交点并选择“最近”的交点。
这还假设感兴趣的线总是从图像的左上角开始(正如您定义的问题)。如果不是这种情况,您需要对图像的所有四个边缘执行此操作并选择前两个相交。
我需要帮助才能获得在图像矩阵中绘制直线的真正“起点”和“终点”。在下面的示例中,检测到的线使用 y0 和 y1 显示。
import numpy as np
from skimage.transform import hough_line, hough_line_peaks
from skimage.feature import canny
from skimage import data
import matplotlib.pyplot as plt
from matplotlib import cm
# Constructing test image
image = np.zeros((200, 200))
idx = np.arange(0, 200)
image[idx, idx//2] = 255
imgOriginal = image.copy()
# Classic straight-line Hough transform
# Set a precision of 0.5 degree.
tested_angles = np.linspace(-np.pi / 2, np.pi / 2, 360)
h, theta, d = hough_line(image, theta=tested_angles)
# Generating figure 1
fig, axes = plt.subplots(1, 3, figsize=(15, 6))
ax = axes.ravel()
ax[0].imshow(image, cmap=cm.gray)
ax[0].set_title('Input image')
ax[0].set_axis_off()
ax[1].imshow(np.log(1 + h),
extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]],
cmap=cm.gray, aspect=1/1.5)
ax[1].set_title('Hough transform')
ax[1].set_xlabel('Angles (degrees)')
ax[1].set_ylabel('Distance (pixels)')
ax[1].axis('image')
ax[2].imshow(image, cmap=cm.gray)
origin = np.array((0, image.shape[1]))
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle)
print('y0 = {} y1 = {}'.format(y0, y1))
ax[2].plot(origin, (y0, y1), '-r')
ax[2].set_xlim(origin)
ax[2].set_ylim((image.shape[0], 0))
ax[2].set_axis_off()
ax[2].set_title('Detected lines')
plt.tight_layout()
plt.show()
此代码导致:
我想要的是在真实的图像矩阵中得到以下几个点:
这很可能是 (0,0) 和 (199, 100)
总而言之,我想将 y0 和 y1 转换为我的 numpy 矩阵中的实数点。
你的问题本质上是找到两条直线的交点。一条是您给定的线,另一条是图像边缘定义的线。
这可以按照解释的方式完成 here。我借用了第一个答案中的代码。定义这些函数 -
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
raise Exception('lines do not intersect')
d = (det(*line1), det(*line2))
x = det(d, xdiff) / div
y = det(d, ydiff) / div
return x, y
按如下方式更改循环 -
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle)
print('y0 = {} y1 = {}'.format(y0, y1))
ax[2].plot(origin, (y0, y1), '-r')
l1 = ((origin[0], y0), (origin[1], y1))
l2 = ((0, 200), (200, 200))
print(line_intersection(l1, l2))
这显然是假设感兴趣的线总是与图像的下边缘相交。如果该线与右边缘相交,则必须相应地修改 l2
。在实践中,我建议找到与两条边的交点并选择“最近”的交点。
这还假设感兴趣的线总是从图像的左上角开始(正如您定义的问题)。如果不是这种情况,您需要对图像的所有四个边缘执行此操作并选择前两个相交。