Skip to content

Instantly share code, notes, and snippets.

@joinAero
Last active September 20, 2023 14:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joinAero/40f2bf867b8d7beed2d2c5de3b6f933a to your computer and use it in GitHub Desktop.
Save joinAero/40f2bf867b8d7beed2d2c5de3b6f933a to your computer and use it in GitHub Desktop.
Use Kinect with OpenCV (C++)
#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_
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})
#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
@joinAero
Copy link
Author

joinAero commented May 19, 2017

Python code is here.

Unable to retrieve correct image using Python code now. Please see this issue.

Extra Links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment