生活随笔
收集整理的這篇文章主要介紹了
知微传感Dkam系列3D相机OpenCV应用篇:OpenCV读入3D相机数据
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
OpenCV讀入3D相機數據
寫在前面
- 本人從事機器視覺細分的3D相機行業。編寫此系列文章主要目的有:
- 1、便利他人應用3D相機,本系列文章包含公司所出售相機的SDK的使用例程及詳細注釋;
- 2、促進行業發展及交流。
- 知微傳感Dkam系列3D相機可以應用于定位分揀、焊接引導、逆向建模、檢測測量等領域
- 歡迎與我深入交流:微信號:liu_zhisensor
OpenCV讀取數據說明
基本說明
- 知微傳感的3D相機可以輸出紅外圖(灰度圖)和RGB圖以便利2D+3D的應用場景
- 紅外圖和RGB圖在相機端是以char類型存儲并在上位機中以char類型接收的
- 深度圖是從點云中提取的Z值,按照紅外圖的順序存放的,在提取數據的過程中將char類型轉為了short類型
相關API
- GetCloudPlaneZ 獲取Z軸數據
- int GetCloudPlaneZ(Camera_Object_C* camera_obj, PhotoInfo *raw_data, short *imagedata)
- 函數功能:獲取點云 Z 平面數據
- 頭文件:dkam_zhicamera_api.h
- 參數:camera_obj:相機的結構體指針; raw_data:點云數據; imagedata:獲取的 Z 平面數據
- 返回值:0:獲取成功; 非 0:獲取失敗
例程及注釋
- 本例程基于WIN10+VisualStudio2019+DkamSDK_1.6.71+OpenCV4.5.4,采用C++語言
- DkamSDK的配置方法請參考SDK說明書
- OpenCV的配置方法另請查閱
- 除自己安裝配置OpenCV外,還可以利用知微傳感提供的DkamSDK自帶的OpenCV,在include和lib文件夾內
- 本例程在D132S型相機上驗證
#include <iostream>
//DkamSDK
#include"dkam_discovery.h"
#include"dkam_gige_camera.h"
#include"dkam_gige_stream.h"
#include"dkam_zhicamera_api.h"
//OpenCV
#include <opencv2/opencv.hpp>int main()
{std::cout << "Hello ZhiSENSOR!" <<std::endl;std::cout << "Hello liu_sensor!" << std::endl;std::vector<DiscoveryInfo> discovery_info;Discovery discovery;GigeCamera camera;GigeStream* pointgigestream = NULL;GigeStream* graygigestream = NULL;GigeStream* rgbgigestream = NULL;//**********************************************查詢相機****************************************************//查詢局域網內的3D相機std::vector<DiscoveryInfo>().swap(discovery_info);int camer_num = discovery.DiscoverCamera(&discovery_info);std::cout << "局域網內共有" << camer_num << "臺相機" << std::endl;//顯示局域網內相機的IPfor (int i = 0; i < camer_num; i++){std::cout << "局域網內相機的IP為:" << discovery.ConvertIpIntToString(discovery_info[i].camera_ip) << std::endl;}//**********************************************連接相機****************************************************//選定相機int k = -1;for (int i = 0; i < camer_num; i++){if (strcmp((discovery.ConvertIpIntToString(discovery_info[i].camera_ip)), "192.168.30.35") == 0){k = i;std::cout << "將連接第" << k + 1 << "臺相機" << std::endl;}else{std::cout << "局域網內無該IP的相機" << std::endl;}}//連接相機int connect = camera.CameraConnect(&discovery_info[k]);if (connect == 0){std::cout << "成功連接相機" << std::endl;}else{std::cout << "連接相機失敗,請檢查!!!" << std::endl;}//**********************************************配置相機****************************************************if (connect == 0){//獲取當前紅外相機的寬和高int width = -1;int height = -1;std::cout << "獲取相機紅外圖的寬和高。。。" << std::endl;int height_gray = camera.GetCameraHeight(&height, 0);int width_gray = camera.GetCameraWidth(&width, 0);std::cout << "相機紅外圖的寬為:" << width << std::endl; std::cout << "相機紅外圖的高為:" << height << std::endl;//獲取當前RGB相機的寬和高,如相機不支持則無此項int width_RGB = -1;int height_RGB = -1;std::cout << "獲取相機RGB圖的寬和高。。。" << std::endl;int height_rgb = camera.GetCameraHeight(&height_RGB, 1);int width_rgb = camera.GetCameraWidth(&width_RGB, 1);std::cout << "相機RGB圖的寬為" << width_RGB << std::endl;std::cout << "相機RGB圖的高為" << height_RGB << std::endl;//定義紅外數據大小PhotoInfo* gray_data = new PhotoInfo;gray_data->pixel = new char[width * height];memset(gray_data->pixel, 0, width * height);//定義點云數據大小PhotoInfo* point_data = new PhotoInfo;point_data->pixel = new char[width * height * 6];memset(point_data->pixel, 0, width * height * 6);//定義RGB數據大小PhotoInfo* RGB_data = new PhotoInfo;RGB_data->pixel = new char[width_RGB * height_RGB * 3];memset(RGB_data->pixel, 0, width_RGB * height_RGB * 3);//**********************************************打開數據通道****************************************************//開啟數據流通道(0:紅外 1:點云 2:RGB)//紅外圖int stream_gray = camera.StreamOn(0, &graygigestream);if (stream_gray == 0){std::cout << "紅外圖通道打開成功!" << std::endl;}else{std::cout << "紅外圖通道打開失敗!!!" << std::endl;}//點云int stream_point = camera.StreamOn(1, &pointgigestream);if (stream_point == 0){std::cout << "點云通道打開成功!" << std::endl;}else{std::cout << "點云通道打開失敗!!!" << std::endl;}//RGB圖通道int stream_RGB = camera.StreamOn(2, &rgbgigestream);if (stream_RGB == 0){std::cout << "RGB圖通道打開成功!" << std::endl;}else{std::cout << "RGB圖通道打開失敗!!!" << std::endl;}//開始接受數據int acquistion = camera.AcquisitionStart();if (acquistion == 0){std::cout << "可以開始接受數據!" << std::endl;}//刷新緩沖區數據pointgigestream->FlushBuffer();graygigestream->FlushBuffer();rgbgigestream->FlushBuffer();//**********************************************等待相機上傳數據***************************************//采集紅外int captureGray = -1;captureGray = graygigestream->TimeoutCapture(gray_data, 3000000);if (captureGray == 0){std::cout << "紅外接收成功!" << std::endl;}else{std::cout << "紅外接收失敗!!!" << std::endl;std::cout << "失敗代號:" << captureGray << std::endl;}//采集點云int capturePoint = -1;capturePoint = pointgigestream->TimeoutCapture(point_data, 3000000);if (capturePoint == 0){std::cout << "點云接收成功!" << std::endl;}else{std::cout << "點云接收失敗!!!" << std::endl;std::cout << "失敗代號:" << capturePoint << std::endl;}//采集RGBint captureRGB = -1;captureRGB = rgbgigestream->TimeoutCapture(RGB_data, 3000000);if (captureRGB == 0){std::cout << "RGB接收成功!" << std::endl;}else{std::cout << "RGB接收失敗!!!" << std::endl;std::cout << "失敗代號:" << captureRGB << std::endl;}//保存數據到本地//保存紅外數據int savegray = camera.SaveToBMP(*gray_data, (char*)"Gray.bmp");if (savegray == 0){std::cout << "紅外圖保存成功!" << std::endl;}else{std::cout << "紅外圖保存失敗!!!" << std::endl;}//保存RGB數據int savergb = camera.SaveToBMP(*RGB_data, (char*)"RGB.bmp");if (savergb == 0){std::cout << "RGB圖保存成功!" << std::endl;}else{std::cout << "RGB圖保存失敗!!!" << std::endl;}//保存深度圖int savedepth = camera.SaveDepthToPng(*point_data, (char*)"Depth.png");if (savedepth == 0){std::cout << "深度圖保存成功!" << std::endl;}else{std::cout << "深度圖保存失敗!!!" << std::endl;}//**********************************************將數據OpenCV可處理格式***************************************//灰度圖std::cout << "將紅外圖轉換到OpenCV格式,并顯示..." << std::endl;cv::Mat GrayImage = cv::Mat(height, width, CV_8UC1, (void*)gray_data->pixel);//顯示灰度圖cv::imshow("Gray Picture", GrayImage);//RGB圖std::cout << "將RGB圖轉換到OpenCV格式,并顯示..." << std::endl;cv::Mat RGBimage = cv::Mat(height_RGB, width_RGB, CV_8UC3, (void*)RGB_data->pixel); cv::imshow("RGB Picture", RGBimage);//深度圖std::cout << "提取深度數據,轉換到OpenCV格式,并顯示..." << std::endl;short* depthdata = (short*)malloc(width * height * 2 * sizeof(short));memset((void*)depthdata,0, width * height * 2 * sizeof(short));int getZ = camera.GetCloudPlaneZ(*point_data, depthdata);if (getZ == 0){std::cout << "提取點云Z值成功!" << std::endl;}else{std::cout << "提取點云Z值失敗!!!" << std::endl;}cv::Mat DepthImage = cv::Mat(height, width, CV_16U, (void*)depthdata);cv::imshow("Depth Picture", DepthImage);std::cout << "注意:深度圖像素值乘以0.05才是真實物理世界的距離。單位:mm" << std::endl;//**********************************************結束工作***************************************memset(point_data->pixel, 0, width* height * 6);memset(gray_data->pixel, 0, width* height);memset(RGB_data->pixel, 0, width_RGB* height_RGB * 3);//釋放內存delete[] point_data->pixel;delete point_data;delete[] gray_data->pixel;delete gray_data;delete[] RGB_data->pixel;delete RGB_data;delete depthdata;//關閉數據流通道 int streamoff_gray = camera.StreamOff(0, graygigestream);int streamoff_point = camera.StreamOff(1, pointgigestream);int streamoff_rgb = camera.StreamOff(2, rgbgigestream);//斷開相機連接int disconnect = camera.CameraDisconnect();std::cout << "工作結束!!!!!!" << std::endl;}else{std::cout << "相機連接失敗!!!" << std::endl;std::cout << "請排查原因,代號:" << connect << std::endl;}cv::waitKey(0);
}
運行結果
結果對比
后記
- 知微傳感Dkam系列3D相機可以應用于定位分揀、焊接引導、逆向建模、檢測測量等領域
- 如有問題,歡迎與我深入交流:微信號:liu_zhisensor
總結
以上是生活随笔為你收集整理的知微传感Dkam系列3D相机OpenCV应用篇:OpenCV读入3D相机数据的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。