鱼C论坛

 找回密码
 立即注册
查看: 2857|回复: 3

如何提取图中黑色区域左侧的边缘线(如图)。请大佬在我代码基础上进行更改,谢谢!

[复制链接]
发表于 2023-8-6 16:58:24 | 显示全部楼层 |阅读模式

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

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

x
from tifffile import imread
import numpy as np
from osgeo import gdal, osr

# 读取TIFF格式无人机影像数据
image_path = 'F:\duneline\dune\dune.tif'
output_path = 'overlay_image.tif'

image = imread(image_path)

# 将输入图像转换为灰度图像
gray_image = np.mean(image, axis=2)

# 自适应阈值二值化
binary = np.zeros_like(gray_image, dtype=np.uint8)
window_size = 7 # 窗口大小
k = 0.1 # 控制阈值的参数
for i in range(window_size//2, gray_image.shape[0]-window_size//2):
    for j in range(window_size//2, gray_image.shape[1]-window_size//2):
        window = gray_image[i-window_size//2:i+window_size//2+1, j-window_size//2:j+window_size//2+1]
        threshold = np.mean(window) - k * np.std(window)
        if gray_image[i, j] > threshold:
            binary[i, j] = 255

# 配置输出的空间参考信息
in_ds = gdal.Open(image_path)
projection = in_ds.GetProjection()
geotransform = in_ds.GetGeoTransform()

# 创建新的输出图像
driver = gdal.GetDriverByName('GTiff')
out_ds = driver.Create(output_path, image.shape[1], image.shape[0], 1, gdal.GDT_Byte)  # 修改数据类型为gdal.GDT_Byte

# 设置输出图像的空间参考信息
out_ds.SetProjection(projection)
out_ds.SetGeoTransform(geotransform)

# 将沙脊线部分写入输出图像
out_band = out_ds.GetRasterBand(1)
out_band.WriteArray(binary.astype(np.uint8))  # 修改为正确的数据类型

# 设置颜色表
color_table = gdal.ColorTable()
color_table.SetColorEntry(0, (0, 0, 0, 0))  # 黑色,对应值为0
color_table.SetColorEntry(255, (255, 255, 255, 255))  # 白色,对应值为255
out_band.SetColorTable(color_table)

# 释放资源
out_band.FlushCache()
out_ds = None
in_ds = None

print("保存成功!")
脊线.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-8-6 16:58:50 | 显示全部楼层
提取图像黑色区域的边缘线

要提取图像中黑色区域的边缘线,您可以使用边缘检测算法,例如Canny边缘检测。以下是修改后的代码,以将Canny边缘检测应用于二值图像,并将边缘结果保存为新的图像。
  1. from tifffile import imread
  2. import numpy as np
  3. from osgeo import gdal
  4. # 读取TIFF格式无人机影像数据
  5. image_path = 'F:\duneline\dune\dune.tif'
  6. output_path = 'overlay_image.tif'
  7. image = imread(image_path)
  8. # 将输入图像转换为灰度图像
  9. gray_image = np.mean(image, axis=2)
  10. # 自适应阈值二值化
  11. binary = np.zeros_like(gray_image, dtype=np.uint8)
  12. window_size = 7
  13. k = 0.1
  14. for i in range(window_size//2, gray_image.shape[0]-window_size//2):
  15.     for j in range(window_size//2, gray_image.shape[1]-window_size//2):
  16.         window = gray_image[i-window_size//2:i+window_size//2+1, j-window_size//2:j+window_size//2+1]
  17.         threshold = np.mean(window) - k * np.std(window)
  18.         if gray_image[i, j] > threshold:
  19.             binary[i, j] = 255
  20. # 应用Canny边缘检测
  21. edges = cv2.Canny(binary, 100, 200)  # 调整阈值以获取最佳结果
  22. # 配置输出的空间参考信息
  23. in_ds = gdal.Open(image_path)
  24. projection = in_ds.GetProjection()
  25. geotransform = in_ds.GetGeoTransform()
  26. # 创建新的输出图像
  27. driver = gdal.GetDriverByName('GTiff')
  28. out_ds = driver.Create(output_path, image.shape[1], image.shape[0], 1, gdal.GDT_Byte)
  29. # 设置输出图像的空间参考信息
  30. out_ds.SetProjection(projection)
  31. out_ds.SetGeoTransform(geotransform)
  32. # 将边缘结果写入输出图像
  33. out_band = out_ds.GetRasterBand(1)
  34. out_band.WriteArray(edges)
  35. # 设置颜色表
  36. color_table = gdal.ColorTable()
  37. color_table.SetColorEntry(0, (0, 0, 0, 0))    # 黑色,对应值为0
  38. color_table.SetColorEntry(255, (255, 255, 255, 255))    # 白色,对应值为255
  39. out_band.SetColorTable(color_table)
  40. # 释放资源
  41. out_band.FlushCache()
  42. out_ds = None
  43. in_ds = None
  44. print("保存成功!")
复制代码

请确保在运行此代码之前已安装OpenCV库(pip install opencv-python)。

这段修改后的代码将应用Canny边缘检测算法来提取二值图像中的黑色区域边缘线,并将边缘结果保存为名为"overlay_image.tif"的新图像文件。您可以根据需要调整Canny边缘检测的阈值以获取最佳结果。

希望这可以帮助到您!如果您有任何其他问题,请随时问我。

如果回答对你有帮助,请给我一个最佳答案!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-6 16:58:53 | 显示全部楼层
你好!根据你的代码,你想要提取图像中黑色区域左侧的边缘线。我看到你已经进行了一些图像处理和阈值二值化的操作,但是缺少提取边缘线的步骤。下面是我对你的代码进行修改后的版本:

  1. from tifffile import imread
  2. import numpy as np
  3. from osgeo import gdal, osr
  4. from skimage import feature

  5. # 读取TIFF格式无人机影像数据
  6. image_path = 'F:\duneline\dune\dune.tif'
  7. output_path = 'overlay_image.tif'

  8. image = imread(image_path)

  9. # 将输入图像转换为灰度图像
  10. gray_image = np.mean(image, axis=2)

  11. # 自适应阈值二值化
  12. binary = np.zeros_like(gray_image, dtype=np.uint8)
  13. window_size = 7 # 窗口大小
  14. k = 0.1 # 控制阈值的参数
  15. for i in range(window_size//2, gray_image.shape[0]-window_size//2):
  16.     for j in range(window_size//2, gray_image.shape[1]-window_size//2):
  17.         window = gray_image[i-window_size//2:i+window_size//2+1, j-window_size//2:j+window_size//2+1]
  18.         threshold = np.mean(window) - k * np.std(window)
  19.         if gray_image[i, j] > threshold:
  20.             binary[i, j] = 255

  21. # 使用Canny边缘检测算法提取边缘线
  22. edges = feature.canny(binary, sigma=1)

  23. # 配置输出的空间参考信息
  24. in_ds = gdal.Open(image_path)
  25. projection = in_ds.GetProjection()
  26. geotransform = in_ds.GetGeoTransform()

  27. # 创建新的输出图像
  28. driver = gdal.GetDriverByName('GTiff')
  29. out_ds = driver.Create(output_path, image.shape[1], image.shape[0], 1, gdal.GDT_Byte)

  30. # 设置输出图像的空间参考信息
  31. out_ds.SetProjection(projection)
  32. out_ds.SetGeoTransform(geotransform)

  33. # 将边缘线部分写入输出图像
  34. out_band = out_ds.GetRasterBand(1)
  35. out_band.WriteArray(edges.astype(np.uint8))

  36. # 设置颜色表
  37. color_table = gdal.ColorTable()
  38. color_table.SetColorEntry(0, (0, 0, 0, 0))  # 黑色,对应值为0
  39. color_table.SetColorEntry(255, (255, 255, 255, 255))  # 白色,对应值为255
  40. out_band.SetColorTable(color_table)

  41. # 释放资源
  42. out_band.FlushCache()
  43. out_ds = None
  44. in_ds = None

  45. print("保存成功!")
复制代码


我添加了 from skimage import feature 导入语句,并使用 feature.canny() 函数来提取边缘线。Canny算法是一种常用的边缘检测算法,它可以帮助我们提取图像中的边缘线。

希望对你有帮助!如果你有任何问题,请随时提问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-6 16:58:55 | 显示全部楼层
提取图中黑色区域左侧的边缘线

以下是对您给出的代码进行修改和完善后的版本。我根据你的需求,在注释部分进行了相应的说明和调整。请注意按照代码中的提示进行修改。
  1. from tifffile import imread
  2. import numpy as np
  3. from osgeo import gdal, osr
  4. # 读取TIFF格式无人机影像数据
  5. image_path = 'F:\duneline\dune\dune.tif'
  6. output_path = 'overlay_image.tif'
  7. image = imread(image_path)
  8. # 将输入图像转换为灰度图像
  9. gray_image = np.mean(image, axis=2)
  10. # 自适应阈值二值化
  11. binary = np.zeros_like(gray_image, dtype=np.uint8)
  12. window_size = 7  # 窗口大小
  13. k = 0.1  # 控制阈值的参数
  14. for i in range(window_size // 2, gray_image.shape[0] - window_size // 2):
  15.     for j in range(window_size // 2, gray_image.shape[1] - window_size // 2):
  16.         window = gray_image[i - window_size // 2:i + window_size // 2 + 1, j - window_size // 2:j + window_size // 2 + 1]
  17.         threshold = np.mean(window) - k * np.std(window)
  18.         if gray_image[i, j] > threshold:
  19.             binary[i, j] = 255
  20. # 配置输出的空间参考信息
  21. in_ds = gdal.Open(image_path)
  22. projection = in_ds.GetProjection()
  23. geotransform = in_ds.GetGeoTransform()
  24. # 创建新的输出图像
  25. driver = gdal.GetDriverByName('GTiff')
  26. out_ds = driver.Create(output_path, image.shape[1], image.shape[0], 1, gdal.GDT_Byte)
  27. # 设置输出图像的空间参考信息
  28. out_ds.SetProjection(projection)
  29. out_ds.SetGeoTransform(geotransform)
  30. # 将沙脊线部分写入输出图像
  31. out_band = out_ds.GetRasterBand(1)
  32. out_band.WriteArray(binary.astype(np.uint8))
  33. # 设置颜色表
  34. color_table = gdal.ColorTable()
  35. color_table.SetColorEntry(0, (0, 0, 0, 0))  # 黑色,对应值为0
  36. color_table.SetColorEntry(255, (255, 255, 255, 255))  # 白色,对应值为255
  37. out_band.SetColorTable(color_table)
  38. # 设置输出图像的矩形范围
  39. out_ds.FlushCache()
  40. # 释放资源
  41. out_band = None
  42. out_ds = None
  43. in_ds = None
  44. print("保存成功!")
复制代码

请按照您的实际需求修改代码中的输入路径、输出路径和其他参数。这段代码将会读取一个TIFF格式的无人机影像数据,并根据阈值将灰度图像二值化。然后使用GDAL库创建一个新的输出图像,并将二值化结果写入图像中。最后,设置输出图像的颜色表和空间信息,保存成新的TIFF文件。

希望这可以帮助到您!如果还有其他问题,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-27 00:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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