123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- #include "../common/common.hpp"
- #include "TYImageProc.h"
- #define MAP_DEPTH_TO_COLOR 0
- struct CallbackData {
- int index;
- TY_ISP_HANDLE IspHandle;
- TY_DEV_HANDLE hDevice;
- DepthRender* render;
- DepthViewer* depthViewer;
- bool needUndistort;
- float scale_unit;
- bool isTof;
- TY_CAMERA_CALIB_INFO depth_calib;
- TY_CAMERA_CALIB_INFO color_calib;
- };
- cv::Mat tofundis_mapx, tofundis_mapy;
- static void doRegister(const TY_CAMERA_CALIB_INFO& depth_calib
- , const TY_CAMERA_CALIB_INFO& color_calib
- , const cv::Mat& depth
- , const float f_scale_unit
- , const cv::Mat& color
- , bool needUndistort
- , cv::Mat& undistort_color
- , cv::Mat& out
- , bool map_depth_to_color
- )
- {
- int32_t image_size;
- TY_PIXEL_FORMAT color_fmt;
- if(color.type() == CV_16U) {
- image_size = color.size().area() * 2;
- color_fmt = TY_PIXEL_FORMAT_MONO16;
- }
- else if(color.type() == CV_16UC3)
- {
- image_size = color.size().area() * 6;
- color_fmt = TY_PIXEL_FORMAT_RGB48;
- }
- else {
- image_size = color.size().area() * 3;
- color_fmt = TY_PIXEL_FORMAT_RGB;
- }
- // do undistortion
- if (needUndistort) {
- if(color_fmt == TY_PIXEL_FORMAT_MONO16)
- undistort_color = cv::Mat(color.size(), CV_16U);
- else if(color_fmt == TY_PIXEL_FORMAT_RGB48)
- undistort_color = cv::Mat(color.size(), CV_16UC3);
- else
- undistort_color = cv::Mat(color.size(), CV_8UC3);
-
- TY_IMAGE_DATA src;
- src.width = color.cols;
- src.height = color.rows;
- src.size = image_size;
- src.pixelFormat = color_fmt;
- src.buffer = color.data;
- TY_IMAGE_DATA dst;
- dst.width = color.cols;
- dst.height = color.rows;
- dst.size = image_size;
- dst.pixelFormat = color_fmt;
- dst.buffer = undistort_color.data;
- ASSERT_OK(TYUndistortImage(&color_calib, &src, NULL, &dst));
- }
- else {
- undistort_color = color;
- }
- // do register
- if (map_depth_to_color) {
- out = cv::Mat::zeros(undistort_color.size(), CV_16U);
- ASSERT_OK(
- TYMapDepthImageToColorCoordinate(
- &depth_calib,
- depth.cols, depth.rows, depth.ptr<uint16_t>(),
- &color_calib,
- out.cols, out.rows, out.ptr<uint16_t>(), f_scale_unit
- )
- );
- cv::Mat temp;
- //you may want to use median filter to fill holes in projected depth image
- //or do something else here
- cv::medianBlur(out, temp, 5);
- out = temp;
- }
- else {
- if(color_fmt == TY_PIXEL_FORMAT_MONO16)
- {
- out = cv::Mat::zeros(depth.size(), CV_16U);
- ASSERT_OK(
- TYMapMono16ImageToDepthCoordinate(
- &depth_calib,
- depth.cols, depth.rows, depth.ptr<uint16_t>(),
- &color_calib,
- undistort_color.cols, undistort_color.rows, undistort_color.ptr<uint16_t>(),
- out.ptr<uint16_t>(), f_scale_unit
- )
- );
- }
- else if(color_fmt == TY_PIXEL_FORMAT_RGB48)
- {
- out = cv::Mat::zeros(depth.size(), CV_16UC3);
- ASSERT_OK(
- TYMapRGB48ImageToDepthCoordinate(
- &depth_calib,
- depth.cols, depth.rows, depth.ptr<uint16_t>(),
- &color_calib,
- undistort_color.cols, undistort_color.rows, undistort_color.ptr<uint16_t>(),
- out.ptr<uint16_t>(), f_scale_unit
- )
- );
- }
- else{
- out = cv::Mat::zeros(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>(), f_scale_unit
- )
- );
- }
- }
- }
- void handleFrame(TY_FRAME_DATA* frame, void* userdata)
- {
- CallbackData* pData = (CallbackData*)userdata;
- LOGD("=== Get frame %d", ++pData->index);
- cv::Mat depth, color;
- parseFrame(*frame, &depth, 0, 0, &color, pData->IspHandle);
- if (!depth.empty()) {
- if (pData->isTof)
- {
- TY_IMAGE_DATA src;
- src.width = depth.cols;
- src.height = depth.rows;
- src.size = depth.size().area() * 2;
- src.pixelFormat = TY_PIXEL_FORMAT_DEPTH16;
- src.buffer = depth.data;
- cv::Mat undistort_depth = cv::Mat(depth.size(), CV_16U);
- TY_IMAGE_DATA dst;
- dst.width = depth.cols;
- dst.height = depth.rows;
- dst.size = undistort_depth.size().area() * 2;
- dst.buffer = undistort_depth.data;
- dst.pixelFormat = TY_PIXEL_FORMAT_DEPTH16;
- ASSERT_OK(TYUndistortImage(&pData->depth_calib, &src, NULL, &dst));
- depth = undistort_depth.clone();
- }
- pData->depthViewer->show(depth);
- }
- if (!color.empty()) {
- cv::imshow("color", color);
- }
- if (!depth.empty() && !color.empty()) {
- cv::Mat undistort_color, out;
- if (pData->needUndistort || MAP_DEPTH_TO_COLOR) {
- doRegister(pData->depth_calib, pData->color_calib, depth, pData->scale_unit, color, pData->needUndistort, undistort_color, out, MAP_DEPTH_TO_COLOR);
- }
- else {
- undistort_color = color;
- out = color;
- }
- cv::imshow("undistort color", undistort_color);
- cv::Mat tmp, gray8, bgr;
- if (MAP_DEPTH_TO_COLOR) {
- cv::Mat depthDisplay = pData->render->Compute(out);
- if(undistort_color.type() == CV_16U) {
- gray8 = cv::Mat(undistort_color.size(), CV_8U);
- cv::normalize(undistort_color, tmp, 0, 255, cv::NORM_MINMAX);
- cv::convertScaleAbs(tmp, gray8);
- cv::cvtColor(gray8, undistort_color, cv::COLOR_GRAY2BGR);
- } else if(undistort_color.type() == CV_16UC3) {
- bgr = cv::Mat(undistort_color.size(), CV_8UC3);
- cv::normalize(undistort_color, tmp, 0, 255, cv::NORM_MINMAX);
- cv::convertScaleAbs(tmp, bgr);
- undistort_color = bgr.clone();
- }
- depthDisplay = depthDisplay / 2 + undistort_color / 2;
- cv::imshow("depth2color RGBD", depthDisplay);
- }
- else {
- cv::imshow("mapped RGB", out);
- if(out.type() == CV_16U) {
- gray8 = cv::Mat(out.size(), CV_8U);
- cv::normalize(out, tmp, 0, 255, cv::NORM_MINMAX);
- cv::convertScaleAbs(tmp, gray8);
- cv::cvtColor(gray8, out, cv::COLOR_GRAY2BGR);
- } else if(undistort_color.type() == CV_16UC3) {
- bgr = cv::Mat(out.size(), CV_8UC3);
- cv::normalize(out, tmp, 0, 255, cv::NORM_MINMAX);
- cv::convertScaleAbs(tmp, bgr);
- out = bgr.clone();
- }
- cv::Mat depthDisplay = pData->render->Compute(depth);
- depthDisplay = depthDisplay / 2 + out / 2;
- cv::imshow("color2depth RGBD", depthDisplay);
- }
- }
- LOGD("=== Re-enqueue buffer(%p, %d)", frame->userBuffer, frame->bufferSize);
- ASSERT_OK(TYEnqueueBuffer(pData->hDevice, frame->userBuffer, frame->bufferSize));
- }
- 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_DEV_HANDLE hDevice = NULL;
- 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], "-h") == 0){
- LOGI("Usage: SimpleView_Registration [-h] [-id <ID>]");
- 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) );
- TY_COMPONENT_ID allComps;
- ASSERT_OK( TYGetComponentIDs(hDevice, &allComps) );
- if(!(allComps & TY_COMPONENT_RGB_CAM)){
- LOGE("=== Has no RGB camera, cant do registration");
- return -1;
- }
- TY_ISP_HANDLE isp_handle;
- ASSERT_OK(TYISPCreate(&isp_handle));
- ASSERT_OK(ColorIspInitSetting(isp_handle, hDevice));
- //You can turn on auto exposure function as follow ,but frame rate may reduce .
- //Device also may be casually stucked 1~2 seconds when software trying to adjust device exposure time value
- #if 0
- ASSERT_OK(ColorIspInitAutoExposure(isp_handle, hDevice));
- #endif
- LOGD("=== Configure components");
- TY_COMPONENT_ID componentIDs = TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_RGB_CAM;
- ASSERT_OK( TYEnableComponents(hDevice, componentIDs) );
- // ASSERT_OK( TYSetEnum(hDevice, TY_COMPONENT_RGB_CAM, TY_ENUM_IMAGE_MODE, TY_IMAGE_MODE_YUYV_640x480) );
- bool hasUndistortSwitch, hasDistortionCoef;
- ASSERT_OK( TYHasFeature(hDevice, TY_COMPONENT_RGB_CAM, TY_BOOL_UNDISTORTION, &hasUndistortSwitch) );
- ASSERT_OK( TYHasFeature(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_DISTORTION, &hasDistortionCoef) );
- if (hasUndistortSwitch) {
- ASSERT_OK( TYSetBool(hDevice, TY_COMPONENT_RGB_CAM, TY_BOOL_UNDISTORTION, true) );
- }
- 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 hasTriggerParam = false;
- ASSERT_OK( TYHasFeature(hDevice, TY_COMPONENT_DEVICE, TY_STRUCT_TRIGGER_PARAM, &hasTriggerParam) );
- if (hasTriggerParam) {
- 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)));
- }
- DepthViewer depthViewer("Depth");
- DepthRender render;
- CallbackData cb_data;
- cb_data.index = 0;
- cb_data.hDevice = hDevice;
- cb_data.depthViewer = &depthViewer;
- cb_data.render = &render;
- cb_data.needUndistort = !hasUndistortSwitch && hasDistortionCoef;
- cb_data.IspHandle = isp_handle;
- float scale_unit = 1.;
- TYGetFloat(hDevice, TY_COMPONENT_DEPTH_CAM, TY_FLOAT_SCALE_UNIT, &scale_unit);
- cb_data.scale_unit = scale_unit;
- depthViewer.depth_scale_unit = scale_unit;
- LOGD("=== Read depth calib info");
- ASSERT_OK( TYGetStruct(hDevice, TY_COMPONENT_DEPTH_CAM, TY_STRUCT_CAM_CALIB_DATA
- , &cb_data.depth_calib, sizeof(cb_data.depth_calib)) );
- LOGD("=== Read color calib info");
- ASSERT_OK( TYGetStruct(hDevice, TY_COMPONENT_RGB_CAM, TY_STRUCT_CAM_CALIB_DATA
- , &cb_data.color_calib, sizeof(cb_data.color_calib)) );
- ASSERT_OK(TYHasFeature(hDevice, TY_COMPONENT_DEPTH_CAM, TY_STRUCT_CAM_DISTORTION, &cb_data.isTof));
- LOGD("=== Start capture");
- ASSERT_OK( TYStartCapture(hDevice) );
- LOGD("=== Wait for callback");
- bool exit_main = false;
- while(!exit_main){
- TY_FRAME_DATA frame;
- int err = TYFetchFrame(hDevice, &frame, -1);
- if( err != TY_STATUS_OK ) {
- LOGE("Fetch frame error %d: %s", err, TYErrorString(err));
- break;
- }
- handleFrame(&frame, &cb_data);
- TYISPUpdateDevice(cb_data.IspHandle);
- int key = cv::waitKey(1);
- switch(key & 0xff){
- case 0xff:
- break;
- case 'q':
- exit_main = true;
- break;
- default:
- LOGD("Pressed key %d", key);
- }
- }
- ASSERT_OK( TYStopCapture(hDevice) );
- ASSERT_OK( TYCloseDevice(hDevice) );
- ASSERT_OK( TYCloseInterface(hIface) );
- ASSERT_OK( TYDeinitLib() );
- delete frameBuffer[0];
- delete frameBuffer[1];
- LOGD("=== Main done!");
- return 0;
- }
|