构建简单的OTB代码

好了,就是这样,你刚刚下载并安装了OTB,受到了你将能够用它做任何事情的承诺的诱惑。这是真的,你将能够做任何事情,但是-总是有一个 but -需要做出一些努力。

OTB使用非常强大的泛型编程系统,许多类已经可用,定义了一些强大的工具来帮助您处理重复的任务,但这并不是一个容易进入的世界。

这些教程旨在帮助您进入这个世界并掌握OTB背后的逻辑。这些教程中的每一个都不应该超过10分钟(包括打字),并且每个教程都旨在突出一个特定的要点。您可能不关心最新的教程,但强烈建议您阅读前几篇教程,它们涵盖了您几乎在任何地方都会用到的基本知识。

你好,世界

让我们从典型的开始 Hello world 程序。我们将编译此链接到您的新OTB的C++程序。

首先,创建一个新文件夹,将您的新程序(本教程中的所有示例)放入其中,然后进入该文件夹。

由于所有使用OTB的程序都是使用CMake系统处理的,因此我们需要创建一个 CMakeLists.txt 它将被CMake用来编译我们的程序。此文件的示例可在 OTB/Examples/Tutorials 目录。这个 CMakeLists.txt 在你们的项目之间会非常相似。

打开 CMakeLists.txt 文件,并在下面几行中写下:

project(Tutorials)

cmake_minimum_required(VERSION 3.1.0)

find_package(OTB)
if(OTB_FOUND)
  include(${OTB_USE_FILE})
else(OTB_FOUND)
  message(FATAL_ERROR "Cannot build OTB project without OTB.  Please set OTB_DIR.")
endif(OTB_FOUND)

add_executable(HelloWorldOTB HelloWorldOTB.cxx )
target_link_libraries(HelloWorldOTB ${OTB_LIBRARIES})

第一行定义项目在Visual Studio中显示的名称(它在Unix或Linux下不起作用)。第二行加载带有用于查找OTB的预定义策略的CMake文件。如果查找OTB的策略失败,CMake将提示您输入系统中安装OTB的目录。在这种情况下,您需要将此信息写入 OTB_DIR 变量。这条线 include(${USE_OTB_FILE}) 加载 UseOTB.cmake 文件以设置OTB中的所有配置信息。

这条线 add_executable 将作为此项目的结果生成的可执行文件的名称定义为其第一个参数。的剩余论据 add_executable 是要编译和链接的源文件的名称。最后, target_link_libraries Line指定将针对此项目链接哪些OTB库。

HelloWorldOTB.cxx

写入文件后,运行 ccmake 在当前目录(即 ccmake ./ 在Linux/Unix下)。如果OTB在一个非标准的地方,你必须告诉CMake它在哪里。一旦你完成了CMake(你不应该再做了),运行 make

你终于有了你的程序。当您运行它时,您将拥有 OTB Hello World ! 打印出来的。

好的,干得好!您刚刚编译并执行了您的第一个OTB程序。事实上,使用OTB并不是很有用,我们怀疑您下载OTB只是为了做到这一点。是时候更上一层楼了。

管道基础知识:读写

OTB设计用于读取图像、处理图像并将其写入磁盘或查看结果。在本教程中,我们将了解如何读写图像以及管道系统的基础知识。

首先,让我们将以下行添加到 CMakeLists.txt 文件:

add_executable(Pipeline Pipeline.cxx )
target_link_libraries(Pipeline ${OTB_LIBRARIES})

现在,创建一个 Pipeline.cxx 文件: Pipeline.cxx

一旦这个文件被写入,你只需要运行 make 。这个 ccmake 不再需要呼叫。

获取一张来自 OTB-Data/Examples OTB数据存储库中的目录。您可以通过克隆OTB数据存储库来获取它 (git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git ),但这可能会很长,因为这也会获得运行测试的数据。或者,您也可以从http://www.orfeo-toolbox.org/packages/OTB-Data-Examples.tgz.获得它以GET为例 QB_Suburb.png

现在,以下列身份运行您的新程序 Pipeline QB_Suburb.png output.png 。您将获得该文件 output.png 它的图像与 QB_Suburb.png 。当您触发 Update() 方法时,OTB打开原始图像,然后用另一个名称将其写回。

Well…这很好,但对于一个复制程序来说有点复杂!

等一下!我们在任何地方都没有指定文件格式!我们试试看 Pipeline QB_Suburb.png output.jpg 。瞧啊!输出的图像是一个jpeg文件。

这开始变得更有趣了:这不仅仅是一个复制图像文件的程序,还可以在图像格式之间进行转换。

您刚刚体验了仅在需要时才执行滤镜的流水线结构和自动图像格式检测。

现在是时候在两者之间进行一些处理了。

过滤管道

我们现在将插入一个简单的过滤器来在读取器和写入器之间进行一些处理。

让我们首先将以下两行添加到 CMakeLists.txt 文件:

add_executable(FilteringPipeline FilteringPipeline.cxx )
target_link_libraries(FilteringPipeline ${OTB_LIBRARIES})

请参见示例 FilteringPipeline.cxx

用来编译 make 并执行为 FilteringPipeline QB_Suburb.png output.png

您的图像的过滤版本位于 output.png 文件。

现在,您可以练习一下,并尝试用150多个筛选器中的一个替换该筛选器,这些筛选器继承自 itk::ImageToImageFilter 班级。你一定会在这里找到一些有用的过滤器!

处理类型:缩放输出

如果您尝试了上一个示例中的其他筛选器,您可能已经注意到,在某些情况下,将输出直接保存为整数没有意义。如果您尝试使用 itk::CannyEdgeDetectionImageFilter 。如果您尝试在前面的示例中直接使用它,您将会收到一些关于从Double转换为无符号字符的警告。

Canny边缘检测的输出是一个浮点数。一个简单的解决方案是将其用作像素类型。遗憾的是,大多数图像格式都使用整数类型,如果您仍然希望使用常用的查看器将图像可视化,则应将结果转换为整数图像(我们将在后面的教程中了解如何使用内置查看器来避免这种情况)。

为了实现此转换,我们将使用 itk::RescaleIntensityImageFilter

将这两行添加到 CMakeLists.txt 文件:

add_executable(ScalingPipeline ScalingPipeline.cxx )
target_link_libraries(ScalingPipeline ${OTB_LIBRARIES})

请参见示例 ScalingPipeline.cxx

因为您现在应该已经习惯了,所以用以下命令编译 make 并执行为 ScalingPipeline QB_Suburb.png output.png

您的图像的过滤版本位于 output.png 文件。

处理多光谱或彩色图像

到目前为止,正如你可能已经注意到的,我们一直在处理灰度图像,即只有一个光谱波段。如果您尝试使用前面的一些示例来处理彩色图像,您可能会得到一个具有欺骗性的灰色结果。

通常,卫星图像结合几个光谱波段来帮助识别物质:这被称为多光谱图像。在本教程中,我们将探索OTB用来处理多光谱图像的一些机制。

将以下行添加到 CMakeLists.txt 文件:

add_executable(Multispectral Multispectral.cxx )
target_link_libraries(Multispectral ${OTB_LIBRARIES})

请参见示例 Multispectral.cxx

用来编译 make 并执行为 ./Multispectral qb_RoadExtract.tif qb_blue.tif qb_shiftscale.tif

从原始的卫星图像到有用的产品

通常,当你购买卫星图像时,你最终会得到几张图像。在光学卫星的情况下,你经常有一个空间分辨率最高的全色光谱波段和一个分辨率较低的相同区域的多光谱乘积。分辨率可能在4左右。

为了充分利用图像处理算法,您需要将这些数据组合在一起,以生成具有最高空间分辨率和多个光谱波段的新图像。此步骤称为融合,有关此步骤的更多详细信息,请参阅 [sec:Fusion] 。然而,融合假设您的两个图像表示完全相同的区域。有不同的解决方案可以处理您的数据来达到这种情况。在这里,我们将使用图像可用的元数据来生成正射校正,如中所述 [sec:Ortho] 。

首先,您需要在 CMakeLists.txt 文件:

add_executable(OrthoFusion  OrthoFusion.cxx)
target_link_libraries(OrthoFusion ${OTB_LIBRARIES})

请参见示例 OrthoFusion.cxx