Last active
September 20, 2023 14:11
-
-
Save joinAero/40f2bf867b8d7beed2d2c5de3b6f933a to your computer and use it in GitHub Desktop.
Use Kinect with OpenCV (C++)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CAMERA_HPP_ | |
#define CAMERA_HPP_ | |
#pragma once | |
#include <functional> | |
#include <iostream> | |
#include <sstream> | |
#include <opencv2/opencv.hpp> | |
class Camera { | |
public: | |
using VideoCapture = cv::VideoCapture; | |
using FrameCallback = std::function<bool(const cv::Mat&, const cv::Mat&)>; | |
Camera(int index = 0) | |
: cap_(new VideoCapture(std::move(index))), | |
#ifdef USE_OPENNI | |
use_openni_(index == cv::CAP_OPENNI || index == cv::CAP_OPENNI2), | |
#endif | |
fps_(-1) { | |
int flag = 0; | |
#ifdef USE_OPENNI | |
if (use_openni_) { | |
flag = cv::CAP_OPENNI_IMAGE_GENERATOR; | |
Set(cv::CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, cv::CAP_OPENNI_VGA_30HZ); | |
} | |
#endif | |
std::cout << "Capture frame width: " << Get(flag + cv::CAP_PROP_FRAME_WIDTH) | |
<< ", height: " << Get(flag + cv::CAP_PROP_FRAME_HEIGHT) | |
<< std::endl; | |
fps_ = Get(flag + cv::CAP_PROP_FPS); | |
std::cout << "Capture fps: " << fps_ << std::endl | |
#ifdef USE_OPENNI | |
<< "Use OpenNI: " << use_openni_ << std::endl | |
#endif | |
<< std::endl; | |
} | |
virtual ~Camera() {} | |
bool UseOpenNI() { | |
#ifdef USE_OPENNI | |
return use_openni_; | |
#else | |
return false; | |
#endif | |
} | |
double Get(int prop_id) const { | |
return cap_->get(prop_id); | |
} | |
bool Set(int prop_id, double value) { | |
return cap_->set(prop_id, value); | |
} | |
bool IsOpened() { | |
#ifdef USE_OPENNI | |
return use_openni_ || cap_->isOpened(); | |
#else | |
return cap_->isOpened(); | |
#endif | |
} | |
void Preview(FrameCallback callback = nullptr) { | |
cv::namedWindow("camera", 1); | |
Capture([&callback](const cv::Mat& frame, const cv::Mat& depthmap) { | |
cv::imshow("camera", frame); | |
if (callback && !callback(frame, depthmap)) { | |
// return false to break | |
return false; | |
} | |
// return false to break if ESC/Q | |
char key = (char) cv::waitKey(30); | |
return !(key == 27 || key == 'q' || key == 'Q'); | |
}); | |
} | |
// callback return true to continue and false to break | |
void Capture(FrameCallback callback) { | |
if (!callback) { | |
std::cerr << "ERROR: Null FrameCallback\n"; | |
return; | |
} | |
cv::Mat frame; | |
cv::Mat depthmap; | |
double t; | |
for (;;) { | |
t = (double)cv::getTickCount(); | |
#ifdef USE_OPENNI | |
if (use_openni_) { | |
cap_->grab(); | |
cap_->retrieve(depthmap, cv::CAP_OPENNI_DEPTH_MAP); | |
cap_->retrieve(frame, cv::CAP_OPENNI_BGR_IMAGE); | |
//cap_->retrieve(frame, cv::CAP_OPENNI_GRAY_IMAGE); | |
} else { | |
cap_->read(frame); | |
} | |
#else | |
cap_->read(frame); | |
#endif | |
if (frame.empty()) { | |
std::cerr << "ERROR: Blank frame grabbed\n"; | |
break; | |
} | |
bool ok = callback(frame, depthmap); | |
t = (double)cv::getTickCount() - t; | |
fps_ = cv::getTickFrequency() / t; | |
//std::cout << "fps: " << fps_ << std::endl; | |
if (!ok) break; | |
} | |
} | |
double FPS() const { | |
return fps_; | |
} | |
std::string ExtraInfo() const { | |
std::ostringstream info; | |
info << "FPS: " << fps_; | |
return info.str(); | |
} | |
void DrawInfo(const cv::Mat& im) const { | |
using namespace std; | |
int w = im.cols, h = im.rows; | |
// topLeft: width x height | |
{ | |
ostringstream ss; | |
ss << w << "x" << h; | |
string text = ss.str(); | |
int baseline = 0; | |
cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN, | |
1, 1, &baseline); | |
cv::putText(im, text, cv::Point(5, 5 + textSize.height), | |
cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(255,0,255)); | |
} | |
// topRight: fps | |
{ | |
ostringstream ss; | |
ss << "FPS: " << fps_; | |
string text = ss.str(); | |
int baseline = 0; | |
cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN, | |
1, 1, &baseline); | |
cv::putText(im, text, | |
cv::Point(w - 5 - textSize.width, 5 + textSize.height), | |
cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(255,0,255)); | |
} | |
} | |
private: | |
std::unique_ptr<VideoCapture> cap_; | |
#ifdef USE_OPENNI | |
bool use_openni_; | |
#endif | |
double fps_; | |
}; | |
#endif // CAMERA_HPP_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 2.8) | |
project(OCVSamples) | |
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | |
find_package(OpenCV 3.0 QUIET) | |
if(OpenCV_FOUND) | |
add_definitions(-DUSE_OPENCV3) | |
else() | |
message(FATAL_ERROR "OpenCV > 3.0 not found.") | |
endif() | |
option(USE_OPENNI "Use OpenNI" ON) | |
if(USE_OPENNI) | |
add_definitions(-DUSE_OPENNI) | |
endif() | |
include_directories( | |
common | |
) | |
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/bin) | |
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/lib) | |
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build/lib) | |
add_executable(kinect "kinect.cc") | |
target_link_libraries(kinect ${OpenCV_LIBS}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "camera.hpp" | |
int main(int argc, char const *argv[]) { | |
Camera cam(cv::CAP_OPENNI2); | |
if (!cam.IsOpened()) { | |
std::cerr << "ERROR: Open camera failed" << std::endl; | |
return 1; | |
} | |
std::cout << "\033[1;32mPress ESC/Q to terminate\033[0m\n\n"; | |
double min, max; | |
cv::Mat adjmap, colormap; | |
cam.Capture([&](const cv::Mat& frame, const cv::Mat& depthmap) { | |
cv::minMaxIdx(depthmap, &min, &max); | |
const float scale = 255 / (max-min); | |
depthmap.convertTo(adjmap, CV_8UC1, scale, -min*scale); | |
//applyColorMap(adjmap, colormap, cv::COLORMAP_AUTUMN); | |
cam.DrawInfo(frame); | |
cam.DrawInfo(adjmap); | |
cv::imshow("frame", frame); | |
cv::imshow("depthmap", adjmap); | |
const int key = cv::waitKey(10); | |
return !(key == 27 || key == 'q' || key == 'Q'); // ESC/Q | |
}); | |
return 0; | |
} | |
// OpenCV: How to visualize a depth image: | |
// http://stackoverflow.com/questions/13840013/opencv-how-to-visualize-a-depth-image |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Python code is here.
Extra Links: