鱼C论坛

 找回密码
 立即注册
查看: 2322|回复: 6

代码实现;提取结果的左侧边界线的提取

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

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

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

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 15:21:21 | 显示全部楼层
代码实现黑色区域左侧边界线的提取

为了实现黑色区域左侧边界线的提取,我们可以使用OpenCV库的轮廓检测功能。以下是在原代码的基础上添加的代码块:
  1. # 使用Canny边缘检测
  2. edges = cv2.Canny(binary, 30, 100)
  3. # 寻找轮廓
  4. contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  5. # 寻找最左侧的轮廓点
  6. leftmost_contour = min(contours, key=lambda contour: np.min(contour[:, :, 0]))
  7. # 绘制左侧边界线
  8. boundary_image = np.zeros_like(binary, dtype=np.uint8)
  9. cv2.drawContours(boundary_image, [leftmost_contour], -1, 255, thickness=2)
  10. # 将边界线写入输出图像
  11. out_band.WriteArray(boundary_image)
复制代码

将上述代码块添加到原有代码的# 将沙脊线部分写入输出图像之前。这段代码会使用Canny边缘检测来获取二值化后图像的边缘,并通过轮廓检测找到最左侧的轮廓点,然后绘制出左侧边界线,并将其写入输出图像。

请尝试运行修改后的代码,并查看输出图像中的结果。结果图像中应该有一条红色线表示黑色区域的左侧边界线。如果需要调整该边界线的样式,例如颜色或线宽,请根据需要进行修改。

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

使用道具 举报

发表于 2023-8-6 15:21:26 | 显示全部楼层
原代码已经实现了沙丘的提取,现在需要进一步完善代码,实现结果左侧的边界线提取。以下是拟完善的代码实现:

  1. # 导入所需的库
  2. import cv2

  3. # 读取二值化后的图像
  4. binary_image = cv2.imread(output_path, cv2.IMREAD_GRAYSCALE)

  5. # 寻找轮廓
  6. contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

  7. # 创建空白图像,用于绘制边界线
  8. boundary_image = np.zeros_like(binary_image, dtype=np.uint8)

  9. # 绘制边界线
  10. for contour in contours:
  11.     for i in range(len(contour)):
  12.         if i == 0:
  13.             cv2.line(boundary_image, tuple(contour[ i][0]), tuple(contour[ i][0]), (0, 0, 255), 2)
  14.         else:
  15.             cv2.line(boundary_image, tuple(contour[i-1][0]), tuple(contour[ i][0]), (0, 0, 255), 2)

  16. # 保存结果
  17. cv2.imwrite('boundary_image.tif', boundary_image)

  18. print("边界线提取完成!")
复制代码


以上代码使用OpenCV库对二值化后的图像进行边界线的提取。首先使用 cv2.imread 函数读取二值化后的图像,然后使用 cv2.findContours 函数寻找轮廓。接着,创建一个空白图像,用于绘制边界线。通过遍历每个轮廓的点,使用 cv2.line 函数绘制边界线。最后,使用 cv2.imwrite 函数保存结果图像。完成后,输出"边界线提取完成!"。

请注意,为了运行此代码,您需要安装OpenCV库。可以使用以下命令进行安装:

  1. pip install opencv-python
复制代码


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

使用道具 举报

发表于 2023-8-6 15:21:29 | 显示全部楼层
请参考下面的代码,在原代码的基础上添加了提取左侧边界线的功能。
  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. # 提取左侧边界线
  21. boundary = np.zeros_like(binary, dtype=np.uint8)
  22. for i in range(binary.shape[0]):
  23.     for j in range(1, binary.shape[1]):
  24.         if binary[i, j-1] == 0 and binary[i, j] == 255:  # 左侧边界线
  25.             boundary[i, j] = 255
  26. # 配置输出的空间参考信息
  27. in_ds = gdal.Open(image_path)
  28. projection = in_ds.GetProjection()
  29. geotransform = in_ds.GetGeoTransform()
  30. # 创建新的输出图像
  31. driver = gdal.GetDriverByName('GTiff')
  32. out_ds = driver.Create(output_path, image.shape[1], image.shape[0], 1, gdal.GDT_Byte)
  33. # 设置输出图像的空间参考信息
  34. out_ds.SetProjection(projection)
  35. out_ds.SetGeoTransform(geotransform)
  36. # 将边界线部分写入输出图像
  37. out_band = out_ds.GetRasterBand(1)
  38. out_band.WriteArray(boundary.astype(np.uint8))
  39. # 设置颜色表
  40. color_table = gdal.ColorTable()
  41. color_table.SetColorEntry(0, (0, 0, 0, 0))  # 黑色,对应值为0
  42. color_table.SetColorEntry(255, (255, 0, 0, 255))  # 红色,对应值为255
  43. out_band.SetColorTable(color_table)
  44. # 释放资源
  45. out_band.FlushCache()
  46. out_ds = None
  47. in_ds = None
  48. print("保存成功!")
复制代码

请尝试运行修改后的代码,看是否能够成功提取结果左侧的边界线并保存图像。

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

使用道具 举报

 楼主| 发表于 2023-8-6 15:46:57 | 显示全部楼层
Mike_python小 发表于 2023-8-6 15:21
代码实现黑色区域左侧边界线的提取

为了实现黑色区域左侧边界线的提取,我们可以使用OpenCV库的轮廓检测功 ...

请在原代码基础上修改 谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-6 15:47:15 | 显示全部楼层
isdkz 发表于 2023-8-6 15:21
原代码已经实现了沙丘的提取,现在需要进一步完善代码,实现结果左侧的边界线提取。以下是拟完善的代码实现 ...

请将代码融合进原代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-6 15:47:47 | 显示全部楼层
学习编程中的Ben 发表于 2023-8-6 15:21
请参考下面的代码,在原代码的基础上添加了提取左侧边界线的功能。

结果不行,还有没有办法
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-23 03:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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