#include <iostream>
#include <visp3/core/vpConfig.h>
#if defined(HAVE_OPENCV_HIGHGUI) && defined(VISP_HAVE_X11)
#include <vector>
#include <opencv2/highgui.hpp>
#include <visp3/core/vpArray2D.h>
#include <visp3/core/vpImageConvert.h>
#include <visp3/core/vpImageTools.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/io/vpImageIo.h>
#include <visp3/sensor/vpRealSense2.h>
std::vector<int> hsv_values_trackbar(6);
const cv::String window_detection_name = "Object Detection";
void set_trackbar_H_min(int val)
{
cv::setTrackbarPos("Low H", window_detection_name, val);
}
void set_trackbar_H_max(int val)
{
cv::setTrackbarPos("High H", window_detection_name, val);
}
void set_trackbar_S_min(int val)
{
cv::setTrackbarPos("Low S", window_detection_name, val);
}
void set_trackbar_S_max(int val)
{
cv::setTrackbarPos("High S", window_detection_name, val);
}
void set_trackbar_V_min(int val)
{
cv::setTrackbarPos("Low V", window_detection_name, val);
}
void set_trackbar_V_max(int val)
{
cv::setTrackbarPos("High V", window_detection_name, val);
}
static void on_low_H_thresh_trackbar(int, void *)
{
hsv_values_trackbar[0] = std::min(hsv_values_trackbar[1]-1, hsv_values_trackbar[0]);
set_trackbar_H_min(hsv_values_trackbar[0]);
}
static void on_high_H_thresh_trackbar(int, void *)
{
hsv_values_trackbar[1] = std::max(hsv_values_trackbar[1], hsv_values_trackbar[0]+1);
set_trackbar_H_max(hsv_values_trackbar[1]);
}
static void on_low_S_thresh_trackbar(int, void *)
{
hsv_values_trackbar[2] = std::min(hsv_values_trackbar[3]-1, hsv_values_trackbar[2]);
set_trackbar_S_min(hsv_values_trackbar[2]);
}
static void on_high_S_thresh_trackbar(int, void *)
{
hsv_values_trackbar[3] = std::max(hsv_values_trackbar[3], hsv_values_trackbar[2]+1);
set_trackbar_S_max(hsv_values_trackbar[3]);
}
static void on_low_V_thresh_trackbar(int, void *)
{
hsv_values_trackbar[4] = std::min(hsv_values_trackbar[5]-1, hsv_values_trackbar[4]);
set_trackbar_V_min(hsv_values_trackbar[4]);
}
static void on_high_V_thresh_trackbar(int, void *)
{
hsv_values_trackbar[5] = std::max(hsv_values_trackbar[5], hsv_values_trackbar[4]+1);
set_trackbar_V_max(hsv_values_trackbar[5]);
}
int main(int argc, const char *argv[])
{
#ifdef ENABLE_VISP_NAMESPACE
#endif
bool opt_save_img = false;
std::string opt_hsv_filename = "calib/hsv-thresholds.yml";
std::string opt_img_filename;
bool show_helper = false;
for (int i = 1; i < argc; i++) {
if ((std::string(argv[i]) == "--hsv-thresholds") && ((i+1) < argc)) {
opt_hsv_filename = std::string(argv[++i]);
}
else if (std::string(argv[i]) == "--image") {
if ((i+1) < argc) {
opt_img_filename = std::string(argv[++i]);
}
else {
show_helper = true;
std::cout << "ERROR \nMissing input image name after parameter " << std::string(argv[i]) << std::endl;
}
}
else if (std::string(argv[i]) == "--save-img") {
opt_save_img = true;
}
if (show_helper || std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
std::cout << "\nSYNOPSIS " << std::endl
<< argv[0]
<< " [--image <input image>]"
<< " [--hsv-thresholds <output filename.yml>]"
<< " [--save-img]"
<< " [--help,-h]"
<< std::endl;
std::cout << "\nOPTIONS " << std::endl
<< " --image <input image>" << std::endl
<< " Name of the input image filename." << std::endl
<< " When this option is not set, we use librealsense to stream images from a Realsense camera. " << std::endl
<< " Example: --image ballons.jpg" << std::endl
<< std::endl
<< " --hsv-thresholds <output filename.yml>" << std::endl
<< " Name of the output filename with yaml extension that will contain HSV low/high thresholds." << std::endl
<< " Default: " << opt_hsv_filename << std::endl
<< std::endl
<< " --save-img" << std::endl
<< " Enable RGB, HSV and segmented image saving" << std::endl
<< std::endl
<< " --help, -h" << std::endl
<< " Display this helper message." << std::endl
<< std::endl;
return EXIT_SUCCESS;
}
}
bool use_realsense = false;
#if defined(VISP_HAVE_REALSENSE2)
use_realsense = true;
#endif
if (use_realsense) {
if (!opt_img_filename.empty()) {
use_realsense = false;
}
}
else if (opt_img_filename.empty()) {
std::cout << "Error: you should use --image <input image> option to specify an input image..." << std::endl;
return EXIT_FAILURE;
}
int max_value_H = 255;
int max_value = 255;
hsv_values_trackbar[0] = 0;
hsv_values_trackbar[1] = max_value_H;
hsv_values_trackbar[2] = 0;
hsv_values_trackbar[3] = max_value;
hsv_values_trackbar[4] = 0;
hsv_values_trackbar[5] = max_value;
int width, height;
#if defined(VISP_HAVE_REALSENSE2)
#endif
if (use_realsense) {
#if defined(VISP_HAVE_REALSENSE2)
width = 848; height = 480;
int fps = 60;
rs2::config config;
config.enable_stream(RS2_STREAM_COLOR, width, height, RS2_FORMAT_RGBA8, fps);
config.disable_stream(RS2_STREAM_DEPTH);
config.disable_stream(RS2_STREAM_INFRARED, 1);
config.disable_stream(RS2_STREAM_INFRARED, 2);
#endif
}
else {
try {
}
return EXIT_FAILURE;
}
}
cv::namedWindow(window_detection_name);
vpArray2D<int> hsv_values(hsv_values_trackbar, hsv_values_trackbar.size(), 1);
std::cout << "Load hsv values from " << opt_hsv_filename << " previous tuning " << std::endl;
std::cout << hsv_values.
t() << std::endl;
hsv_values_prev = hsv_values;
for (size_t i = 0; i < hsv_values.size(); ++i) {
hsv_values_trackbar[i] = hsv_values.
data[i];
}
}
cv::createTrackbar("Low H", window_detection_name, &hsv_values_trackbar[0], max_value_H, on_low_H_thresh_trackbar);
cv::createTrackbar("High H", window_detection_name, &hsv_values_trackbar[1], max_value_H, on_high_H_thresh_trackbar);
cv::createTrackbar("Low S", window_detection_name, &hsv_values_trackbar[2], max_value, on_low_S_thresh_trackbar);
cv::createTrackbar("High S", window_detection_name, &hsv_values_trackbar[3], max_value, on_high_S_thresh_trackbar);
cv::createTrackbar("Low V", window_detection_name, &hsv_values_trackbar[4], max_value, on_low_V_thresh_trackbar);
cv::createTrackbar("High V", window_detection_name, &hsv_values_trackbar[5], max_value, on_high_V_thresh_trackbar);
vpDisplayX d_I(I, 0, 0, "Current frame");
vpDisplayX d_I_segmented(I_segmented, I.
getWidth()+75, 0,
"Segmented frame");
bool quit = false;
while (!quit) {
if (use_realsense) {
#if defined(VISP_HAVE_REALSENSE2)
#endif
}
else {
}
reinterpret_cast<unsigned char *>(H.bitmap),
reinterpret_cast<unsigned char *>(S.bitmap),
reinterpret_cast<unsigned char *
>(V.bitmap), I.
getSize());
reinterpret_cast<unsigned char *>(S.bitmap),
reinterpret_cast<unsigned char *>(V.bitmap),
hsv_values_trackbar,
reinterpret_cast<unsigned char *>(mask.bitmap),
mask.getSize());
quit = true;
}
unsigned int i = ip.
get_i();
unsigned int j = ip.
get_j();
int h = static_cast<int>(H[i][j]);
int s = static_cast<int>(S[i][j]);
int v = static_cast<int>(V[i][j]);
std::cout << "RGB[" << i << "][" << j << "]: " << static_cast<int>(I[i][j].R) << " " << static_cast<int>(I[i][j].G)
<< " " << static_cast<int>(I[i][j].B) << " -> HSV: " << h << " " << s << " " << v << std::endl;
}
unsigned int i = ip.
get_i();
unsigned int j = ip.
get_j();
int h = static_cast<int>(H[i][j]);
int s = static_cast<int>(S[i][j]);
int v = static_cast<int>(V[i][j]);
int offset = 30;
hsv_values_trackbar[0] = std::max(0, h - offset);
hsv_values_trackbar[1] = std::min(max_value_H, h + offset);
hsv_values_trackbar[2] = std::max(0, s - offset);
hsv_values_trackbar[3] = std::min(max_value, s + offset);
hsv_values_trackbar[4] = std::max(0, v - offset);
hsv_values_trackbar[5] = std::min(max_value, v + offset);
std::cout << "HSV learned: " << h << " " << s << " " << v << std::endl;
set_trackbar_H_min(hsv_values_trackbar[0]);
set_trackbar_H_max(hsv_values_trackbar[1]);
set_trackbar_S_min(hsv_values_trackbar[2]);
set_trackbar_S_max(hsv_values_trackbar[3]);
set_trackbar_V_min(hsv_values_trackbar[4]);
set_trackbar_V_max(hsv_values_trackbar[5]);
}
}
if (quit) {
std::cout << "Create directory: " << parent << std::endl;
}
vpArray2D<int> hsv_values_new(hsv_values_trackbar, hsv_values_trackbar.size(), 1);
if (hsv_values_new != hsv_values_prev) {
std::string hsv_filename_backup(opt_hsv_filename + std::string(".previous"));
std::cout << "Create a backup of the previous calibration in " << hsv_filename_backup << std::endl;
}
std::cout << "Save new calibration in: " << opt_hsv_filename << std::endl;
}
if (opt_save_img) {
std::string path_img(parent + "/images-visp");
std::cout << "Create directory: " << path_img << std::endl;
}
std::cout << "Save images in path_img folder..." << std::endl;
}
break;
}
cv::waitKey(10);
}
return EXIT_SUCCESS;
}
#else
int main()
{
#if !defined(HAVE_OPENCV_HIGHGUI)
std::cout << "This tutorial needs OpenCV highgui module as 3rd party." << std::endl;
#endif
#if !defined(VISP_HAVE_X11)
std::cout << "This tutorial needs X11 3rd party enabled." << std::endl;
#endif
std::cout << "Install missing 3rd parties, configure and rebuild ViSP." << std::endl;
return EXIT_SUCCESS;
}
#endif
Implementation of a generic 2D array used as base class for matrices and vectors.
Type * data
Address of the first element of the data array.
static bool saveYAML(const std::string &filename, const vpArray2D< Type > &A, const char *header="")
vpArray2D< Type > t() const
Compute the transpose of the array.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
const std::string & getStringMessage() const
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, unsigned int size)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getWidth() const
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
void acquire(vpImage< unsigned char > &grey, double *ts=nullptr)
bool open(const rs2::config &cfg=rs2::config())
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")