Skip to content
Search

Welding:SurfaceSampleDataGenerator

lastmod 2026-04-17created 2026-04-177 edits

How to take a single line of csv data from LVS that has only the (x, z) axes, add multiple lines along the y axis, and generate it as virtual "Surface" data in ply.

Sample Data

Using Micro-Epsilon:scanCONTROL:

ScanCONTROL_preview.png

The following weld surface was scanned:

Welding_surface_sample_example.jpg

You can obtain a csv file like the following:

27.08,114.632
26.866,114.63
26.652,114.632
26.438,114.636
26.224,114.638

The full data sample is 20260415-butt_bead_profile_sample.zip.

Converting CSV data with only the X and Z axes

When you get data from a laser scanner such as LVS, you only get (x, z) coordinates. To represent this as a 3D ply, add a y axis:

import csv
import sys
import os

def convert_csv_to_ply(csv_path, ply_path):
    points = []
    with open(csv_path, 'r') as f:
        reader = csv.reader(f)
        for row in reader:
            if len(row) >= 2:
                try:
                    x = float(row[0])
                    y = 0.0  # 단일 프로파일이므로 y는 0으로 고정
                    z = float(row[1])
                    points.append((x, y, z))
                except ValueError:
                    continue

    with open(ply_path, 'w') as f:
        f.write("ply\n")
        f.write("format ascii 1.0\n")
        f.write(f"element vertex {len(points)}\n")
        f.write("property float x\n")
        f.write("property float y\n")
        f.write("property float z\n")
        f.write("end_header\n")
        for p in points:
            f.write(f"{p[0]} {p[1]} {p[2]}\n")

if __name__ == "__main__":
    files = [
        "20260415-butt_bead_profile_sample.csv",
        "20260415-fillet_bead_profile_sample.csv"
    ]

    for csv_file in files:
        if os.path.exists(csv_file):
            ply_file = csv_file.replace(".csv", ".ply")
            convert_csv_to_ply(csv_file, ply_file)
            print(f"Converted {csv_file} -> {ply_file}")

Generating multiple scan lines

I have reviewed the CSV data and images you provided. The data you currently have is cross-section (2D Profile) information of a weld bead.

To generate a Korean: 가상 데이터셋 (Synthetic Dataset) based on this that looks like a scan of the entire Surface, you need to extend the existing profile in the Y-axis direction while applying consistent variations.

Data generation strategies

Here are 3 data generation strategies that can be used for testing quality evaluation algorithms or for training.

Simple interpolation and noise addition (most realistic)

A real weld bead is not uniform like a straight line; it wavers slightly and its height varies. This method duplicates the existing single data set while giving each line a bit of randomness.

  1. Load the original CSV (X, Z).
  2. Set the Y-axis coordinates (e.g., 0.1mm spacing).
  3. For each Y coordinate, add Gaussian noise (Gaussian Noise) to the Z values.
  4. Slightly Shift the bead's center position (X axis) left and right.

Advantage: Data generation is very fast, and it can even simulate the sensor's measurement error.

Using the Morphing technique

If you have one 'normal bead' data set and one 'defective (e.g., Overlap or Underfill)' data set, you can create multiple sets by gradually transitioning between the two.

\(Znew​=(1−t)⋅Znormal​+t⋅Zdefect​\)

  • Znew​: Height data of the newly generated profile.
  • Znormal​: Height data of the reference normal bead.
  • Zdefect​: Height data of the target defective bead.
  • t: The interpolation coefficient, in the range 0≤t≤1 (t=0 is normal, t=1 is the defective state).

Advantage: You can continuously generate transitional quality states from good to defective, which helps with setting the decision Threshold.

Generating bead undulation using a Sine Wave

Real welding produces wave-shaped ripples (Ripple) along the travel direction (Y axis). This is implemented with a formula.

\(Z(x,y)=Zbase​(x)+A⋅sin(2π⋅f⋅y+ϕ)\) Z(x,y): The height value of the final generated 3D coordinate.

  • Zbase​(x): The height of the base cross-section profile taken from the original CSV.
  • A: The Amplitude of the sine wave, which determines how high or low the ripples are.
  • f: The Frequency, which determines the number of ripples generated per unit length.
  • y: The coordinate along the welding travel direction.
  • ϕ: The Phase, which adjusts the starting point of the waveform.

Advantage: You can obtain a bead shape that looks visually very close to reality.

Python sample code

Based on the CSV data you provided, this generates 2,000 lines along the Y axis to produce a 3D point cloud (PLY file) that makes up the entire weld surface.

To capture the feel of a real weld, the virtual data adds fine Gaussian noise and bead position Wandering to each line.

## 이 코드는 원본 데이터 1장을 읽어 Y축으로 2,000번 반복하며 데이터를 확장합니다. 각 좌표는 (X,Y,Z) 형태로 저장됩니다.

import pandas as pd
import numpy as np

# 1. 원본 데이터 로드 (X, Z)
# 사용자 데이터: 컬럼명 없이 x, z 순서로 구성됨
df = pd.read_csv('20260415-butt_bead_profile_sample.csv', names=['x', 'z'])

y_steps = 2000      # 요청하신 2,000개 라인
y_interval = 0.05   # Y축 간격 (mm) - 적절한 밀도를 위해 설정

points = []

print("포인트 생성 중...")
for i in range(y_steps):
    y_val = i * y_interval

    # 현실성을 위한 무작위 변위 추가
    # 1. Z축 노이즈 (센서 노이즈 모사: ±0.005mm)
    z_noise = np.random.normal(0, 0.005, len(df))
    # 2. X축 미세 흔들림 (용접 진행 시 좌우 유동 모사)
    x_shift = np.sin(i * 0.05) * 0.02 

    for idx, row in df.iterrows():
        points.append([row['x'] + x_shift, y_val, row['z'] + z_noise[idx]])

# 2. PLY 파일 형식으로 저장
def save_ply(filename, points):
    header = f"""ply
format ascii 1.0
element vertex {len(points)}
property float x
property float y
property float z
end_header
"""
    with open(filename, 'w') as f:
        f.write(header)
        for p in points:
            f.write(f"{p[0]:.4f} {p[1]:.4f} {p[2]:.4f}\n")

save_ply('welding_bead_3d.ply', points)
print(f"완료! 총 {len(points)}개의 포인트가 'welding_bead_3d.ply'로 저장되었습니다.")

Detailed data generation settings (Recipe)

Rather than simple duplication, the following factors were incorporated to make it suitable for testing quality evaluation algorithms.

  • Y-axis spacing (dy): The default spacing is set to 0.05mm so that the 2,000 lines are not too sparse (total length about 100mm).
  • Bead meandering (Wandering): The np.sin function makes the bead weave very slightly left and right. This simulates the hand tremor of a real welding robot or operator.
  • Surface roughness (Roughness): Gaussian noise reproduces the diffuse reflection noise that occurs when the LVS sensor captures a real metal surface.

Result files

The files created as ply were compressed: 20260415-butt_bead_profile_sample-all.zip

What's next?

See Pointcept:Examples:Weld:LVS for details.

See also

author Zer0 sitemap