Justheartyoung 发表于 2023-8-4 16:21:44

请大佬帮弟弟看看,问题出在哪里 怎么修改 谢谢

代码想实现对影像中沙丘脊线的提取,但是最终绘制的沙脊线感觉不对,有大佬知道问题出在哪里吗?可否给出改正代码!谢谢
from tifffile import imread
from skimage import filters, feature, img_as_ubyte, color
import matplotlib.pyplot as plt
import numpy as np
from skimage.transform import hough_line, hough_line_peaks

# 使用tifffile库读取TIFF格式的RGB影像
image = imread('F:\\duneline\\dune\\dune.tif')

# 将影像转换为灰度图像
gray_image = color.rgb2gray(image)

# 将灰度图像转换为8位无符号整数格式,因为后续的图像处理函数需要这种格式
edges = filters.sobel(img_as_ubyte(gray_image))

# 使用Hough变换找出可能的直线
tested_angles = np.linspace(-np.pi / 2, np.pi / 2, 360)
h, theta, d = hough_line(edges, theta=tested_angles)

# 在原图上画出沙丘脊线
fig, ax = plt.subplots()
ax.imshow(image, cmap=plt.cm.gray)

for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
    y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
    y1 = (dist - image.shape * np.cos(angle)) / np.sin(angle)
    ax.plot((0, image.shape), (y0, y1), '-r')

plt.show()

tyh小号 发表于 2023-8-4 16:22:03

根据您提供的代码,我看到您的问题可能出在将灰度图像转换为8位无符号整数格式时的处理上。

在使用 img_as_ubyte() 将灰度图像转换为8位无符号整数格式之前,您应该先对图像进行归一化操作,将像素值范围从0-1缩放到0-255。这样可以确保图像的像素值在正确的范围内,以便后续的图像处理函数能够正确处理。

下面是修改后的代码示例:

from tifffile import imread
from skimage import filters, feature, img_as_ubyte, color
import matplotlib.pyplot as plt
import numpy as np
from skimage.transform import hough_line, hough_line_peaks

# 使用tifffile库读取TIFF格式的RGB影像
image = imread('F:\\duneline\\dune\\dune.tif')
# 将影像转换为灰度图像
gray_image = color.rgb2gray(image)

# 将灰度图像归一化并转换为8位无符号整数格式
normalized_image = gray_image * 255
image_ubyte = normalized_image.astype(np.uint8)

# 使用Sobel边缘检测
edges = filters.sobel(image_ubyte)
# 使用Hough变换找出可能的直线
tested_angles = np.linspace(-np.pi / 2, np.pi / 2, 360)
h, theta, d = hough_line(edges, theta=tested_angles)

# 在原图上画出沙丘脊线
fig, ax = plt.subplots()
ax.imshow(image, cmap=plt.cm.gray)
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
    y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
    y1 = (dist - image.shape * np.cos(angle)) / np.sin(angle)
    ax.plot((0, image.shape), (y0, y1), '-r')

plt.show()


通过对灰度图像进行归一化,然后将像素值范围缩放到0-255,可以确保图像的像素值符合8位无符号整数的取值范围。这样修改后的代码应该能够正确地绘制沙丘脊线。希望对您有所帮助!如有其他问题,请随时提问。
如果问题已经解决,请设置最佳答案

学习编程中的Ben 发表于 2023-8-4 16:22:13

本帖最后由 学习编程中的Ben 于 2023-8-4 16:29 编辑

根据您提供的代码,有几个问题可能导致最终绘制的沙脊线不正确:

1. 彩色图像转换为灰度图像时,使用了color.rgb2gray()函数,但是在导入语句中没有引入color模块。请将导入语句修改为from skimage import filters, img_as_ubyte, color。

2. 在边缘检测时,使用了filters.sobel()函数对灰度图像进行处理。这一步骤应该是正确的。

3. 在Hough变换的相关函数调用中,使用了zip(*hough_line_peaks(h, theta, d))。请将这部分修改为zip(h, theta, d)。

4. 在绘制沙脊线时,计算直线的起点和终点坐标的公式可能存在问题。您可以尝试使用以下公式计算:

y0 = (dist - 0 * np.cos(theta)) / np.sin(theta)
y1 = (dist - gray_image.shape * np.cos(theta)) / np.sin(theta)

请注意,我对代码进行了上述修改。以下是修改后的代码:

from tifffile import imread
from skimage import filters, img_as_ubyte, color
import matplotlib.pyplot as plt
import numpy as np
from skimage.transform import hough_line, hough_line_peaks

# 使用tifffile库读取TIFF格式的RGB影像
image = imread('F:\\duneline\\dune\\dune.tif')

# 将影像转换为灰度图像
gray_image = color.rgb2gray(image)

# 将灰度图像转换为8位无符号整数格式,因为后续的图像处理函数需要这种格式
edges = filters.sobel(img_as_ubyte(gray_image))

# 使用Hough变换找出可能的直线
tested_angles = np.linspace(-np.pi / 2, np.pi / 2, 360)
h, theta, d = hough_line(edges, theta=tested_angles)

# 在原图上画出沙丘脊线
fig, ax = plt.subplots()
ax.imshow(image, cmap=plt.cm.gray)

for _, angle, dist in zip(h, theta, d):
    y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
    y1 = (dist - gray_image.shape * np.cos(angle)) / np.sin(angle)
    ax.plot((0, gray_image.shape), (y0, y1), '-r')

plt.show()

希望以上修改能够解决您的问题!如果您有任何其他疑问,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!{:10_254:}{:10_254:}{:10_254:}

isdkz 发表于 2023-8-4 16:22:15

问题可能出在绘制沙丘脊线的部分。根据代码,绘制沙丘脊线的逻辑是使用Hough变换找出可能的直线,然后根据直线的角度和距离在原图上绘制直线。

在绘制直线的代码中,使用了 zip(*hough_line_peaks(h, theta, d)) 来遍历直线的角度和距离。然后根据直线的角度和距离计算直线上的两个点 (0, y0) 和 (image.shape, y1) ,并使用 ax.plot 函数绘制直线。

可能的问题在于直线上的两个点的计算方式不正确。根据代码,计算 y0 和 y1 的公式为:

y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
y1 = (dist - image.shape * np.cos(angle)) / np.sin(angle)


这里使用了 dist 、 angle 和 image.shape 来计算直线上的点的纵坐标。其中 dist 是直线的距离, angle 是直线的角度, image.shape 是图像的宽度。

根据代码逻辑, dist 表示直线与原点的距离, angle 表示直线的角度, image.shape 表示图像的宽度。而直线上的点的纵坐标应该是根据直线方程计算得出的。

修正代码如下:

for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
    cos_angle = np.cos(angle)
    sin_angle = np.sin(angle)
    x0 = 0
    x1 = image.shape
    y0 = (dist - x0 * cos_angle) / sin_angle
    y1 = (dist - x1 * cos_angle) / sin_angle
    ax.plot((x0, x1), (y0, y1), '-r')


修正后的代码中,首先计算了 cos_angle 和 sin_angle ,然后根据直线方程 y = (dist - x * cos_angle) / sin_angle 计算直线上的点的纵坐标 y0 和 y1 ,其中 x0 为0, x1 为图像的宽度。最后使用 ax.plot 函数绘制直线。

请尝试使用修正后的代码,看看是否能够正确绘制沙丘脊线。

Justheartyoung 发表于 2023-8-4 16:28:42

学习编程中的Ben 发表于 2023-8-4 16:22
根据您提供的代码,有几个问题可能导致最终绘制的沙脊线不正确:

1. 彩色图像转换为灰度图像时,使用了col ...

还是不行

Justheartyoung 发表于 2023-8-4 16:30:32

tyh小号 发表于 2023-8-4 16:22
根据您提供的代码,我看到您的问题可能出在将灰度图像转换为8位无符号整数格式时的处理上。

在使用 img_ ...

运行结果和我原来还是一样,没有解决

学习编程中的Ben 发表于 2023-8-4 16:31:10

Justheartyoung 发表于 2023-8-4 16:28
还是不行

如果您仍然遇到问题,可能是由于沙丘脊线提取的算法不适用于您的图像,或者图像中的沙丘脊线不够清晰。在这种情况下,您可以尝试以下方法来改进您的沙丘脊线提取结果:

调整边缘检测算法:尝试使用其他边缘检测算法,例如Canny边缘检测,看是否能够更好地检测到沙丘脊线。

参数调整:根据图像的特点和需要,尝试调整Hough变换的参数,包括角度的步长、距离的步长等,以及设置适当的阈值。

图像预处理:在进行边缘检测之前,可以尝试对图像进行预处理,例如去噪或平滑操作,以提高边缘检测的效果。可以使用滤波器如高斯滤波器或中值滤波器进行图像平滑处理。

其他算法:除了Hough变换,还有其他算法可用于提取直线特征,如RANSAC算法等。您可以尝试使用其他算法来提取沙丘脊线。

请注意,每个图像都有其独特的特点和挑战,因此并不存在一种通用的解决方案。根据您的具体情况,可能需要进行多次尝试和调整,以获得最佳的沙丘脊线提取结果。

如果您能提供更多关于图像特点和预期结果的信息,我可能能够为您提供更具体的建议。

Justheartyoung 发表于 2023-8-4 16:31:21

Mike_python小 发表于 2023-8-4 16:22
根据您提供的代码,有几个问题可能导致绘制的沙脊线不正确:

1. 影像加载:首先,请确保实际路径'F:\\dune ...

运行了您的代码,和我结果一样,还是没解决

Justheartyoung 发表于 2023-8-4 16:33:11

isdkz 发表于 2023-8-4 16:22
问题可能出在绘制沙丘脊线的部分。根据代码,绘制沙丘脊线的逻辑是使用Hough变换找出可能的直线,然后根据 ...

没有解决,还是那样

学习编程中的Ben 发表于 2023-8-4 16:36:03

如果您仍然遇到问题,可能是由于沙丘脊线提取的算法不适用于您的图像,或者图像中的沙丘脊线不够清晰。在这种情况下,您可以尝试以下方法来改进您的沙丘脊线提取结果:

调整边缘检测算法:尝试使用其他边缘检测算法,例如Canny边缘检测,看是否能够更好地检测到沙丘脊线。

参数调整:根据图像的特点和需要,尝试调整Hough变换的参数,包括角度的步长、距离的步长等,以及设置适当的阈值。

图像预处理:在进行边缘检测之前,可以尝试对图像进行预处理,例如去噪或平滑操作,以提高边缘检测的效果。可以使用滤波器如高斯滤波器或中值滤波器进行图像平滑处理。

其他算法:除了Hough变换,还有其他算法可用于提取直线特征,如RANSAC算法等。您可以尝试使用其他算法来提取沙丘脊线。

请注意,每个图像都有其独特的特点和挑战,因此并不存在一种通用的解决方案。根据您的具体情况,可能需要进行多次尝试和调整,以获得最佳的沙丘脊线提取结果。

如果您能提供更多关于图像特点和预期结果的信息,我可能能够为您提供更具体的建议。


给个最佳答案呗!求你了!!!{:10_254:}

学习编程中的Ben 发表于 2023-8-4 17:00:33

请问还有哪里有问题QAQ

Mike_python小 发表于 2023-8-4 17:21:18

Justheartyoung 发表于 2023-8-4 13:31
运行了您的代码,和我结果一样,还是没解决

from tifffile import imread
from skimage import filters, feature, img_as_ubyte, color
import matplotlib.pyplot as plt
import numpy as np
from skimage.transform import hough_line, hough_line_peaks

# 使用tifffile库读取TIFF格式的RGB影像
image = imread('F:\\duneline\\dune\\dune.tif')

# 将影像转换为灰度图像
gray_image = color.rgb2gray(image)

# 将灰度图像转换为8位无符号整数格式,因为后续的图像处理函数需要这种格式
edges = filters.sobel(img_as_ubyte(gray_image))

# 使用Hough变换找出可能的直线
tested_angles = np.linspace(-np.pi / 2, np.pi / 2, 360)
h, theta, d = hough_line(edges, theta=tested_angles)

# 设置阈值来选取直线
angle_threshold = 30# 沙脊线的倾斜角度范围
dist_threshold = 50# 直线到原点的距离阈值

# 在原图上画出沙脊线
fig, ax = plt.subplots()
ax.imshow(image, cmap=plt.cm.gray)

for _, angle, dist in zip(*hough_line_peaks(h, theta, d, threshold=0, min_distance=5)):
    if np.abs(angle) < angle_threshold and np.abs(dist) > dist_threshold:
      y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
      y1 = (dist - image.shape * np.cos(angle)) / np.sin(angle)
      ax.plot((0, image.shape), (y0, y1), '-r')

plt.show()


这个代码试试?
页: [1]
查看完整版本: 请大佬帮弟弟看看,问题出在哪里 怎么修改 谢谢