鱼C论坛

 找回密码
 立即注册
查看: 783|回复: 7

[已解决]求各位大佬帮弟弟改进并实现代码 谢谢 (不吝啬最优答案)

[复制链接]
发表于 2023-8-4 17:07:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我想实现对沙丘脊线的提取,但是在对RGB TIFF格式的影像二值化方法以及沙脊线提取涉及的阈值问题 特别影响我最终提取结果的好坏。原来代码提取结果很差,因此我想请大佬们帮我改进代码以实现:
1.基于局部阈值法来对影像进行灰度处理
2.在提取沙脊线的时候,能否基于局部阈值方法来提取。
原来的代码:
from tifffile import imread, imwrite
from skimage import filters, feature, color
import matplotlib.pyplot as plt
import numpy as np

# 读取TIFF格式无人机影像数据
image = imread('F:\\duneline\\dune\\dune.tif')
# 转换为灰度图像
gray_image = color.rgb2gray(image)
# 边缘检测,提取沙丘脊线
edges = filters.sobel(gray_image)

# 使用自适应阈值法确定沙脊线的二值化图像
adaptive_threshold = filters.threshold_multiotsu(edges, classes=2)
binary = edges > adaptive_threshold[0]  # 使用较低的阈值

# 叠加沙脊线在原始影像上
overlay = np.copy(image)
overlay[binary] = [255, 0, 0]  # 将沙脊线部分标记为红色

# 显示原始影像和叠加效果
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].imshow(image)
ax[0].set_title('Original Image')
ax[0].axis('off')
ax[1].imshow(overlay)
ax[1].set_title('Overlay')
ax[1].axis('off')
plt.show()

# 导出结果
imwrite('overlay_image.tif', overlay)
最佳答案
2023-8-4 17:08:22
为了实现基于局部阈值法对影像进行灰度处理,并使用局部阈值法提取沙脊线,您可以尝试以下改进:
  1. from tifffile import imread, imwrite
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. # 读取TIFF格式无人机影像数据
  5. image = imread('F:\\duneline\\dune\\dune.tif')
  6. # 灰度化处理
  7. gray_image = np.mean(image, axis=2)
  8. # 自适应阈值二值化
  9. binary = np.zeros_like(gray_image, dtype=np.uint8)
  10. window_size = 51  # 窗口大小
  11. k = 0.2  # 控制阈值的参数
  12. for i in range(window_size//2, gray_image.shape[0]-window_size//2):
  13.     for j in range(window_size//2, gray_image.shape[1]-window_size//2):
  14.         window = gray_image[i-window_size//2:i+window_size//2+1, j-window_size//2:j+window_size//2+1]
  15.         threshold = np.mean(window) - k * np.std(window)
  16.         if gray_image[i, j] > threshold:
  17.             binary[i, j] = 255
  18. # 叠加沙脊线在原始影像上
  19. overlay = np.copy(image)
  20. overlay[binary != 0] = [255, 0, 0]  # 将沙脊线部分标记为红色
  21. # 显示原始影像和叠加效果
  22. fig, ax = plt.subplots(1, 2, figsize=(10, 5))
  23. ax[0].imshow(image)
  24. ax[0].set_title('Original Image')
  25. ax[0].axis('off')
  26. ax[1].imshow(overlay)
  27. ax[1].set_title('Overlay')
  28. ax[1].axis('off')
  29. plt.show()
  30. # 导出结果
  31. imwrite('overlay_image.tif', overlay)
复制代码

在上述代码中,我首先将彩色图像转换为灰度图像,然后使用自适应阈值法对灰度图像进行二值化处理。窗口大小和阈值调整参数可以根据实际情况进行调整。最后,将沙脊线部分叠加在原始影像上并进行显示和保存。

请注意,由于我无法运行您的特定图像数据,因此无法验证代码的准确性。您可以尝试使用这个改进后的代码并根据您的实际情况进行调整。如果您遇到任何问题,请提供错误信息或具体描述,以便我能够帮助您进一步解决问题。

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-4 17:08:14 | 显示全部楼层
首先,根据您的要求,我们需要使用局部阈值法对影像进行灰度处理。可以使用skimage库中的 filters.threshold_local 函数来实现。

  1. from skimage import filters

  2. # 使用局部阈值法对影像进行灰度处理
  3. local_threshold = filters.threshold_local(gray_image, block_size=51, offset=10)
  4. binary_image = gray_image > local_threshold

复制代码

在上述代码中, block_size 参数表示局部阈值计算的窗口大小, offset 参数用于调整阈值。您可以根据具体情况调整这两个参数的值。

接下来,我们需要使用局部阈值法来提取沙脊线。可以使用 filters.threshold_local 函数来计算局部阈值,然后将其应用于边缘图像。

  1. # 使用局部阈值法来提取沙脊线
  2. local_threshold = filters.threshold_local(edges, block_size=51, offset=10)
  3. binary = edges > local_threshold

复制代码

同样地,您可以根据实际情况调整 block_size 和 offset 参数的值。

最后,您可以按照原来的代码将沙脊线叠加在原始影像上,并导出结果。

  1. # 叠加沙脊线在原始影像上
  2. overlay = np.copy(image)
  3. overlay[binary] = [255, 0, 0]  # 将沙脊线部分标记为红色

  4. # 显示原始影像和叠加效果
  5. fig, ax = plt.subplots(1, 2, figsize=(10, 5))
  6. ax[0].imshow(image)
  7. ax[0].set_title('Original Image')
  8. ax[0].axis('off')
  9. ax[1].imshow(overlay)
  10. ax[1].set_title('Overlay')
  11. ax[1].axis('off')
  12. plt.show()

  13. # 导出结果
  14. imwrite('overlay_image.tif', overlay)
复制代码


希望以上代码对您有所帮助!如果您有任何疑问,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-4 17:08:15 | 显示全部楼层
根据您提供的代码,我进行了一些改进和优化。主要包括:

1. 使用局部阈值法进行灰度处理。
2. 使用局部阈值法提取沙丘脊线。

以下是改进的代码:

  1. from tifffile import imread, imwrite
  2. from skimage.filters import threshold_local, threshold_multiotsu
  3. from skimage.feature import canny
  4. from skimage.color import rgb2gray, gray2rgb
  5. import matplotlib.pyplot as plt

  6. # 读取TIFF格式无人机影像数据
  7. image = imread('F:\\duneline\\dune\\dune.tif')

  8. # 转换为灰度图像
  9. gray_image = rgb2gray(image)

  10. # 使用局部阈值法确定沙脊线的二值化图像
  11. block_size = 31  # 局部阈值法的块大小
  12. adaptive_threshold = threshold_local(gray_image, block_size)
  13. binary = gray_image > adaptive_threshold

  14. # 边缘检测,提取沙丘脊线
  15. edges = canny(gray_image)

  16. # 叠加沙脊线在原始影像上
  17. overlay = gray2rgb(image)
  18. overlay[edges] = [255, 0, 0]  # 将边缘部分标记为红色

  19. # 显示原始影像和叠加效果
  20. fig, ax = plt.subplots(1, 2, figsize=(10, 5))
  21. ax[0].imshow(image)
  22. ax[0].set_title('Original Image')
  23. ax[0].axis('off')
  24. ax[1].imshow(overlay)
  25. ax[1].set_title('Overlay')
  26. ax[1].axis('off')
  27. plt.show()

  28. # 导出结果
  29. imwrite('overlay_image.tif', overlay)
复制代码


在改进的代码中,使用了 threshold_local() 函数来进行局部阈值法处理,并将块大小设置为 block_size。此外,使用 canny() 函数进行边缘检测,提取沙丘脊线。

希望这个改进的代码可以满足您的需求。如果您有任何其他问题,请随时提问。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-4 17:08:22 | 显示全部楼层    本楼为最佳答案   
为了实现基于局部阈值法对影像进行灰度处理,并使用局部阈值法提取沙脊线,您可以尝试以下改进:
  1. from tifffile import imread, imwrite
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. # 读取TIFF格式无人机影像数据
  5. image = imread('F:\\duneline\\dune\\dune.tif')
  6. # 灰度化处理
  7. gray_image = np.mean(image, axis=2)
  8. # 自适应阈值二值化
  9. binary = np.zeros_like(gray_image, dtype=np.uint8)
  10. window_size = 51  # 窗口大小
  11. k = 0.2  # 控制阈值的参数
  12. for i in range(window_size//2, gray_image.shape[0]-window_size//2):
  13.     for j in range(window_size//2, gray_image.shape[1]-window_size//2):
  14.         window = gray_image[i-window_size//2:i+window_size//2+1, j-window_size//2:j+window_size//2+1]
  15.         threshold = np.mean(window) - k * np.std(window)
  16.         if gray_image[i, j] > threshold:
  17.             binary[i, j] = 255
  18. # 叠加沙脊线在原始影像上
  19. overlay = np.copy(image)
  20. overlay[binary != 0] = [255, 0, 0]  # 将沙脊线部分标记为红色
  21. # 显示原始影像和叠加效果
  22. fig, ax = plt.subplots(1, 2, figsize=(10, 5))
  23. ax[0].imshow(image)
  24. ax[0].set_title('Original Image')
  25. ax[0].axis('off')
  26. ax[1].imshow(overlay)
  27. ax[1].set_title('Overlay')
  28. ax[1].axis('off')
  29. plt.show()
  30. # 导出结果
  31. imwrite('overlay_image.tif', overlay)
复制代码

在上述代码中,我首先将彩色图像转换为灰度图像,然后使用自适应阈值法对灰度图像进行二值化处理。窗口大小和阈值调整参数可以根据实际情况进行调整。最后,将沙脊线部分叠加在原始影像上并进行显示和保存。

请注意,由于我无法运行您的特定图像数据,因此无法验证代码的准确性。您可以尝试使用这个改进后的代码并根据您的实际情况进行调整。如果您遇到任何问题,请提供错误信息或具体描述,以便我能够帮助您进一步解决问题。

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-4 17:10:36 | 显示全部楼层
给个最佳答案呗!求你了!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-4 17:19:48 | 显示全部楼层
tyh小号 发表于 2023-8-4 17:08
根据您提供的代码,我进行了一些改进和优化。主要包括:

1. 使用局部阈值法进行灰度处理。

为什么报错了,大佬。可以帮忙看下嘛
  File "C:\安装软件\Python\lib\site-packages\matplotlib\image.py", line 699, in set_data
    .format(self._A.shape))
TypeError: Invalid shape (3217, 2532, 3, 3) for image data
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-4 17:20:01 | 显示全部楼层
要改进代码以实现基于局部阈值法对影像进行灰度处理和沙脊线的提取,可以使用适应性阈值方法(如局部自适应阈值法)来替代原始代码中的全局阈值法。以下是改进后的代码示例:


  1. from tifffile import imread, imwrite
  2. from skimage import filters, feature, color
  3. import matplotlib.pyplot as plt
  4. import numpy as np

  5. # 读取TIFF格式无人机影像数据
  6. image = imread('F:\duneline\dune\dune.tif')

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

  9. # 使用局部自适应阈值法对图像进行二值化处理
  10. binary = filters.threshold_local(gray_image, block_size=51, method='gaussian', offset=0.05)

  11. # 叠加沙脊线在原始影像上
  12. overlay = np.copy(image)
  13. overlay[binary] = [255, 0, 0]  # 将沙脊线部分标记为红色

  14. # 显示原始影像和叠加效果
  15. fig, ax = plt.subplots(1, 2, figsize=(10, 5))
  16. ax[0].imshow(image)
  17. ax[0].set_title('Original Image')
  18. ax[0].axis('off')
  19. ax[1].imshow(overlay)
  20. ax[1].set_title('Overlay')
  21. ax[1].axis('off')
  22. plt.show()

  23. # 导出结果
  24. imwrite('overlay_image.tif', overlay)
复制代码


改进后的代码使用 threshold_local 函数来实现局部自适应阈值法。其中,block_size 参数指定了每个像素点周围的邻域大小,可以根据您的需求进行调整。method 参数指定了阈值计算方法,这里选择了高斯加权平均(Gaussian-weighted average)方法。offset 参数用于微调阈值,可以根 据具体情况进行调整。

请尝试使用改进后的代码,并根据实际需求调整参数,以获得更好的沙脊线提取结果。如有任何疑问,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-4 17:30:15 | 显示全部楼层
学习编程中的Ben 发表于 2023-8-4 17:10
给个最佳答案呗!求你了!!!

好的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-20 17:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表