Zivid로 캡처하면 프레임을 받게 됩니다. 포인트 클라우드는 프레임에 저장되고, 프레임은 GPU 메모리에 저장됩니다. 호출하는 메서드에 따라 캡처에 색상이 포함될 수도 있고 포함되지 않을 수도 있습니다. 자세한 내용은 다양한 캡처 모드가 포함된 이 table with different capture modes 표를 참조하세요.
이 메서드 Frame::pointCloud() 는 GPU 메모리에서 복사를 수행하지 않습니다.
참고
Camera::capture2D3D() 및 Camera::capture3D() 메서드는 카메라가 RAW 이미지 캡처를 완료한 후 특정 시점에 반환됩니다. Frame::pointCloud() 의 핸들은 즉시 사용할 수 있습니다. 그러나 실제 포인트 클라우드 데이터는 GPU에서 처리가 완료된 후에만 사용할 수 있습니다. 데이터 복사 함수(아래 섹션)에 대한 모든 호출은 차단되고 처리가 완료될 때까지 기다린 후 요청된 복사 작업을 진행합니다.
Frame.PointCloud 속성을 가져올 때는 GPU 메모리에서 복사를 수행하지 않습니다.
참고
Camera.Capture2D3D() 및 Camera.Capture3D() 메서드는 카메라가 RAW 이미지 캡처를 완료한 후 특정 시점에 반환됩니다. Frame.PointCloud 의 핸들은 즉시 사용할 수 있습니다. 그러나 실제 포인트 클라우드 데이터는 GPU에서 처리가 완료된 후에만 사용할 수 있습니다. 데이터 복사 메서드(아래 섹션)에 대한 모든 호출은 차단되고 처리가 완료될 때까지 기다린 후 요청된 복사 작업을 진행합니다.
zivid.frame.point_cloud() 함수는 GPU 메모리에서 복사를 수행하지 않습니다.
참고
zivid.camera.capture_2d_3d() 및 zivid.camera.capture_3d() 메서드는 카메라가 RAW 이미지 캡처를 완료한 후 특정 시점에 반환됩니다. zivid.frame.point_cloud() 의 핸들은 즉시 사용할 수 있습니다. 그러나 실제 포인트 클라우드 데이터는 GPU에서 처리가 완료된 후에만 사용할 수 있습니다. 데이터 복사 함수(아래 섹션)에 대한 모든 호출은 차단되고 처리가 완료될 때까지 기다린 후 요청된 복사 작업을 진행합니다.
std::cout<<"Capturing frame"<<std::endl;frame=camera.capture2D3D(settings);constautoframe2D=frame.frame2D();if(!frame2D.has_value()){throwstd::runtime_error("Captured frame does not contain a 2D image.");}std::cout<<"Copying colors with Zivid API from GPU to CPU"<<std::endl;autocolors=frame2D->imageBGRA_SRGB();std::cout<<"Casting the data pointer as a void*, since this is what the OpenCV matrix constructor requires."<<std::endl;auto*dataPtrZividAllocated=const_cast<void*>(static_cast<constvoid*>(colors.data()));std::cout<<"Wrapping this block of data in an OpenCV matrix. This is possible since the layout of \n"<<"Zivid::ColorBGRA_SRGB exactly matches the layout of CV_8UC4. No copying occurs in this step."<<std::endl;constcv::MatbgraZividAllocated(colors.height(),colors.width(),CV_8UC4,dataPtrZividAllocated);std::cout<<"Displaying image"<<std::endl;cv::imshow("BGRA image Zivid Allocated",bgraZividAllocated);cv::waitKey(CI_WAITKEY_TIMEOUT_IN_MS);
Copy selected data from GPU to CPU memory (user-allocated)
위 예에서 데이터의 소유권은 반환된 Zivid::Array2D<> 객체가 가지고 있습니다. 또는 Zivid::PointCloud::copyData(dataPtr) 에 사전 할당된 메모리 버퍼를 제공할 수도 있습니다. dataPtr 의 유형에 따라 복사할 대상이 정의됩니다(PointXYZ, ColorRGBA 등).
이제 위와 똑같은 사용 사례를 살펴보겠습니다. 그러나 이번에는 OpenCV가 필요한 스토리지를 할당하도록 허용합니다. 그런 다음 GPU에서 이 메모리 위치로 데이터를 직접 복사하도록 Zivid API에 요청합니다.
std::cout<<"Allocating the necessary storage with OpenCV API based on resolution info before any capturing"<<std::endl;autobgraUserAllocated=cv::Mat(resolution.height(),resolution.width(),CV_8UC4);std::cout<<"Capturing frame"<<std::endl;autoframe=camera.capture2D3D(settings);autopointCloud=frame.pointCloud();std::cout<<"Copying data with Zivid API from the GPU into the memory location allocated by OpenCV"<<std::endl;pointCloud.copyData(&(*bgraUserAllocated.begin<Zivid::ColorBGRA_SRGB>()));std::cout<<"Displaying image"<<std::endl;cv::imshow("BGRA image User Allocated",bgraUserAllocated);cv::waitKey(CI_WAITKEY_TIMEOUT_IN_MS);
더 보기
각 데이터 유형을 GPU에서 시스템 메모리로 복사하는 데 걸리는 시간에 대한 벤치마크는 Copy Speed 를 참조하세요.
관심 객체가 ROI로 자른 포인트 클라우드의 부분집합인 경우, 바이너리 마스크를 적용하여 이를 더욱 정교하게 다듬을 수 있습니다. 일반적인 작업 흐름은 2D 이미지를 캡처하고 세그멘테이션 알고리즘을 실행하여 객체를 식별한 다음, 그 결과 마스크를 3D 포인트 클라우드에 적용하는 것입니다. 이렇게 하면 세그멘테이션된 영역 밖의 모든 포인트가 무효화됩니다.
You can mask the point cloud to keep only a specific region of interest.
A typical use case is to capture a 2D image, run it through a segmentation algorithm to produce a binary mask, and apply it to the 3D point cloud.
Non-zero values in the mask invalidate the corresponding points (set to NaN), while zero values preserve them.
The mask can be applied using PointCloud::mask() (in-place) or PointCloud::masked() (returns a new copy), on both PointCloud and Frame.
// Create a ones-filled maskZivid::Maskmask(resolution);// Calculate rectangle boundsconstintheight=static_cast<int>(resolution.height());constintwidth=static_cast<int>(resolution.width());constintheightMin=(height-pixelsToDisplay)/2;constintheightMax=(height+pixelsToDisplay)/2;constintwidthMin=(width-pixelsToDisplay)/2;constintwidthMax=(width+pixelsToDisplay)/2;// Create OpenCV Mat wrapper for the mask datacv::MatmaskMat(height,width,CV_8UC1,mask.data());// Draw filled rectangle on the mask to unmask the central regioncv::rectangle(maskMat,cv::Point(widthMin,heightMin),cv::Point(widthMax,heightMax),cv::Scalar(0),cv::FILLED);returnmask;automaskedPointCloud=pointCloud.masked(mask);
// Create a ones-filled maskvarmask=newZivid.NET.Mask(resolution);// Calculate rectangle boundsintheight=(int)resolution.Height;intwidth=(int)resolution.Width;intheightMin=(height-pixelsToDisplay)/2;intheightMax=(height+pixelsToDisplay)/2;intwidthMin=(width-pixelsToDisplay)/2;intwidthMax=(width+pixelsToDisplay)/2;// Set pixels inside the rectangle to zerofor(inty=heightMin;y<heightMax;++y){for(intx=widthMin;x<widthMax;++x){mask[x,y]=0;}}returnmask;varmaskedPointCloud=pointCloud.Masked(mask);
pixels_to_display=300print(f"Generating binary mask of central {pixels_to_display} x {pixels_to_display} pixels")height=frame.point_cloud().heightwidth=frame.point_cloud().widthmask=np.ones((height,width),bool)h_min=(height-pixels_to_display)//2h_max=(height+pixels_to_display)//2w_min=(width-pixels_to_display)//2w_max=(width+pixels_to_display)//2mask[h_min:h_max,w_min:w_max]=0print("Masking point cloud")point_cloud.mask(mask)
// Create a circular mask in OpenCVconstintcenterX=static_cast<int>(resolution.width())/2;constintcenterY=static_cast<int>(resolution.height())/2;constintradius=pixelsToDisplay;cv::circle(opencvMask,cv::Point(centerX,centerY),radius,cv::Scalar(0),cv::FILLED);// Convert OpenCV mask to Zivid::MaskconstZivid::MaskcircularMask(resolution,opencvMask.datastart,opencvMask.dataend);
UnorganizedPointCloud 는 Voxel 다운샘플링을 지원합니다. 이 API는 두 가지 인수를 사용합니다.
voxelSize - Voxel의 크기(밀리미터)입니다.
minPointsPerVoxel - Voxel당 유지하기 위한 최소 포인트 수입니다.
Voxel 다운샘플링은 3D 공간을 주어진 크기의 입방 Voxel 격자로 세분화합니다. 주어진 Voxel에 주어진 한계 이상의 여러 포인트들이 포함된 경우, 모든 소스 포인트는 다음과 같은 속성을 가진 단일 포인트로 대체됩니다.
위치(XYZ)는 소스 지점 위치의 SNR 가중 평균입니다. 즉, 신뢰도가 높은 소스 지점은 신뢰도가 낮은 소스 지점보다 결과 위치에 더 큰 영향을 미칩니다.
색상(RGBA)은 소스 포인트의 색상의 평균입니다.
신호 대 잡음비(SNR)는 소스 포인트의 SNR 값의 sqrt(SNR^2의 합)입니다. 즉, 새 포인트의 SNR은 위치를 계산하는 데 사용된 소스 포인트의 수와 신뢰도가 높아질수록 증가합니다.
minPointsPerVoxel > 1을 사용하면 여러 각도에서 촬영된 포인트 클라우드의 조합인 비정형 포인트 클라우드에서 노이즈와 아티팩트를 제거하는 데 특히 유용합니다. 특정 아티팩트는 두 캡처 중 하나에만 존재할 가능성이 높기 때문에 minPointsPerVoxel을 사용하면 두 캡처가 “동의하는” Voxel로만 채울 수 있습니다.
std::cout<<"Setting up visualization"<<std::endl;Zivid::Visualization::Visualizervisualizer;std::cout<<"Visualizing point cloud"<<std::endl;visualizer.showMaximized();visualizer.show(frame);visualizer.resetToFit();std::cout<<"Running visualizer. Blocking until window closes."<<std::endl;visualizer.run();
Console.WriteLine("Setting up visualization");using(varvisualizer=newZivid.NET.Visualization.Visualizer()){Console.WriteLine("Visualizing point cloud");visualizer.Show(frame);visualizer.ShowMaximized();visualizer.ResetToFit();Console.WriteLine("Running visualizer. Blocking until window closes.");visualizer.Run();}
print("Visualizing point cloud")withzivid.visualization.Visualizer()asvisualizer:visualizer.set_window_title("Zivid Point Cloud Visualizer")visualizer.colors_enabled=Truevisualizer.axis_indicator_enabled=Truevisualizer.show(frame)visualizer.reset_to_fit()visualizer.run()
std::cout<<"Getting point cloud from frame"<<std::endl;autopointCloud=frame.pointCloud();std::cout<<"Setting up visualization"<<std::endl;Zivid::Visualization::Visualizervisualizer;std::cout<<"Visualizing point cloud"<<std::endl;visualizer.showMaximized();visualizer.show(pointCloud);visualizer.resetToFit();std::cout<<"Running visualizer. Blocking until window closes."<<std::endl;visualizer.run();
Console.WriteLine("Getting point cloud from frame");varpointCloud=frame.PointCloud;Console.WriteLine("Setting up visualization");varvisualizer=newZivid.NET.Visualization.Visualizer();Console.WriteLine("Visualizing point cloud");visualizer.Show(pointCloud);visualizer.ShowMaximized();visualizer.ResetToFit();Console.WriteLine("Running visualizer. Blocking until window closes.");visualizer.Run();
point_cloud=frame.point_cloud()withzivid.visualization.Visualizer()asvisualizer:visualizer.set_window_title("Zivid Point Cloud Visualizer")visualizer.colors_enabled=Truevisualizer.axis_indicator_enabled=Truevisualizer.show(point_cloud)visualizer.reset_to_fit()visualizer.run()
자세한 내용은 다음을 확인하세요. Visualization Tutorial, 여기서 우리는 타사 라이브러리를 사용하여 포인트 클라우드, 컬러 이미지, 깊이 맵 및 법선 시각화를 다룹니다.