1. 概述

本文档介绍了如何使用 Activiz.NET 5.8VTK 库实现地震数据的三维可视化。地震数据通常以 SEG-Y 格式存储,而我们将通过读取 SEG-Y 文件中的数据并将其可视化为三维网格,提供一个地震剖面的可视化效果。

2. 主要功能

  1. 设置颜色查找表:利用颜色渐变图像生成 vtkLookupTable,用于对地震数据的振幅值进行颜色映射。
  2. 创建渲染窗口:通过 vtkRenderWindowvtkRenderer 创建一个可视化的三维场景。
  3. 读取SEG-Y文件:从SEG-Y文件中读取地震数据,并提取道头和样本数据。
  4. 绘制地震剖面:将地震数据转换为 3D 网格数据,并通过 vtkActorvtkDataSetMapper 进行可视化。
  5. 添加颜色条和坐标轴:在场景中添加颜色条和坐标轴,以增强可视化效果。
  6. 设置材质属性:调整对象的光照属性,增强渲染效果

3. 环境配置

  • 开发平台:Windows
  • 开发工具:Visual Studio 2022
  • 库和版本:Activiz.NET 5.8, VTK

4. 主要代码结构

4.1 设置颜色查找表

通过读取内嵌的颜色渐变图像 ColorRamp,生成一个颜色查找表 vtkLookupTable,用于映射振幅值到颜色。

public vtkLookupTable SetupColorLookupTable()
{
    Bitmap colorRamp = Properties.Resources.ColorRamp;
    int colorRampHeight = colorRamp.Height; // 1023
    int colorRampWidth = colorRamp.Width;   // 45

    vtkLookupTable colorLut = new vtkLookupTable();
    colorLut.SetNumberOfTableValues(colorRampHeight);
    colorLut.Build();

    // 从颜色渐变位图中提取颜色
    for (int i = 0; i < colorRampHeight; i++)
    {
        Color pixelColor = colorRamp.GetPixel(colorRampWidth / 2, colorRampHeight - 1 - i);
        colorLut.SetTableValue(i,
            pixelColor.R / 255.0,
            pixelColor.G / 255.0,
            pixelColor.B / 255.0,
            1.0);
    }
    return colorLut;
}

4.2 渲染窗口初始化

创建一个 vtkRenderWindow,并将其添加到 RenderWindowControl 控件中。此窗口将用于渲染地震数据的三维可视化。

private void Form1_Load(object sender, EventArgs e)
{
    // 创建VTK渲染窗口
    renderWindowControl = new RenderWindowControl();
    renderWindowControl.Dock = DockStyle.Fill;
    this.panel_container.Controls.Add(renderWindowControl);

    vtkRenderer _renderer = vtkRenderer.New();
    _renderer.SetBackground(1.0, 1.0, 1.0); // 白色背景

    vtkRenderWindow _renderWindow = vtkRenderWindow.New();
    _renderWindow.AddRenderer(_renderer);

    vtkRenderWindowInteractor _interactor = vtkRenderWindowInteractor.New();
    _interactor.SetInteractorStyle(vtkInteractorStyleTrackballCamera.New());
    _interactor.SetRenderWindow(_renderWindow);

    // 加载并可视化地震数据
    LoadAndVisualizeSeismicData(_renderer);

    // 设置颜色条
    AddColorBar(_renderer);

    // 设置坐标轴
    AddOrientationWidget(_interactor);

    _renderer.ResetCamera();
    _renderWindow.Render();
    _interactor.Start();
}

4.3 读取SEG-Y文件

通过 ReadSegy 方法从 SEG-Y 文件中读取地震数据。每个 SEG-Y 文件中包含一个 SegyReelHeader 和多个 SegyTraceHeader,用于描述数据结构。数据以矩阵的形式存储,每个点代表振幅值。

public static float[,] ReadSegy(string segyfile, out string textHdr, out SegyReelHeader reelHdr, out SegyTraceHeader[] trcHdrs)
{
    ByteOrder byteOrder = SegyReader.GetByteOrder(segyfile);

    FileStream fs = new FileStream(segyfile, FileMode.Open, FileAccess.Read);
    BinaryReader br = new BinaryReader(fs);

    textHdr = SegyReader.ReadTextHeader(br);
    reelHdr = SegyReader.ReadReelHeader(br, byteOrder);

    var dataFormat = reelHdr.DataFormatCode;
    int smpPerTrc = reelHdr.SmpPerTrc;
    var bytesPerSmp = SegyReader.GetBytesPerSample(dataFormat);  //每样本字节数
    var bytesPerTrc = 240 + smpPerTrc * bytesPerSmp;  //每道字节数

    var trcs = (int)((br.BaseStream.Length - 3600) / bytesPerTrc);

    trcHdrs = new SegyTraceHeader[trcs];
    float[,] trcData = new float[smpPerTrc, trcs];
    for (int i = 0; i < trcs; i++)
    {
        long skip = 3600 + bytesPerTrc * i; //跳过字节
        br.BaseStream.Seek(skip, SeekOrigin.Begin);

        trcHdrs[i] = SegyReader.ReadTraceHeader(br, byteOrder);
        float[] trc = SegyReader.ReadTrcData(br, smpPerTrc, bytesPerSmp, byteOrder, dataFormat);
        for (int j = 0; j < smpPerTrc; j++)
        {
            trcData[j, i] = trc[j];
        }
    }

    br.Close();
    return trcData;
}

4.4 创建地震剖面

CreateSeismicPlane 方法通过 vtkStructuredGrid 将地震数据转换为三维网格。每个网格的点包含振幅值,用于在渲染时进行颜色映射。

private vtkActor CreateSeismicPlane(float[,] trcData, SegyTraceHeader[] segyTraceHeaders, vtkLookupTable colorLut, double scalarMin, double scalarMax)
{
    int numTraces = trcData.GetLength(1);
    int numSamples = trcData.GetLength(0);

    vtkPoints points = new vtkPoints();
    vtkStructuredGrid grid = new vtkStructuredGrid();
    grid.SetDimensions(numTraces, numSamples, 1);

    vtkFloatArray scalars = new vtkFloatArray();
    scalars.SetNumberOfComponents(1);
    scalars.SetName("Amplitude");

    var sampleInterval = segyTraceHeaders[0].SmplIntvl;
    for (int j = 0; j < numSamples; j++)
    {
        double z = j * sampleInterval;
        for (int i = 0; i < numTraces; i++)
        {
            points.InsertNextPoint(segyTraceHeaders[i].SrcY, segyTraceHeaders[i].SrcX, z);
            scalars.InsertNextValue(trcData[j, i]);
        }
    }
    grid.SetPoints(points);
    grid.GetPointData().SetScalars(scalars);

    vtkDataSetMapper mapper = new vtkDataSetMapper();
    mapper.SetInput(grid);
    mapper.SetScalarRange(scalarMin, scalarMax);
    mapper.SetLookupTable(colorLut);
    mapper.ScalarVisibilityOn();

    vtkActor actor = new vtkActor();
    actor.SetMapper(mapper);

    vtkProperty property = actor.GetProperty();
    property.SetAmbient(0.3);
    property.SetDiffuse(0.7);
    property.SetSpecular(0.2);
    property.SetSpecularPower(50.0);

    vtkTransform transform = new vtkTransform();
    transform.Scale(1, 1, 0.5);
    actor.SetUserTransform(transform);

    return actor;
}

4.5 添加颜色条和坐标轴

为了增强可视化效果,我们可以在渲染窗口中添加颜色条和坐标轴。

private static void AddColorBar(vtkRenderer _renderer, vtkLookupTable colorLut)
{
    vtkScalarBarActor scalarBar = new vtkScalarBarActor();
    scalarBar.SetLookupTable(colorLut);
    scalarBar.SetNumberOfLabels(0);
    scalarBar.SetPosition(0.9, 0.1);
    scalarBar.SetWidth(0.1);
    scalarBar.SetHeight(0.8);
    scalarBar.SetTextPositionToPrecedeScalarBar();
    _renderer.AddActor(scalarBar);
}

private static void AddOrientationWidget(vtkRenderWindowInteractor _interactor)
{
    vtkAxesActor axesActor = new vtkAxesActor();
    axesActor.SetTotalLength(1.0, 1.0, 1.0);
    vtkOrientationMarkerWidget widget = new vtkOrientationMarkerWidget();
    widget.SetOrientationMarker(axesActor);
    widget.SetInteractor(_interactor);
    widget.SetEnabled(true);
}

5. 总结

本项目结合了 Activiz.NETVTK 库,通过读取 SEG-Y 文件中的地震数据并进行三维可视化,帮助用户更直观地理解地震剖面信息。您可以根据实际需求调整渲染参数、颜色映射等,以满足特定的可视化需求。

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐