Capture Tutorial
Introduction
이 튜토리얼에서는 Zivid SDK를 사용하여 포인트 클라우드 및 2D 이미지를 캡처하는 방법을 설명합니다.
Prerequisites
설치 Zivid Software.
Python의 경우: zivid-python 을 설치합니다.
Initialize
Zivid SDK에서 API를 호출하려면 Zivid 애플리케이션을 초기화하고 프로그램이 실행되는 동안 활성 상태를 유지해야 합니다.
참고
Zivid::Application Zivid 카메라를 작동하는 동안 살아 있어야 합니다. 이것은 본질적으로 Zivid 드라이버입니다.
Connect
이제 카메라에 연결할 수 있습니다.
Specific Camera
때로는 여러 대의 카메라가 동일한 컴퓨터에 연결되어 있지만 코드에서 특정 카메라로 작업해야 할 수도 있습니다. 원하는 카메라의 일련 번호를 제공하면 됩니다.
auto camera = zivid.connectCamera(Zivid::CameraInfo::SerialNumber{ "2020C0DE" });
var camera = zivid.ConnectCamera(new Zivid.NET.CameraInfo.SerialNumber("2020C0DE"));
camera = app.connect_camera(serial_number="2020C0DE")
참고
카메라의 일련 번호는 Zivid Studio에 표시됩니다.
컴퓨터에 연결된 모든 카메라를 나열하고 일련 번호도 확인할 수 있습니다.
auto cameras = zivid.cameras();
std::cout << "Found " << cameras.size() << " cameras" << std::endl;
for(auto &camera : cameras)
{
std::cout << "Camera Info: " << camera.info() << std::endl;
std::cout << "Camera State: " << camera.state() << std::endl;
}
Configure
모든 카메라와 마찬가지로 구성할 수 있는 설정이 있습니다.
Presets
Zivid Studio에서 제공하는 Presets 을 사용하거나 .yml 파일로 제공하는 것을 권장합니다(아래 참조). 프리셋은 대부분의 경우 바로 사용할 수 있도록 설계되어 있어 시작하기에 좋습니다. 필요한 경우 설정을 쉽게 미세 조정하여 더 나은 결과를 얻을 수 있습니다. YAML 파일은 모든 텍스트 편집기에서 편집하거나 설정을 수동으로 코딩할 수 있습니다.
Load
Zivid Studio에서 카메라 설정을 .yml 파일로 내보낼 수 있습니다. 이 설정은 API에서 로드하여 적용할 수 있습니다.
const auto settingsFile = "Settings.yml";
std::cout << "Loading settings from file: " << settingsFile << std::endl;
const auto settingsFromFile = Zivid::Settings(settingsFile);
Save
설정을 .yml 파일의 형태로 저장할 수 있습니다.
Manual configuration
또 다른 옵션은 설정을 수동으로 구성하는 것입니다. 각 설정의 기능에 대한 자세한 내용은 Camera Settings 을 참조하세요. 그 다음 단계는 Capturing High Quality Point Clouds 입니다.
Single 2D and 3D Acquisition - Default settings
단일 획득 캡처에 대한 설정을 만들 수 있습니다.
const auto settings =
Zivid::Settings{ Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} },
Zivid::Settings::Color{ Zivid::Settings2D{
Zivid::Settings2D::Acquisitions{ Zivid::Settings2D::Acquisition{} } } } };
Multi Acquisition HDR
We may also create settings with multiple acquisitions for an HDR capture.
using std::chrono::microseconds;
Zivid::Settings settings;
for(const auto exposure : { microseconds{ 1000 }, microseconds{ 10000 } })
{
std::cout << "Adding acquisition with exposure time of " << exposure.count() << " microseconds "
<< std::endl;
const auto acquisitionSettings = Zivid::Settings::Acquisition{
Zivid::Settings::Acquisition::ExposureTime{ exposure },
};
settings.acquisitions().emplaceBack(acquisitionSettings);
}
var settings = new Zivid.NET.Settings();
foreach (var exposure in new Duration[] { Duration.FromMicroseconds(1000), Duration.FromMicroseconds(10000) })
{
Console.WriteLine("Adding acquisition with exposure time of " + exposure.Microseconds + " microseconds");
var acquisitionSettings = new Zivid.NET.Settings.Acquisition { ExposureTime = exposure };
settings.Acquisitions.Add(acquisitionSettings);
}
settings.Color = new Zivid.NET.Settings2D { Acquisitions = { new Zivid.NET.Settings2D.Acquisition { } } };
settings = zivid.Settings()
for exposure in [1000, 10000]:
print(f"Adding acquisition with exposure time of {exposure} microseconds")
settings.acquisitions.append(
zivid.Settings.Acquisition(exposure_time=datetime.timedelta(microseconds=exposure))
)
Fully Configured Settings
2D Settings, such as color balance and gamma, configured manually:
std::cout << "Configuring settings for capture:" << std::endl;
Zivid::Settings2D settings2D{
Zivid::Settings2D::Sampling::Color::rgb,
Zivid::Settings2D::Sampling::Pixel::all,
Zivid::Settings2D::Sampling::Interval::Enabled::no,
Zivid::Settings2D::Sampling::Interval::Duration{ microseconds{ 10000 } },
Zivid::Settings2D::Processing::Color::Balance::Blue{ 1.0 },
Zivid::Settings2D::Processing::Color::Balance::Green{ 1.0 },
Zivid::Settings2D::Processing::Color::Balance::Red{ 1.0 },
Zivid::Settings2D::Processing::Color::Gamma{ 1.0 },
Zivid::Settings2D::Processing::Color::Experimental::Mode::automatic,
};
Console.WriteLine("Configuring settings for capture:");
var settings2D = new Zivid.NET.Settings2D()
{
Sampling =
{
Color = Zivid.NET.Settings2D.SamplingGroup.ColorOption.Rgb,
Pixel = Zivid.NET.Settings2D.SamplingGroup.PixelOption.All,
Interval =
{
Enabled = false,
Duration = Duration.FromMicroseconds(10000),
},
},
Processing =
{
Color =
{
Balance =
{
Blue = 1.0,
Green = 1.0,
Red = 1.0,
},
Gamma = 1.0,
Experimental = { Mode = Zivid.NET.Settings2D.ProcessingGroup.ColorGroup.ExperimentalGroup.ModeOption.Automatic },
},
},
};
print("Configuring settings for capture:")
settings_2d = zivid.Settings2D()
settings_2d.sampling.color = zivid.Settings2D.Sampling.Color.rgb
settings_2d.sampling.pixel = zivid.Settings2D.Sampling.Pixel.all
settings_2d.sampling.interval.enabled = False
settings_2d.sampling.interval.duration = timedelta(microseconds=10000)
settings_2d.processing.color.balance.red = 1.0
settings_2d.processing.color.balance.blue = 1.0
settings_2d.processing.color.balance.green = 1.0
settings_2d.processing.color.gamma = 1.0
settings_2d.processing.color.experimental.mode = zivid.Settings2D.Processing.Color.Experimental.Mode.automatic
Manually configured 3D settings such as engine, region of interest, filter settings and more:
Zivid::Settings settings{
Zivid::Settings::Color{ settings2D },
Zivid::Settings::Engine::stripe,
Zivid::Settings::RegionOfInterest::Box::Enabled::yes,
Zivid::Settings::RegionOfInterest::Box::PointO{ 1000, 1000, 1000 },
Zivid::Settings::RegionOfInterest::Box::PointA{ 1000, -1000, 1000 },
Zivid::Settings::RegionOfInterest::Box::PointB{ -1000, 1000, 1000 },
Zivid::Settings::RegionOfInterest::Box::Extents{ -1000, 1000 },
Zivid::Settings::RegionOfInterest::Depth::Enabled::yes,
Zivid::Settings::RegionOfInterest::Depth::Range{ 200, 2000 },
Zivid::Settings::Processing::Filters::Cluster::Removal::Enabled::yes,
Zivid::Settings::Processing::Filters::Cluster::Removal::MaxNeighborDistance{ 10 },
Zivid::Settings::Processing::Filters::Cluster::Removal::MinArea{ 100 },
Zivid::Settings::Processing::Filters::Hole::Repair::Enabled::yes,
Zivid::Settings::Processing::Filters::Hole::Repair::HoleSize{ 0.2 },
Zivid::Settings::Processing::Filters::Hole::Repair::Strictness{ 1 },
Zivid::Settings::Processing::Filters::Noise::Removal::Enabled::yes,
Zivid::Settings::Processing::Filters::Noise::Removal::Threshold{ 7.0 },
Zivid::Settings::Processing::Filters::Noise::Suppression::Enabled::yes,
Zivid::Settings::Processing::Filters::Noise::Repair::Enabled::yes,
Zivid::Settings::Processing::Filters::Outlier::Removal::Enabled::yes,
Zivid::Settings::Processing::Filters::Outlier::Removal::Threshold{ 5.0 },
Zivid::Settings::Processing::Filters::Reflection::Removal::Enabled::yes,
Zivid::Settings::Processing::Filters::Reflection::Removal::Mode::global,
Zivid::Settings::Processing::Filters::Smoothing::Gaussian::Enabled::yes,
Zivid::Settings::Processing::Filters::Smoothing::Gaussian::Sigma{ 1.5 },
Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Correction::Enabled::yes,
Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Correction::Strength{ 0.4 },
Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Removal::Enabled::no,
Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Removal::Threshold{ 0.5 },
Zivid::Settings::Processing::Resampling::Mode::upsample2x2,
Zivid::Settings::Diagnostics::Enabled::no,
};
setSamplingPixel(settings, camera);
std::cout << settings << std::endl;
var settings = new Zivid.NET.Settings()
{
Engine = Zivid.NET.Settings.EngineOption.Stripe,
RegionOfInterest =
{
Box = {
Enabled = true,
PointO = new Zivid.NET.PointXYZ{ x = 1000, y = 1000, z = 1000 },
PointA = new Zivid.NET.PointXYZ{ x = 1000, y = -1000, z = 1000 },
PointB = new Zivid.NET.PointXYZ{ x = -1000, y = 1000, z = 1000 },
Extents = new Zivid.NET.Range<double>(-1000, 1000),
},
Depth =
{
Enabled = true,
Range = new Zivid.NET.Range<double>(200, 2000),
},
},
Processing =
{
Filters =
{
Cluster =
{
Removal = { Enabled = true, MaxNeighborDistance = 10, MinArea = 100}
},
Hole =
{
Repair = { Enabled = true, HoleSize = 0.2, Strictness = 1 },
},
Noise =
{
Removal = { Enabled = true, Threshold = 7.0 },
Suppression = { Enabled = true },
Repair = { Enabled = true },
},
Outlier =
{
Removal = { Enabled = true, Threshold = 5.0 },
},
Reflection =
{
Removal = { Enabled = true, Mode = ReflectionFilterModeOption.Global },
},
Smoothing =
{
Gaussian = { Enabled = true, Sigma = 1.5 },
},
Experimental =
{
ContrastDistortion =
{
Correction = { Enabled = true, Strength = 0.4 },
Removal = { Enabled = true, Threshold = 0.5 },
},
},
},
Resampling = { Mode = Zivid.NET.Settings.ProcessingGroup.ResamplingGroup.ModeOption.Upsample2x2 },
},
Diagnostics = { Enabled = false },
};
settings.Color = settings2D;
SetSamplingPixel(ref settings, camera);
Console.WriteLine(settings);
settings = zivid.Settings()
settings.engine = zivid.Settings.Engine.stripe
settings.region_of_interest.box.enabled = True
settings.region_of_interest.box.point_o = [1000, 1000, 1000]
settings.region_of_interest.box.point_a = [1000, -1000, 1000]
settings.region_of_interest.box.point_b = [-1000, 1000, 1000]
settings.region_of_interest.box.extents = [-1000, 1000]
settings.region_of_interest.depth.enabled = True
settings.region_of_interest.depth.range = [200, 2000]
settings.processing.filters.cluster.removal.enabled = True
settings.processing.filters.cluster.removal.max_neighbor_distance = 10
settings.processing.filters.cluster.removal.min_area = 100
settings.processing.filters.hole.repair.enabled = True
settings.processing.filters.hole.repair.hole_size = 0.2
settings.processing.filters.hole.repair.strictness = 1
settings.processing.filters.noise.removal.enabled = True
settings.processing.filters.noise.removal.threshold = 7.0
settings.processing.filters.noise.suppression.enabled = True
settings.processing.filters.noise.repair.enabled = True
settings.processing.filters.outlier.removal.enabled = True
settings.processing.filters.outlier.removal.threshold = 5.0
settings.processing.filters.reflection.removal.enabled = True
settings.processing.filters.reflection.removal.mode = (
zivid.Settings.Processing.Filters.Reflection.Removal.Mode.global_
)
settings.processing.filters.smoothing.gaussian.enabled = True
settings.processing.filters.smoothing.gaussian.sigma = 1.5
settings.processing.filters.experimental.contrast_distortion.correction.enabled = True
settings.processing.filters.experimental.contrast_distortion.correction.strength = 0.4
settings.processing.filters.experimental.contrast_distortion.removal.enabled = False
settings.processing.filters.experimental.contrast_distortion.removal.threshold = 0.5
settings.processing.resampling.mode = zivid.Settings.Processing.Resampling.Mode.upsample2x2
settings.diagnostics.enabled = False
settings.color = settings_2d
_set_sampling_pixel(settings, camera)
print(settings)
Different values per acquisition are also possible:
std::cout << "Configuring acquisition settings different for all HDR acquisitions" << std::endl;
const auto baseAcquisition = Zivid::Settings::Acquisition{};
std::cout << baseAcquisition << std::endl;
auto exposureValues = getExposureValues(camera);
const std::vector<double> aperture = std::get<0>(exposureValues);
const std::vector<double> gain = std::get<1>(exposureValues);
const std::vector<std::chrono::microseconds> exposureTime = std::get<2>(exposureValues);
const std::vector<double> brightness = std::get<3>(exposureValues);
for(size_t i = 0; i < aperture.size(); ++i)
{
std::cout << "Acquisition " << i + 1 << ":" << std::endl;
std::cout << " Exposure Time: " << exposureTime.at(i).count() << std::endl;
std::cout << " Aperture: " << aperture.at(i) << std::endl;
std::cout << " Gain: " << gain.at(i) << std::endl;
std::cout << " Brightness: " << brightness.at(i) << std::endl;
const auto acquisitionSettings = baseAcquisition.copyWith(
Zivid::Settings::Acquisition::Aperture{ aperture.at(i) },
Zivid::Settings::Acquisition::Gain{ gain.at(i) },
Zivid::Settings::Acquisition::ExposureTime{ exposureTime.at(i) },
Zivid::Settings::Acquisition::Brightness{ brightness.at(i) });
settings.acquisitions().emplaceBack(acquisitionSettings);
}
const auto aquisitionSettings2D = makeSettings2D(camera).acquisitions();
settings.color().value().set(aquisitionSettings2D);
Console.WriteLine("Configuring acquisition settings different for all HDR acquisitions:");
var baseAcquisition = new Zivid.NET.Settings.Acquisition { };
Console.WriteLine(baseAcquisition);
var baseAcquisition2D = new Zivid.NET.Settings2D.Acquisition { };
Tuple<double[], Duration[], double[], double[]> exposureValues = GetExposureValues(camera);
double[] aperture = exposureValues.Item1;
Duration[] exposureTime = exposureValues.Item2;
double[] gain = exposureValues.Item3;
double[] brightness = exposureValues.Item4;
for (int i = 0; i < aperture.Length; i++)
{
Console.WriteLine("Acquisition {0}:", i + 1);
Console.WriteLine(" Exposure Time: {0}", exposureTime[i].Microseconds);
Console.WriteLine(" Aperture: {0}", aperture[i]);
Console.WriteLine(" Gain: {0}", gain[i]);
Console.WriteLine(" Brightness: {0}", brightness[i]);
var acquisitionSettings = baseAcquisition.CopyWith(s =>
{
s.Aperture = aperture[i];
s.ExposureTime = exposureTime[i];
s.Gain = gain[i];
s.Brightness = brightness[i];
});
settings.Acquisitions.Add(acquisitionSettings);
}
var aquisitionSettings2D = MakeSettings2D(camera);
settings.Color.Acquisitions = aquisitionSettings2D.Acquisitions;
print("Configuring acquisition settings different for all HDR acquisitions")
exposure_values = _get_exposure_values(camera)
for aperture, gain, exposure_time, brightness in exposure_values:
settings.acquisitions.append(
zivid.Settings.Acquisition(
aperture=aperture,
exposure_time=exposure_time,
brightness=brightness,
gain=gain,
)
)
acquisition_settings_2d = make_settings_2d(camera).Acquisition()
settings.color.acquisitions.append(acquisition_settings_2d)
Capture 2D3D
이제 2D 및 3D 이미지(컬러 포인트 클라우드)를 캡처할 수 있습니다. 단일 획득인지 다중 획득인지(HDR)는 settings 의 acquisitions 횟수에 따라 결정됩니다.
Zivid::Frame 에는 포인트 클라우드, 컬러 이미지, 캡처, 카메라 정보가 포함되어 있으며, 이 모든 정보는 컴퓨팅 장치 메모리에 저장됩니다.
Zivid.NET.Frame 에는 포인트 클라우드, 컬러 이미지, 캡처, 카메라 정보가 포함되어 있으며, 이 모든 정보는 컴퓨팅 장치 메모리에 저장됩니다.
zivid.Frame 에는 포인트 클라우드, 컬러 이미지, 캡처, 카메라 정보가 포함되어 있으며, 이 모든 정보는 컴퓨팅 장치 메모리에 저장됩니다.
Capture 3D
색상이 없는 3D 포인트 클라우드만 캡처하려면 capture3D API를 사용하면 됩니다.
Capture 2D
3D보다 빠른 2D 이미지만 캡처하고 싶은 경우 capture2D API를 사용하면 됩니다.
Save
이제 결과를 저장할 수 있습니다.
팁
Zivid Studio 에서 Frame.zdf 파일을 열고 볼 수 있습니다.
Export
다음 코드 예제에서는 포인트 클라우드를 .ply 형식으로 내보냅니다. 다른 내보내기 옵션은 Point Cloud 에서 지원되는 형식 목록을 참조하세요.
Load
프레임을 저장하면 ZDF 파일에서 로드할 수 있습니다.
const auto dataFile = std::string(ZIVID_SAMPLE_DATA_DIR) + "/Zivid3D.zdf";
std::cout << "Reading ZDF frame from file: " << dataFile << std::endl;
const auto frame = Zivid::Frame(dataFile);
Save 2D
capture2D() 함수에서 Frame2D 함수를 얻습니다. 2D 이미지에는 선형 RGB와 sRGB, 두 가지 색상 공간이 있습니다. imageRGBA() 함수는 선형 RGB 색상 공간의 이미지를 반환합니다. 함수 이름에 _SRGB 를 추가하면 반환되는 이미지는 sRGB 색상 공간입니다.
그러면 2D 이미지를 선형 RGB 또는 sRGB 색상 공간에 저장할 수 있습니다.
![]()
const auto imageFile = "ImageRGBA_linear.png"; std::cout << "Saving 2D color image (Linear RGB) to file: " << imageFile << std::endl; imageRGBA.save(imageFile);
![]()
const auto imageFile = "ImageRGBA_sRGB.png"; std::cout << "Saving 2D color image (sRGB color space) to file: " << imageFile << std::endl; imageSRGB.save(imageFile);
포인트 클라우드에서 직접 2D 컬러 이미지를 얻을 수 있습니다. 이 이미지는 포인트 클라우드와 동일한 해상도를 가지며 sRGB 색 공간에 속합니다.
const auto pointCloud = frame.pointCloud();
const auto image2DInPointCloudResolution = pointCloud.copyImageRGBA_SRGB();
var pointCloud = frame.PointCloud;
var image2DInPointCloudResolution = pointCloud.CopyImageRGBA_SRGB();
point_cloud = frame.point_cloud()
image_2d_in_point_cloud_resolution = point_cloud.copy_image("bgra_srgb")
capture2D3D() 객체의 일부인 Frame 에서 얻은 Frame2D 에서 2D 컬러 이미지를 가져올 수 있습니다. 이 이미지는 2D3D 설정 내의 2D 설정에 지정된 해상도를 갖습니다.
const auto image2D = frame.frame2D().value().imageBGRA_SRGB();
var image2D = frame.Frame2D.ImageBGRA_SRGB();
image_2d = frame.frame_2d().image_bgra_srgb()
File Camera
A file camera allows you to experiment with the SDK without access to a physical camera. The file cameras can be found in Sample Data where there are multiple file cameras to choose from.
const auto fileCamera =
userInput ? fileCameraPath : std::string(ZIVID_SAMPLE_DATA_DIR) + "/FileCameraZivid2PlusMR60.zfc";
획득 설정은 아래와 같이 초기화되어야 하지만 처리 설정을 자유롭게 변경할 수 있습니다.
Zivid::Settings settings{
Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} },
Zivid::Settings::Processing::Filters::Smoothing::Gaussian::Enabled::yes,
Zivid::Settings::Processing::Filters::Smoothing::Gaussian::Sigma{ 1.5 },
Zivid::Settings::Processing::Filters::Reflection::Removal::Enabled::yes,
Zivid::Settings::Processing::Filters::Reflection::Removal::Mode::global,
};
Zivid::Settings2D settings2D{ Zivid::Settings2D::Acquisitions{ Zivid::Settings2D::Acquisition{} },
Zivid::Settings2D::Processing::Color::Balance::Red{ 1 },
Zivid::Settings2D::Processing::Color::Balance::Green{ 1 },
Zivid::Settings2D::Processing::Color::Balance::Blue{ 1 } };
settings.color() = Zivid::Settings::Color{ settings2D };
var settings2D = new Zivid.NET.Settings2D
{
Acquisitions = { new Zivid.NET.Settings2D.Acquisition { } },
Processing =
{
Color =
{
Balance = { Red = 1.0, Green = 1.0, Blue = 1.0 }
}
}
};
var settings = new Zivid.NET.Settings
{
Acquisitions = { new Zivid.NET.Settings.Acquisition { } },
Processing =
{
Filters =
{
Smoothing =
{
Gaussian = { Enabled = true, Sigma = 1.5 }
},
Reflection =
{
Removal = { Enabled = true, Mode = ReflectionFilterModeOption.Global}
}
}
}
};
settings.Color = settings2D;
settings = zivid.Settings()
settings.acquisitions.append(zivid.Settings.Acquisition())
settings.processing.filters.smoothing.gaussian.enabled = True
settings.processing.filters.smoothing.gaussian.sigma = 1
settings.processing.filters.reflection.removal.enabled = True
settings.processing.filters.reflection.removal.mode = "global"
settings_2d = zivid.Settings2D()
settings_2d.acquisitions.append(zivid.Settings2D.Acquisition())
settings_2d.processing.color.balance.blue = 1.0
settings_2d.processing.color.balance.green = 1.0
settings_2d.processing.color.balance.red = 1.0
settings.color = settings_2d
파일 카메라 옵션에 대한 자세한 내용은 File Camera 에서 확인할 수 있습니다.
Multithreading
카메라 개체에 대한 작업은 스레드로부터 안전하지만 카메라 나열 및 카메라 연결과 같은 다른 작업은 순서대로 실행해야 합니다. 자세한 내용은 Multithreading 알아보십시오.
Conclusion
이 튜토리얼은 Zivid SDK를 사용하여 Zivid 카메라에 연결, 구성, 캡처 및 저장하는 방법을 보여줍니다.