主頁 >  其他 > 圖漾深度相機開發-PCL點云實時顯示

圖漾深度相機開發-PCL點云實時顯示

2021-08-20 09:38:33 其他

目錄

  • 1. 從示例程式 SimpleView_FetchFrame 開始
    • 程式功能
    • 程式解讀
  • 2. 創建自己的點云處理程式
    • 檔案結構
    • 創建點云
    • 點云圖實時顯示完整代碼
  • 3. 新建工程


  • 相機型號:圖漾科技 FS820 深度相機
    【引數資訊】【深度相機開發說明檔案】【SDK下載】
  • 編譯環境:Ubuntu 18.04 / C++ / VS code
  • 依賴庫:OpenCV + PCL
  • 圖漾深度相機初步使用流程見博客,在能簡單應用相機示例程式的基礎上,對相機進行開發,以實作三維點云處理,本文實作的功能是顯示實時點云圖
    在這里插入圖片描述

1. 從示例程式 SimpleView_FetchFrame 開始

程式功能

SimpleView_FetchFrame 是深度相機獲取影像資料并在資料獲取執行緒中進行 OpenCV 渲染的示例程式,以此為例說明影像獲取流程【影像獲取的完整流程】

運行程式,生成 color彩色影像、depth深度影像、leftIR、rightIR 視窗

在這里插入圖片描述

程式解讀

打開 sample/SimpleView_FetchFrame/main.cpp,解讀代碼:

從主函式開始閱讀,可以看到多個 LOGD() 函式,這些函式實作的是列印功能,相當于程式中的注釋(如 LOGD("Init lib"),說明下一段代碼的功能是初始化 API,初始化設備物件等資料結構)

對于開發者而言,我們需要關注的是如何獲取相機的資料,以進行后續的處理,也就是下圖中的 Loop 回圈部分,這一回圈的作用是不斷獲取相機的幀資料,并對資料進行處理(本例中的處理效果即為生成 color彩色影像、depth深度影像、leftIR、rightIR 視窗)
在這里插入圖片描述
因此我們繼續往下閱讀代碼,讀到 LOGD("While loop to fetch frame") 陳述句,下面一段程式的功能就是獲取相機幀回圈,貼出代碼進行解讀:

LOGD("While loop to fetch frame");
    bool exit_main = false;  
    TY_FRAME_DATA frame;
    int index = 0;
    while(!exit_main) {
        int err = TYFetchFrame(hDevice, &frame, -1);
        if( err == TY_STATUS_OK ) {
            LOGD("Get frame %d", ++index);

            int fps = get_fps();
            if (fps > 0){
                LOGI("fps: %d", fps);
            }

            cv::Mat depth, irl, irr, color;
            parseFrame(frame, &depth, &irl, &irr, &color, hColorIspHandle);
            if(!depth.empty()){
                depthViewer.show(depth);
            }
            if(!irl.empty()){ cv::imshow("LeftIR", irl); }
            if(!irr.empty()){ cv::imshow("RightIR", irr); }
            if(!color.empty()){ cv::imshow("Color", color); }

            int key = cv::waitKey(1);
            switch(key & 0xff) {
            case 0xff:
                break;
            case 'q':
                exit_main = true;
                break;
            default:
                LOGD("Unmapped key %d", key);
            }

            TYISPUpdateDevice(hColorIspHandle);
            LOGD("Re-enqueue buffer(%p, %d)"
                , frame.userBuffer, frame.bufferSize);
            ASSERT_OK( TYEnqueueBuffer(hDevice, frame.userBuffer, frame.bufferSize) );
        }
    }

首先定義了 bool 型變數exit_main:作為回圈的標志位,while(!exit_main) 表示當 exit_main = 1 時回圈結束

  • Fetch Frame
    這一段代碼的功能是獲取相機的幀資訊,即 frame:
int err = TYFetchFrame(hDevice, &frame, -1);
        if( err == TY_STATUS_OK ) {
            LOGD("Get frame %d", ++index);

            int fps = get_fps();
            if (fps > 0){
                LOGI("fps: %d", fps);
            }

這段代碼的核心部分為:TYFetchFrame(hDevice, &frame, -1),函式功能為 Fetch one frame,即通過輸入 hDevice 這一引數,獲取一幀相機的資訊到 frame 中,如果成功獲取幀資訊,則回傳值為 TY_STATUS_OK

err == TY_STATUS_OK (成功獲取幀資訊)時,會列印資訊:Get frame + (index 的值),表示當前獲取的是第幾幀,index 在每次回圈中加1,如下圖所示:

在這里插入圖片描述

  • Parse Frame
    這一段代碼的功能是決議獲取的幀資訊:
cv::Mat depth, irl, irr, color;
parseFrame(frame, &depth, &irl, &irr, &color, hColorIspHandle);

首先定義 cv::Mat 型別的深度圖 depth,彩色圖 color,左紅外影像 irl,右紅外影像 irr
接著通過 parseFrame() 函式決議 frame,分別生成深度圖、左右紅外圖和彩色圖

  • User Process
    在決議幀后,我們成功得到了相機的深度圖 depth 和彩色圖 color 等,用戶就可以利用獲取的資料進行處理和開發了,示例程式中實作的是簡單的影像顯示功能,即分別可視化深度圖、左右紅外圖和彩色圖:
if(!depth.empty()){
                depthViewer.show(depth);
            }
            if(!irl.empty()){ cv::imshow("LeftIR", irl); }
            if(!irr.empty()){ cv::imshow("RightIR", irr); }
            if(!color.empty()){ cv::imshow("Color", color); }

            int key = cv::waitKey(1);
            switch(key & 0xff) {
            case 0xff:
                break;
            case 'q':
                exit_main = true;
                break;
            default:
                LOGD("Unmapped key %d", key);
            }

如果在 openCV 的圖窗中,鍵盤按下 q 鍵,則exit_main = true,整個幀回圈會結束

  • Return Frame Buffer
TYISPUpdateDevice(hColorIspHandle);
LOGD("Re-enqueue buffer(%p, %d)" , frame.userBuffer, frame.bufferSize);
ASSERT_OK( TYEnqueueBuffer(hDevice, frame.userBuffer, frame.bufferSize) );

更新設備狀態,將 frame buffer 推入幀緩沖佇列

2. 創建自己的點云處理程式

檔案結構

最簡單的方式是直接在 sample 檔案夾創建一個新的檔案夾例如 point3D,并在該檔案夾中創建 main.cpp ,接著在 CMakeLists.txt 中修改以下部分即可:

set(ALL_SAMPLES
    point3D  # 加上自己命名的檔案夾
    DumpAllFeatures
    ListDevices
    ...

在 sample/build 目錄下打開終端,重新編譯運行即可:

cmake ..
make
cd bin
sudo ./point3D

創建點云

根據對示例程式的分析可知,通過 parseFrame(frame, &depth, &irl, &irr, &color, hColorIspHandle) 陳述句可以獲取相機的深度圖和彩色圖,處理深度圖得到位置資訊 ( x , y , z ) (x, y, z) (x,y,z) ,處理彩色圖得到顏色資訊 ( r , g , b ) (r, g, b) (r,g,b) ,最終生成包含顏色資訊的點云圖

使用 Point CLoud Library 處理點云,首先需要安裝 PCL 庫:

  • 安裝 PCL 庫
sudo apt install libpcl-dev
  • 修改 CMakeLists.txt 添加 PCL 庫

添加如下陳述句:

# ========================================
# === PCL
# ========================================
find_package(PCL 1.8 REQUIRED)
    include_directories(${PCL_INCLUDE_DIRS})
    link_directories(${PCL_LIBRARY_DIRS})
    add_definitions(${PCL_DEFINITIONS})

修改倒數第五行:

target_link_libraries(${sample} sample_common ${ABSOLUTE_TARGET_LIB} ${OpenCV_LIBS} ${CLOUD_VIEWER} ${PCL_LIBRARIES})
  • Map depth image to 3D points
    根據深度相機的標定引數,將深度圖映射為三維點云:

(1) 首先需要獲取深度相機的標定引數,根據官方檔案可知,利用 TYGetStruct() 函式即可:

 TY_CAMERA_CALIB_INFO depth_calib; 
 TYGetStruct(hDevice, TY_COMPONENT_DEPTH_CAM
 , TY_STRUCT_CAM_CALIB_DATA, &depth_calib,sizeof(depth_calib));  //  提取深度相機的標定資料

(2) 接著將深度圖轉換為三維資料:

std::vector<TY_VECT_3F> p3d;  // p3d 用于存盤三維資料
TYMapDepthImageToPoint3d(&depth_calib, depth.cols, depth.rows
, (uint16_t*)depth.data, &p3d[0]);  // 輸入深度資料和標定資料,輸出三維資料

p3d[i].x 表示第 i 個點的 x值;p3d[i].y 表示第 i 個點的 y值;p3d[i].z 表示第 i 個點的 z值

  • Map original RGB image to depth coordinate RGB image
    根據彩色相機的標定引數,將彩色圖與深度圖對齊:

(1) 首先需要獲取彩色相機的標定引數,根據官方檔案可知,利用 TYGetStruct() 函式即可:

 TY_CAMERA_CALIB_INFO color_calib; 
 TYGetStruct(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_CALIB_DATA
, &color_calib, sizeof(color_calib));  // 提取彩色相機的標定資料

(2) 彩色圖與深度圖對齊:
首先定義函式doRgbRegister(),實作對齊功能:

// 定義一個函式 doRgbRegister(),實作對齊功能
static void doRgbRegister(const TY_CAMERA_CALIB_INFO& depth_calib
                       , const TY_CAMERA_CALIB_INFO& color_calib
                       , const cv::Mat& depth
                       , const cv::Mat& color
                       , cv::Mat& out
                       )
{
    // do rgb undistortion
    TY_IMAGE_DATA src;
    src.width = color.cols;
    src.height = color.rows;
    src.size = color.size().area() * 3;
    src.pixelFormat = TY_PIXEL_FORMAT_RGB;
    src.buffer = color.data;

    cv::Mat  undistort_color = cv::Mat(color.size(), CV_8UC3);
    TY_IMAGE_DATA dst;
    dst.width = color.cols;
    dst.height = color.rows;
    dst.size = undistort_color.size().area() * 3;
    dst.buffer = undistort_color.data;
    dst.pixelFormat = TY_PIXEL_FORMAT_RGB;
    TYUndistortImage(&color_calib, &src, NULL, &dst);

    // do register
    out.create(depth.size(), CV_8UC3);
        TYMapRGBImageToDepthCoordinate(
        &depth_calib,
        depth.cols, depth.rows, depth.ptr<uint16_t>(),
        &color_calib,
        undistort_color.cols, undistort_color.rows, undistort_color.ptr<uint8_t>(),
        out.ptr<uint8_t>());
}

在主函式中呼叫函式doRgbRegister()

cv::Mat color_data_mat;  // color_data_mat 為對齊后的彩色圖
if (!color.empty())
{
bool hasColorCalib;
TYHasFeature(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_CALIB_DATA, &hasColorCalib);  // 查詢有無彩色相機標定引數這一屬性
    if (hasColorCalib) 
    {
    doRgbRegister(depth_calib, color_calib, depth, color, color_data_mat); // 輸入深度相機標定資料、彩色相機標定資料、深度圖和彩色圖,輸出對齊后的彩色圖
    cv::cvtColor(color_data_mat, color_data_mat, cv::COLOR_BGR2RGB);  // BGR 格式轉換為 RGB 格式
    }
}
  • 生成 PointXYZRGB 型別點云(核心代碼)
pcl::PointCloud<pcl::PointXYZRGB> cloud; // 生成的點云 cloud
pcl::PointXYZRGB point; 

for (int m = 0; m < depth.rows; m++)
    {
        for (int n=0; n < depth.cols; n++)
        {
            point.x = p3d[(m*(depth.cols)+n)].x;
            point.y = p3d[(m*(depth.cols)+n)].y;
            point.z = p3d[(m*(depth.cols)+n)].z;

            point.r = color_data_mat.at<cv::Vec3b>(m, n)[0];
            point.g = color_data_mat.at<cv::Vec3b>(m, n)[1];
            point.b =color_data_mat.at<cv::Vec3b>(m, n)[2];

            cloud.points.push_back(point); // 構造xyzrgb型別點云
        }
    }
    cloud.width = (uint32_t)cloud.points.size();
    cloud.height = 1;
  • 點云可視化
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer1(new pcl::visualization::PCLVisualizer("3D Viewer"));

pcl::PointCloud<pcl::PointXYZRGB>::Ptr basic_cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
basic_cloud_ptr = cloud.makeShared(); // 轉換為指標格式 basic_cloud_ptr
basic_cloud_ptr->is_dense = false;  //  自己創建的點云,默認為dense,需要修改屬性,否則removenanfrompointcloud函式無效
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
std::vector<int> mapping;
pcl::removeNaNFromPointCloud(*basic_cloud_ptr, *cloud_ptr, mapping); // 移除無效點

viewer1->removeAllPointClouds();  // 移除當前所有點云
viewer1->addPointCloud<pcl::PointXYZRGB> (cloud_ptr, "initial"); 
viewer1->updatePointCloud(cloud_ptr, "initial"); 
viewer1->spinOnce(100);

點云圖實時顯示完整代碼

#include <TYApi.h>
#include "TYImageProc.h"
#include "../common.hpp"

#include <vector>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>
#include <pcl/filters/filter.h>
#include <pcl/common/impl/io.hpp>

static void doRgbRegister(const TY_CAMERA_CALIB_INFO& depth_calib, const TY_CAMERA_CALIB_INFO& color_calib, const cv::Mat& depth, const cv::Mat& color, cv::Mat& out)
{
	// do rgb undistortion
	TY_IMAGE_DATA src;
	src.width = color.cols;
	src.height = color.rows;
	src.size = color.size().area() * 3;
	src.pixelFormat = TY_PIXEL_FORMAT_RGB;
	src.buffer = color.data;

	cv::Mat  undistort_color = cv::Mat(color.size(), CV_8UC3);
	TY_IMAGE_DATA dst;
	dst.width = color.cols;
	dst.height = color.rows;
	dst.size = undistort_color.size().area() * 3;
	dst.buffer = undistort_color.data;
	dst.pixelFormat = TY_PIXEL_FORMAT_RGB;
	ASSERT_OK(TYUndistortImage(&color_calib, &src, NULL, &dst));

	// do register
	out.create(depth.size(), CV_8UC3);
	ASSERT_OK(
		TYMapRGBImageToDepthCoordinate(
		&depth_calib,
		depth.cols, depth.rows, depth.ptr<uint16_t>(),
		&color_calib,
		undistort_color.cols, undistort_color.rows, undistort_color.ptr<uint8_t>(),
		out.ptr<uint8_t>()));
}

void eventCallback(TY_EVENT_INFO *event_info, void *userdata)
{
	if (event_info->eventId == TY_EVENT_DEVICE_OFFLINE) {
		LOGD("=== Event Callback: Device Offline!");
		// Note: 
		//     Please set TY_BOOL_KEEP_ALIVE_ONOFF feature to false if you need to debug with breakpoint!
	}
	else if (event_info->eventId == TY_EVENT_LICENSE_ERROR) {
		LOGD("=== Event Callback: License Error!");
		}
}

int main(int argc, char* argv[])
{
	std::string ID, IP;
	TY_INTERFACE_HANDLE hIface = NULL;
	TY_ISP_HANDLE hColorIspHandle = NULL;
	TY_DEV_HANDLE hDevice = NULL;
	int32_t color, ir, depth;
	color = ir = depth = 1;
	
	for(int i = 1; i < argc; i++) {
		if(strcmp(argv[i], "-id") == 0){
			ID = argv[++i];
		} else if(strcmp(argv[i], "-ip") == 0) {
			IP = argv[++i];
		} else if(strcmp(argv[i], "-color=off") == 0) {
			color = 0;
		} else if(strcmp(argv[i], "-depth=off") == 0) {
			depth = 0;
		} else if(strcmp(argv[i], "-ir=off") == 0) {
			ir = 0;
		} else if(strcmp(argv[i], "-h") == 0) {
			LOGI("Usage: SimpleView_FetchFrame [-h] [-id <ID>] [-ip <IP>]");
			return 0;
		}
	}
	LOGD("Init lib");
	ASSERT_OK( TYInitLib() );
	TY_VERSION_INFO ver;
	ASSERT_OK( TYLibVersion(&ver) );
	LOGD("     - lib version: %d.%d.%d", ver.major, ver.minor, ver.patch);
	
	std::vector<TY_DEVICE_BASE_INFO> selected;
	ASSERT_OK( selectDevice(TY_INTERFACE_ALL, ID, IP, 1, selected) );
	ASSERT(selected.size() > 0);
	TY_DEVICE_BASE_INFO& selectedDev = selected[0];

	ASSERT_OK( TYOpenInterface(selectedDev.iface.id, &hIface) );
	ASSERT_OK( TYOpenDevice(hIface, selectedDev.id, &hDevice) );

	int32_t allComps;
	ASSERT_OK( TYGetComponentIDs(hDevice, &allComps) );

	///try to enable color camera
	if(allComps & TY_COMPONENT_RGB_CAM  && color) {
		LOGD("Has RGB camera, open RGB cam");
		ASSERT_OK( TYEnableComponents(hDevice, TY_COMPONENT_RGB_CAM) );
		//create a isp handle to convert raw image(color bayer format) to rgb image
		ASSERT_OK(TYISPCreate(&hColorIspHandle));
		//Init code can be modified in common.hpp
		//NOTE: Should set RGB image format & size before init ISP
		ASSERT_OK(ColorIspInitSetting(hColorIspHandle, hDevice));
		//You can  call follow function to show  color isp supported features
#if 0
		ColorIspShowSupportedFeatures(hColorIspHandle);
#endif
		//You can turn on auto exposure function as follow ,but frame rate may reduce .
		//Device may be casually stucked  1~2 seconds while software is trying to adjust device exposure time value
#if 0
		ASSERT_OK(ColorIspInitAutoExposure(hColorIspHandle, hDevice));
#endif
	}

	if (allComps & TY_COMPONENT_IR_CAM_LEFT && ir) {
		LOGD("Has IR left camera, open IR left cam");
		ASSERT_OK(TYEnableComponents(hDevice, TY_COMPONENT_IR_CAM_LEFT));
	}

	if (allComps & TY_COMPONENT_IR_CAM_RIGHT && ir) {
		LOGD("Has IR right camera, open IR right cam");
		ASSERT_OK(TYEnableComponents(hDevice, TY_COMPONENT_IR_CAM_RIGHT));
	}

	//try to enable depth map
	LOGD("Configure components, open depth cam");
	if (allComps & TY_COMPONENT_DEPTH_CAM && depth) {
		int32_t image_mode;
		ASSERT_OK(get_default_image_mode(hDevice, TY_COMPONENT_DEPTH_CAM, image_mode));
		LOGD("Select Depth Image Mode: %dx%d", TYImageWidth(image_mode), TYImageHeight(image_mode));
		ASSERT_OK(TYSetEnum(hDevice, TY_COMPONENT_DEPTH_CAM, TY_ENUM_IMAGE_MODE, image_mode));
		ASSERT_OK(TYEnableComponents(hDevice, TY_COMPONENT_DEPTH_CAM));

		//depth map pixel format is uint16_t ,which default unit is  1 mm
		//the acutal depth (mm)= PixelValue * ScaleUnit 
	}

	LOGD("Prepare image buffer");
	uint32_t frameSize;
	ASSERT_OK( TYGetFrameBufferSize(hDevice, &frameSize) );
	LOGD("     - Get size of framebuffer, %d", frameSize);

	LOGD("     - Allocate & enqueue buffers");
	char* frameBuffer[2];
	frameBuffer[0] = new char[frameSize];
	frameBuffer[1] = new char[frameSize];
	LOGD("     - Enqueue buffer (%p, %d)", frameBuffer[0], frameSize);
	ASSERT_OK( TYEnqueueBuffer(hDevice, frameBuffer[0], frameSize) );
	LOGD("     - Enqueue buffer (%p, %d)", frameBuffer[1], frameSize);
	ASSERT_OK( TYEnqueueBuffer(hDevice, frameBuffer[1], frameSize) );

	LOGD("Register event callback");
	ASSERT_OK(TYRegisterEventCallback(hDevice, eventCallback, NULL));

	bool hasTrigger;
	ASSERT_OK(TYHasFeature(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &hasTrigger));
	if (hasTrigger) {
		LOGD("Disable trigger mode");
		TY_TRIGGER_PARAM trigger;
		trigger.mode = TY_TRIGGER_MODE_OFF;
		ASSERT_OK(TYSetStruct(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &trigger, sizeof(trigger)));
	}

	LOGD("Start capture");
	ASSERT_OK( TYStartCapture(hDevice) );

	LOGD("While loop to fetch frame");
	
	TY_FRAME_DATA frame;
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer1(new pcl::visualization::PCLVisualizer("3D Viewer"));
	while(!viewer1->wasStopped()){
		int err = TYFetchFrame(hDevice, &frame, -1);
		cv::Mat depth, irl, irr, color;
		parseFrame(frame, &depth, &irl, &irr, &color, hColorIspHandle);
		std::vector<TY_VECT_3F> p3d;
		TY_CAMERA_CALIB_INFO depth_calib; 
		TY_CAMERA_CALIB_INFO color_calib;
		
		pcl::PointCloud<pcl::PointXYZRGB> cloud;
		pcl::PointXYZRGB point; 
		
		p3d.resize(depth.size().area());
		TYGetStruct(hDevice, TY_COMPONENT_DEPTH_CAM, TY_STRUCT_CAM_CALIB_DATA, &depth_calib, sizeof(depth_calib));  //  提取深度相機的標定資料
	    TYGetStruct(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_CALIB_DATA, &color_calib, sizeof(color_calib)); // 提取RGB相機的標定資料
		TYMapDepthImageToPoint3d(&depth_calib, depth.cols, depth.rows, (uint16_t*)depth.data, &p3d[0]); // 深度影像->xyz點云
		
		cv::Mat color_data_mat;
		if (!color.empty())
		{
			bool hasColorCalib;
			TYHasFeature(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_CALIB_DATA, &hasColorCalib);
			if (hasColorCalib)
			{
				doRgbRegister(depth_calib, color_calib, depth, color, color_data_mat);
				cv::cvtColor(color_data_mat, color_data_mat, cv::COLOR_BGR2RGB);
			}
		}
		
		for (int m = 0; m < depth.rows; m++)
		{
			for (int n=0; n < depth.cols; n++)
			{
				point.x = p3d[(m*(depth.cols)+n)].x;
				point.y = p3d[(m*(depth.cols)+n)].y;
				point.z = p3d[(m*(depth.cols)+n)].z;
				
				point.r = color_data_mat.at<cv::Vec3b>(m, n)[0];
				point.g = color_data_mat.at<cv::Vec3b>(m, n)[1];
				point.b =color_data_mat.at<cv::Vec3b>(m, n)[2];
				
				cloud.points.push_back(point); // 構造xyzrgb型別點云
			}
		}
		
		cloud.width = (uint32_t)cloud.points.size();
		cloud.height = 1;
		
		pcl::PointCloud<pcl::PointXYZRGB>::Ptr basic_cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
		basic_cloud_ptr = cloud.makeShared(); // 轉換為指標格式 basic_cloud_ptr
		basic_cloud_ptr->is_dense = false;  //  自己創建的點云,默認為dense,需要修改屬性,否則removenanfrompointcloud函式無效
		pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
		std::vector<int> mapping;
		pcl::removeNaNFromPointCloud(*basic_cloud_ptr, *cloud_ptr, mapping); // 移除無效點
		
		viewer1->removeAllPointClouds();  // 移除當前所有點云
		viewer1->addPointCloud<pcl::PointXYZRGB> (cloud_ptr, "initial"); 
		viewer1->updatePointCloud(cloud_ptr, "initial"); 
		viewer1->spinOnce(100);
		
		TYISPUpdateDevice(hColorIspHandle);
		LOGD("Re-enqueue buffer(%p, %d)", frame.userBuffer, frame.bufferSize);
		ASSERT_OK( TYEnqueueBuffer(hDevice, frame.userBuffer, frame.bufferSize));
	}

	ASSERT_OK( TYStopCapture(hDevice) );
	ASSERT_OK( TYCloseDevice(hDevice) );
	ASSERT_OK( TYCloseInterface(hIface) );
	ASSERT_OK(TYISPRelease(&hColorIspHandle));
	ASSERT_OK( TYDeinitLib() );
	LOGD("Main done!");
	
	return 0;
}

3. 新建工程

如果不想使用官方 SDK 的檔案結構,自己新建一個專案,可以新建工程檔案夾 TYCamera,檔案結構如圖:
在這里插入圖片描述
除了 CMakeLists.txt 和 main.cpp,其他的檔案都可以直接從官方 SDK 中拷貝,main.cpp 即為上一節中的點云圖實時顯示完整代碼

CMakeLists.txt 修改為:
(可以正常運行,但我對 cmake 不是很熟悉,寫法上可能有不規范之處)

cmake_minimum_required(VERSION 2.8)
project(rgbd_camera)

if (NOT TARGET tycam) 
    #only build samples 
    option (OpenCV_STATIC OFF)
    set(INCLUDE_PATH include)
    include_directories(${INCLUDE_PATH})
    set(ABSOLUTE_TARGET_LIB tycam)
    add_library(${ABSOLUTE_TARGET_LIB} SHARED IMPORTED)
    if(ARCH)
        set_property(TARGET ${ABSOLUTE_TARGET_LIB} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../lib/linux/lib_${ARCH}/libtycam.so)
    else()
        set(ABSOLUTE_TARGET_LIB -ltycam)
    endif()
endif()

# ========================================
# === common, build static lib to speed up
# ========================================
set(COMMON_SOURCES src/MatViewer.cpp src/TYThread.cpp)

add_library(sample_common STATIC ${COMMON_SOURCES})

if(UNIX)
  target_link_libraries(sample_common pthread)
endif()

# ========================================
# === OpenCV
# ========================================
set(OpenCV_DIR "/home/olefine_casia/opencv-4.5.1/build/")
find_package(OpenCV REQUIRED)
if (NOT OpenCV_FOUND)
    message(FATAL_ERROR "OpenCV library not found")
else()
    include_directories(${OpenCV_INCLUDE_DIRS})
    include_directories(${OpenCV2_INCLUDE_DIRS})
    # if(CMAKE_BUILD_TYPE STREQUAL Debug)
    # link_directories(${OpenCV_LIB_DIR_DBG})
    # else()
    # link_directories(${OpenCV_LIB_DIR_OPT})
    # endif()
   link_directories(${OpenCV_LIB_DIR})

endif()

# ========================================
# === PCL
# ========================================
find_package(PCL 1.8 REQUIRED)
    include_directories(${PCL_INCLUDE_DIRS})
    link_directories(${PCL_LIBRARY_DIRS})
    add_definitions(${PCL_DEFINITIONS})


aux_source_directory(./src/ DIR_SRCS)

add_executable(rgbd_camera  ${DIR_SRCS})
    
include_directories ( 
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    )
    
target_link_libraries(rgbd_camera
${ABSOLUTE_TARGET_LIB} ${OpenCV_LIBS} ${PCL_LIBRARIES}
)   

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295039.html

標籤:其他

上一篇:EWT/經驗小波變換/EWT安裝包下載

下一篇:3分鐘帶你入門人工智能?互聯網巨頭都在用的高能演算法,干了它!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more