英文:
Cube Edge detection
问题
我试图使用Scikit-Image库中的Hough变换获取下面图像中立方体的边缘。
更新
这是我正在使用的代码:
smoothed_image = filters.frangi(gray_image)
# 使用Canny边缘检测器进行边缘检测
低阈值 = 0.1
高阈值 = 3
低阈值 = 低 * smoothed_image.max()
高阈值 = 高 * 低阈值
edges = canny(smoothed_image, sigma, low_threshold=低阈值,
high_threshold=高阈值)
# 使用Hough变换检测丝状物轮廓
hspace, theta, dist = hough_line(edges)
# 找到垂直线
vertical_peaks = hough_line_peaks(hspace, theta, dist, num_peaks=2)
vertical_lines = []
for _, angle, dist in zip(*vertical_peaks):
x = dist * np.cos(angle)
y = dist * np.sin(angle)
vertical_lines.append((x, y))
# 可视化结果
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(smoothed_image)
axes[0].set_title('平滑后的图像')
#axes[0].axis('off')
axes[1].imshow(edges, cmap='gray')
axes[1].set_title('Canny边缘检测')
axes[1].axis('off')
axes[2].imshow(edges, cmap='gray')
for x, y in vertical_lines:
axes[2].axvline(x=x, color='red')
axes[2].set_xlim((0, image.shape[1]))
axes[2].set_ylim((image.shape[0], 0))
axes[2].set_title('检测到的线条')
axes[2].axis('off')
plt.tight_layout()
plt.show()
有关如何使Hough变换检测到另一条边的任何想法吗?
英文:
I am trying to get the edges of a cube in the image below using the Hough transform in the Scikit-Image library .
Update
Here is the code I am working with:
smoothed_image = filters.frangi(gray_image)
# Perform edge detection using the Canny edge detector
low_threshold = 0.1
high_threshold = 3
low_threshold = low * smoothed_image.max()
high_threshold = high * low_threshold
edges = canny(smoothed_image, sigma, low_threshold=low_threshold,
high_threshold=high_threshold)
# Hough transform to detect the filament profile
hspace, theta, dist = hough_line(edges)
# Find the vertical lines
vertical_peaks = hough_line_peaks(hspace, theta, dist, num_peaks=2)
vertical_lines = []
for _, angle, dist in zip(*vertical_peaks):
x = dist * np.cos(angle)
y = dist * np.sin(angle)
vertical_lines.append((x, y))
# Visualize the results
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(smoothed_image)
axes[0].set_title('Smoothed Image')
#axes[0].axis('off')
axes[1].imshow(edges, cmap='gray')
axes[1].set_title('Canny Edge Detection')
axes[1].axis('off')
axes[2].imshow(edges, cmap='gray')
for x, y in vertical_lines:
axes[2].axvline(x=x, color='red')
axes[2].set_xlim((0, image.shape[1]))
axes[2].set_ylim((image.shape[0], 0))
axes[2].set_title('Detected Lines')
axes[2].axis('off')
plt.tight_layout()
plt.show()
And this is the resulting output
Any ideas on how to make the Hough transform detect the other edge?
答案1
得分: 0
如@Pete建议的,"遮住管子",因为它挡住了立方体,并调整以下参数:
- Canny 参数
- 高斯滤波器 参数
- 霍夫直线 检测器参数
这样你就可以检测到另一条边。
P.S:我使用了
OpenCV
,但你也可以使用Scikit Image
重复这些结果。
#!/usr/bin/env python3
import cv2
import numpy as np
import matplotlib.pyplot as plt
im_path = "cube.png"
img = cv2.imread(im_path)
# 将图像转换为灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯滤波
k = 5
sigma = 0
gauss = cv2.GaussianBlur(gray, (k, k), sigma)
# 在图像上应用边缘检测方法
edges = cv2.Canny(gauss, 50, 150, apertureSize=3)
# 移除不需要的管子
# https://stackoverflow.com/a/64175996/8618242
sum_ = np.sum(edges, axis=1)
mean_ = np.mean(sum_)
edges[sum_ > mean_, :] = 0
# 这将返回一个r和theta值的数组
lines = cv2.HoughLines(edges, 1, np.pi/180, 150)
# 以下for循环在r和theta值在2D数组的范围内运行
for r_theta in lines:
arr = np.array(r_theta[0], dtype=np.float64)
r, theta = arr
# 在a中存储cos(theta)的值
a = np.cos(theta)
# 在b中存储sin(theta)的值
b = np.sin(theta)
# x0存储rcos(theta)的值
x0 = a*r
# y0存储rsin(theta)的值
y0 = b*r
# x1存储(rcos(theta)-1000sin(theta))的四舍五入值
x1 = int(x0 + 1000*(-b))
# y1存储(rsin(theta)+1000cos(theta))的四舍五入值
y1 = int(y0 + 1000*(a))
# x2存储(rcos(theta)+1000sin(theta))的四舍五入值
x2 = int(x0 - 1000*(-b))
# y2存储(rsin(theta)-1000cos(theta))的四舍五入值
y2 = int(y0 - 1000*(a))
# cv2.line在图像中从点(x1, y1)到(x2, y2)绘制一条线。
# (0,0,255)表示要绘制的线的颜色。在这种情况下,是红色。
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.namedWindow("output", cv2.WINDOW_NORMAL)
cv2.imshow("output", img)
cv2.waitKey(0)
英文:
As suggested by @Pete "Mask out the tube" as it is occluding the cube, and adjust the parameters:
- Canny parameters
- Gaussian Filter parameters
- Hough Line detector parameters
so you can detect the other edge.
> P.S: I used OpenCV
, but you might repeat the results using Scikit Image
#!/usr/bin/env python3
import cv2
import numpy as np
import matplotlib.pyplot as plt
im_path = "cube.png"
img = cv2.imread(im_path)
# Convert the img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Gaussian Filter
k = 5
sigma = 0
gauss = cv2.GaussianBlur(gray,(k,k),sigma)
# Apply edge detection method on the image
edges = cv2.Canny(gauss, 50, 150, apertureSize=3)
# Remove unwanted tube
# https://stackoverflow.com/a/64175996/8618242
sum_ = np.sum(edges, axis=1)
mean_ = np.mean(sum_)
edges[sum_> mean_, :] = 0
# This returns an array of r and theta values
lines = cv2.HoughLines(edges, 1, np.pi/180, 150)
# The below for loop runs till r and theta values
# are in the range of the 2d array
for r_theta in lines:
arr = np.array(r_theta[0], dtype=np.float64)
r, theta = arr
# Stores the value of cos(theta) in a
a = np.cos(theta)
# Stores the value of sin(theta) in b
b = np.sin(theta)
# x0 stores the value rcos(theta)
x0 = a*r
# y0 stores the value rsin(theta)
y0 = b*r
# x1 stores the rounded off value of (rcos(theta)-1000sin(theta))
x1 = int(x0 + 1000*(-b))
# y1 stores the rounded off value of (rsin(theta)+1000cos(theta))
y1 = int(y0 + 1000*(a))
# x2 stores the rounded off value of (rcos(theta)+1000sin(theta))
x2 = int(x0 - 1000*(-b))
# y2 stores the rounded off value of (rsin(theta)-1000cos(theta))
y2 = int(y0 - 1000*(a))
# cv2.line draws a line in img from the point(x1,y1) to (x2,y2).
# (0,0,255) denotes the colour of the line to be
# drawn. In this case, it is red.
cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.namedWindow("output", cv2.WINDOW_NORMAL)
cv2.imshow("output", img)
cv2.waitKey(0)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论