123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- #ifndef SAMPLE_COMMON_COMMON_HPP_
- #define SAMPLE_COMMON_COMMON_HPP_
- #include "Utils.hpp"
- #include <fstream>
- #include <iterator>
- #include <opencv2/opencv.hpp>
- #include "DepthRender.hpp"
- #include "MatViewer.hpp"
- #include "TYThread.hpp"
- #include "DepthInpainter.hpp"
- #include "TyIsp.h"
- #include "BayerISP.hpp"
- #include "CommandLineParser.hpp"
- #include "CommandLineFeatureHelper.hpp"
- static inline int decodeCsiRaw10(unsigned char* src, unsigned short* dst, int width, int height)
- {
- if(width & 0x3) {
- return -1;
- }
- int raw10_line_size = 5 * width / 4;
- for(size_t i = 0, j = 0; i < raw10_line_size * height; i+=5, j+=4)
- {
- //[A2 - A9] | [B2 - B9] | [C2 - C9] | [D2 - D9] | [A0A1-B0B1-C0C1-D0D1]
- dst[j + 0] = ((uint16_t)src[i + 0] << 2) | ((src[i + 4] & 0x3) >> 0);
- dst[j + 1] = ((uint16_t)src[i + 1] << 2) | ((src[i + 4] & 0xc) >> 2);
- dst[j + 2] = ((uint16_t)src[i + 2] << 2) | ((src[i + 4] & 0x30) >> 4);
- dst[j + 3] = ((uint16_t)src[i + 3] << 2) | ((src[i + 4] & 0xc0) >> 6);
- }
- return 0;
- }
- static inline int decodeCsiRaw12(unsigned char* src, unsigned short* dst, int width, int height)
- {
- if(width & 0x1) {
- return -1;
- }
- int raw12_line_size = 3 * width / 2;
- for(size_t i = 0, j = 0; i < raw12_line_size * height; i+=3, j+=2)
- {
- //[A4 - A11] | [B4 - B11] | [A0A1A2A3-B0B1B2B3]
- dst[j + 0] = ((uint16_t)src[i + 0] << 4) | ((src[i + 2] & 0x0f) >> 0);
- dst[j + 1] = ((uint16_t)src[i + 1] << 4) | ((src[i + 2] & 0xf0) >> 4);
- }
- return 0;
- }
- static inline int decodeCsiRaw14(unsigned char* src, unsigned short* dst, int width, int height)
- {
- if(width & 0x3) {
- return -1;
- }
- int raw14_line_size = 7 * width / 4;
- for(size_t i = 0, j = 0; i < raw14_line_size * height; i+=7, j+=4)
- {
- //[A6 - A13] | [B6 - B13] | [C6 - C13] | [D6 - D13] | [A0A1A2A3A4A5-B0B1] | [B2B3B4B5-C0C1C2C3] | [C4C5-D0D1D2D3D4D5]
- dst[j + 0] = ((uint16_t)src[i + 0] << 6) | ((src[i + 4] & 0x3f) >> 0);
- dst[j + 1] = ((uint16_t)src[i + 1] << 6) | ((src[i + 4] & 0xc0) >> 6) | ((src[i + 5] & 0x0f) << 2);
- dst[j + 2] = ((uint16_t)src[i + 2] << 6) | ((src[i + 5] & 0xf0) >> 4) | ((src[i + 6] & 0x03) << 4);
- dst[j + 3] = ((uint16_t)src[i + 3] << 6) | ((src[i + 6] & 0xfc) >> 2);
- }
- return 0;
- }
- static inline int parseCsiRaw10(unsigned char* src, cv::Mat &dst, int width, int height)
- {
- cv::Mat m(height, width, CV_16U);
- decodeCsiRaw10(src, (ushort*)m.data, width, height);
- //convert valid 10bit from lsb to msb, d = s * 64
- dst = m * 64;
- return 0;
- }
- static inline int parseCsiRaw12(unsigned char* src, cv::Mat &dst, int width, int height)
- {
- cv::Mat m(height, width, CV_16U);
- decodeCsiRaw12(src, (ushort*)m.data, width, height);
- //convert valid 12bit from lsb to msb, d = s * 16
- dst = m * 16;
- return 0;
- }
- static inline int parseIrFrame(const TY_IMAGE_DATA* img, cv::Mat* pIR)
- {
- if (img->pixelFormat == TY_PIXEL_FORMAT_MONO16 || img->pixelFormat==TY_PIXEL_FORMAT_TOF_IR_MONO16){
- *pIR = cv::Mat(img->height, img->width, CV_16U, img->buffer).clone();
- } else if(img->pixelFormat == TY_PIXEL_FORMAT_CSI_MONO10) {
- *pIR = cv::Mat(img->height, img->width, CV_16U);
- parseCsiRaw10((uchar*)img->buffer, (*pIR), img->width, img->height);
- } else if(img->pixelFormat == TY_PIXEL_FORMAT_MONO) {
- *pIR = cv::Mat(img->height, img->width, CV_8U, img->buffer).clone();
- } else if(img->pixelFormat == TY_PIXEL_FORMAT_CSI_MONO12) {
- *pIR = cv::Mat(img->height, img->width, CV_8U, img->buffer).clone();
- parseCsiRaw12((uchar*)img->buffer, (*pIR), img->width, img->height);
- }
- else {
- return -1;
- }
- return 0;
- }
- static inline int parseBayer8Frame(const TY_IMAGE_DATA* img, cv::Mat* pColor, TY_ISP_HANDLE color_isp_handle = NULL)
- {
- int code = cv::COLOR_BayerGB2BGR;
- switch (img->pixelFormat)
- {
- case TY_PIXEL_FORMAT_BAYER8GBRG:
- code = cv::COLOR_BayerGR2BGR;
- break;
- case TY_PIXEL_FORMAT_BAYER8BGGR:
- code = cv::COLOR_BayerRG2BGR;
- break;
- case TY_PIXEL_FORMAT_BAYER8GRBG:
- code = cv::COLOR_BayerGB2BGR;
- break;
- case TY_PIXEL_FORMAT_BAYER8RGGB:
- code = cv::COLOR_BayerBG2BGR;
- break;
- default:
- LOGE("Invalid bayer8 fmt!");
- return -1;
- }
- if (!color_isp_handle){
- cv::Mat raw(img->height, img->width, CV_8U, img->buffer);
- cv::cvtColor(raw, *pColor, code);
- }
- else{
- cv::Mat raw(img->height, img->width, CV_8U, img->buffer);
- pColor->create(img->height, img->width, CV_8UC3);
- int sz = img->height* img->width * 3;
- TY_IMAGE_DATA out_buff = TYInitImageData(sz, pColor->data, img->width, img->height);
- out_buff.pixelFormat = TY_PIXEL_FORMAT_BGR;
- int res = TYISPProcessImage(color_isp_handle, img, &out_buff);
- if (res != TY_STATUS_OK){
- //fall back to using opencv api
- cv::Mat raw(img->height, img->width, CV_8U, img->buffer);
- cv::cvtColor(raw, *pColor, code);
- }
- }
- return 0;
- }
- static inline int parseBayer10Frame(const TY_IMAGE_DATA* img, cv::Mat* pColor)
- {
- int code = cv::COLOR_BayerGB2BGR;
- switch (img->pixelFormat)
- {
- case TY_PIXEL_FORMAT_CSI_BAYER10GBRG:
- code = cv::COLOR_BayerGR2BGR;
- break;
- case TY_PIXEL_FORMAT_CSI_BAYER10BGGR:
- code = cv::COLOR_BayerRG2BGR;
- break;
- case TY_PIXEL_FORMAT_CSI_BAYER10GRBG:
- code = cv::COLOR_BayerGB2BGR;
- break;
- case TY_PIXEL_FORMAT_CSI_BAYER10RGGB:
- code = cv::COLOR_BayerBG2BGR;
- break;
- default:
- LOGE("Invalid bayer10 fmt!");
- return -1;
- }
- cv::Mat raw16(img->height, img->width, CV_16U);
- parseCsiRaw10((uchar*)img->buffer, raw16, img->width, img->height);
- cv::cvtColor(raw16, *pColor, code);
-
- return 0;
- }
- static inline int parseBayer12Frame(const TY_IMAGE_DATA* img, cv::Mat* pColor)
- {
- int code = cv::COLOR_BayerGB2BGR;
- switch (img->pixelFormat)
- {
- case TY_PIXEL_FORMAT_CSI_BAYER12GBRG:
- code = cv::COLOR_BayerGR2BGR;
- break;
- case TY_PIXEL_FORMAT_CSI_BAYER12BGGR:
- code = cv::COLOR_BayerRG2BGR;
- break;
- case TY_PIXEL_FORMAT_CSI_BAYER12GRBG:
- code = cv::COLOR_BayerGB2BGR;
- break;
- case TY_PIXEL_FORMAT_CSI_BAYER12RGGB:
- code = cv::COLOR_BayerBG2BGR;
- break;
- default:
- LOGE("Invalid bayer12 fmt!");
- return -1;
- }
- cv::Mat raw16(img->height, img->width, CV_16U);
- parseCsiRaw12((uchar*)img->buffer, raw16, img->width, img->height);
- cv::cvtColor(raw16, *pColor, code);
- return 0;
- }
- static inline int parseColorFrame(const TY_IMAGE_DATA* img, cv::Mat* pColor, TY_ISP_HANDLE color_isp_handle = NULL)
- {
- int ret = 0;
- if (img->pixelFormat == TY_PIXEL_FORMAT_JPEG){
- std::vector<uchar> _v((uchar*)img->buffer, (uchar*)img->buffer + img->size);
- *pColor = cv::imdecode(_v, cv::IMREAD_COLOR);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_YVYU){
- cv::Mat yuv(img->height, img->width, CV_8UC2, img->buffer);
- cv::cvtColor(yuv, *pColor, cv::COLOR_YUV2BGR_YVYU);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_YUYV){
- cv::Mat yuv(img->height, img->width, CV_8UC2, img->buffer);
- cv::cvtColor(yuv, *pColor, cv::COLOR_YUV2BGR_YUYV);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_RGB){
- cv::Mat rgb(img->height, img->width, CV_8UC3, img->buffer);
- cv::cvtColor(rgb, *pColor, cv::COLOR_RGB2BGR);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_BGR){
- *pColor = cv::Mat(img->height, img->width, CV_8UC3, img->buffer);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_BAYER8GBRG ||
- img->pixelFormat == TY_PIXEL_FORMAT_BAYER8BGGR ||
- img->pixelFormat == TY_PIXEL_FORMAT_BAYER8GRBG ||
- img->pixelFormat == TY_PIXEL_FORMAT_BAYER8RGGB)
- {
- ret = parseBayer8Frame(img, pColor, color_isp_handle);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER10GBRG ||
- img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER10BGGR ||
- img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER10GRBG ||
- img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER10RGGB)
- {
- ret = parseBayer10Frame(img, pColor);
- }
- else if(img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER12GBRG ||
- img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER12BGGR ||
- img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER12GRBG ||
- img->pixelFormat == TY_PIXEL_FORMAT_CSI_BAYER12RGGB)
- {
- ret = parseBayer12Frame(img, pColor);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_MONO){
- cv::Mat gray(img->height, img->width, CV_8U, img->buffer);
- cv::cvtColor(gray, *pColor, cv::COLOR_GRAY2BGR);
- }
- else if (img->pixelFormat == TY_PIXEL_FORMAT_CSI_MONO10){
- cv::Mat gray16(img->height, img->width, CV_16U);
- parseCsiRaw10((uchar*)img->buffer, gray16, img->width, img->height);
- *pColor = gray16.clone();
- }
- return ret;
- }
- static inline int parseFrame(const TY_FRAME_DATA& frame, cv::Mat* pDepth
- , cv::Mat* pLeftIR, cv::Mat* pRightIR
- , cv::Mat* pColor, TY_ISP_HANDLE color_isp_handle = NULL)
- {
- for (int i = 0; i < frame.validCount; i++){
- if (frame.image[i].status != TY_STATUS_OK) continue;
- // get depth image
- if (pDepth && frame.image[i].componentID == TY_COMPONENT_DEPTH_CAM){
- if (frame.image[i].pixelFormat == TY_PIXEL_FORMAT_XYZ48) {
- *pDepth = cv::Mat(frame.image[i].height, frame.image[i].width
- , CV_16SC3, frame.image[i].buffer).clone();
- }
- else {
- *pDepth = cv::Mat(frame.image[i].height, frame.image[i].width
- , CV_16U, frame.image[i].buffer).clone();
- }
- }
- // get left ir image
- if (pLeftIR && frame.image[i].componentID == TY_COMPONENT_IR_CAM_LEFT){
- parseIrFrame(&frame.image[i], pLeftIR);
- }
- // get right ir image
- if (pRightIR && frame.image[i].componentID == TY_COMPONENT_IR_CAM_RIGHT){
- parseIrFrame(&frame.image[i], pRightIR);
- }
- // get BGR
- if (pColor && frame.image[i].componentID == TY_COMPONENT_RGB_CAM){
- parseColorFrame(&frame.image[i], pColor, color_isp_handle);
- }
- }
- return 0;
- }
- enum{
- PC_FILE_FORMAT_XYZ = 0,
- };
- static void writePC_XYZ(const cv::Point3f* pnts, const cv::Vec3b *color, size_t n, FILE* fp)
- {
- if (color){
- for (size_t i = 0; i < n; i++){
- if (!std::isnan(pnts[i].x)){
- fprintf(fp, "%f %f %f %d %d %d\n", pnts[i].x, pnts[i].y, pnts[i].z, color[i][0], color[i][1], color[i][2]);
- }
- }
- }
- else{
- for (size_t i = 0; i < n; i++){
- if (!std::isnan(pnts[i].x)){
- fprintf(fp, "%f %f %f 0 0 0\n", pnts[i].x, pnts[i].y, pnts[i].z);
- }
- }
- }
- }
- static void writePointCloud(const cv::Point3f* pnts, const cv::Vec3b *color, size_t n, const char* file, int format)
- {
- FILE* fp = fopen(file, "w");
- if (!fp){
- return;
- }
- switch (format){
- case PC_FILE_FORMAT_XYZ:
- writePC_XYZ(pnts, color, n, fp);
- break;
- default:
- break;
- }
- fclose(fp);
- }
- class CallbackWrapper
- {
- public:
- typedef void(*TY_FRAME_CALLBACK) (TY_FRAME_DATA*, void* userdata);
- CallbackWrapper(){
- _hDevice = NULL;
- _cb = NULL;
- _userdata = NULL;
- _exit = true;
- }
- TY_STATUS TYRegisterCallback(TY_DEV_HANDLE hDevice, TY_FRAME_CALLBACK v, void* userdata)
- {
- _hDevice = hDevice;
- _cb = v;
- _userdata = userdata;
- _exit = false;
- _cbThread.create(&workerThread, this);
- return TY_STATUS_OK;
- }
- void TYUnregisterCallback()
- {
- if (!_exit) {
- _exit = true;
- _cbThread.destroy();
- }
- }
- private:
- static void* workerThread(void* userdata)
- {
- CallbackWrapper* pWrapper = (CallbackWrapper*)userdata;
- TY_FRAME_DATA frame;
- while (!pWrapper->_exit)
- {
- int err = TYFetchFrame(pWrapper->_hDevice, &frame, 100);
- if (!err) {
- pWrapper->_cb(&frame, pWrapper->_userdata);
- }
- }
- LOGI("frameCallback exit!");
- return NULL;
- }
- TY_DEV_HANDLE _hDevice;
- TY_FRAME_CALLBACK _cb;
- void* _userdata;
- bool _exit;
- TYThread _cbThread;
- };
- #ifdef _WIN32
- static int get_fps() {
- static int fps_counter = 0;
- static clock_t fps_tm = 0;
- const int kMaxCounter = 250;
- fps_counter++;
- if (fps_counter < kMaxCounter) {
- return -1;
- }
- int elapse = (clock() - fps_tm);
- int v = (int)(((float)fps_counter) / elapse * CLOCKS_PER_SEC);
- fps_tm = clock();
- fps_counter = 0;
- return v;
- }
- #else
- static int get_fps() {
- static int fps_counter = 0;
- static clock_t fps_tm = 0;
- const int kMaxCounter = 200;
- struct timeval start;
- fps_counter++;
- if (fps_counter < kMaxCounter) {
- return -1;
- }
- gettimeofday(&start, NULL);
- int elapse = start.tv_sec * 1000 + start.tv_usec / 1000 - fps_tm;
- int v = (int)(((float)fps_counter) / elapse * 1000);
- gettimeofday(&start, NULL);
- fps_tm = start.tv_sec * 1000 + start.tv_usec / 1000;
- fps_counter = 0;
- return v;
- }
- #endif
- static std::vector<uint8_t> TYReadBinaryFile(const char* filename)
- {
- // open the file:
- std::ifstream file(filename, std::ios::binary);
- if (!file.is_open()){
- return std::vector<uint8_t>();
- }
- // Stop eating new lines in binary mode!!!
- file.unsetf(std::ios::skipws);
- // get its size:
- std::streampos fileSize;
- file.seekg(0, std::ios::end);
- fileSize = file.tellg();
- file.seekg(0, std::ios::beg);
- // reserve capacity
- std::vector<uint8_t> vec;
- vec.reserve(fileSize);
- // read the data:
- vec.insert(vec.begin(),
- std::istream_iterator<uint8_t>(file),
- std::istream_iterator<uint8_t>());
- return vec;
- }
- #endif
|