diff --git a/app/SandboxSetup/beamerlocationgui.cpp b/app/SandboxSetup/beamerlocationgui.cpp index 3e0d14344d2eb77cb800d8b2a26521eb1a1f3102..d2ad1fc0e3ff2225d8230511dd1264236f957c77 100644 --- a/app/SandboxSetup/beamerlocationgui.cpp +++ b/app/SandboxSetup/beamerlocationgui.cpp @@ -125,7 +125,7 @@ void BeamerLocationGui::routineFrame(){ QPixmap px = QPixmap::fromImage(img); // Show black screen with cross - cv::Mat frameImage = beamer->getCrossFrame(cross, capturedPoints.size()+1, beamer->MAX_LINEAR_LINE_POINTS, !circles.empty()); + cv::Mat frameImage = beamer->buildCrossFrame(cross, capturedPoints.size()+1, beamer->MAX_LINEAR_LINE_POINTS, !circles.empty()); cv::cvtColor(frameImage, frameImage, CV_BGR2RGB); ui->lblFrame->setPixmap(px); diff --git a/inc/beamer.h b/inc/beamer.h index 12c05bdc89a8af77b236f01bc4ec818b4a62a5bf..3a20048153b3e096f422a222006220c28c086f45 100644 --- a/inc/beamer.h +++ b/inc/beamer.h @@ -1,69 +1,23 @@ -#ifndef BEAMER_H -#define BEAMER_H +#ifndef SANDBOX_BEAMER_H +#define SANDBOX_BEAMER_H + #include <opencv2/opencv.hpp> #include "camera.h" +#include "frameProcessProfil.h" -class FrameProcessProfil{ - private: - // Profil to process on gray scaled images - double contrast; // ]0, 255] - int brightness; // [-2^16, 255] - uint minDistance; // [1, 100] % of the frame's width - uint cannyEdgeThreshold; // [0, 255] the strongest the contrast in the image is, the higher this param should be - uint houghAccThreshold; // [0, n] where n = width*height of the frame - uint minRadius; // [1, 100] % of the frame's width - uint maxRadius; // [1, 100] % of the frame's width - - public: - FrameProcessProfil(double c=1.0, int b=0, int d=15, uint cannyThreshold=100, uint accThreshold=50, uint minR=10, uint maxR=50){ - contrast = c; - brightness = b; - minDistance = d; - cannyEdgeThreshold = cannyThreshold; - houghAccThreshold = accThreshold; - minRadius = minR; - maxRadius = maxR; - }; - double getContrast(){ return contrast; }; - void setContrast(double c){ contrast = c; }; - int getBrightness(){ return brightness; }; - void setBrightness(int b){ brightness = b; }; - uint getMinDistance(){ return minDistance; }; - void setMinDistance(uint d){ minDistance = d; }; - uint getCannyEdgeThreshold(){ return cannyEdgeThreshold; }; - void setCannyEdgeThreshold(uint cannyThreshold){ cannyEdgeThreshold = cannyThreshold; }; - uint getHoughAccThreshold(){ return houghAccThreshold; }; - void setHoughAccThreshold(uint accThreshold){ houghAccThreshold = accThreshold; }; - uint getMinRadius(){ return minRadius; }; - void setMinRadius(uint min){ minRadius = min; }; - uint getMaxRadius(){ return maxRadius; }; - void setMaxRadius(uint max){ maxRadius = max; }; - - void print(){ - std::cout << contrast << std::endl; - std::cout << brightness << std::endl; - std::cout << minDistance << std::endl; - std::cout << cannyEdgeThreshold << std::endl; - std::cout << houghAccThreshold << std::endl; - std::cout << minRadius << std::endl; - std::cout << maxRadius << std::endl; - } - -}; - class Beamer{ private: cv::Point3f beamerPosition; cv::Size resolution = cv::Size(256,144); - FrameProcessProfil profil = FrameProcessProfil(); + FrameProcessProfil *profil; - cv::Point3f intersection(cv::Vec3f v1, cv::Point3f p1, cv::Vec3f v2, cv::Point3f p2, cv::Vec3f v3, cv::Point3f p3, bool &isFound); + //cv::Point3f intersection(cv::Vec3f v1, cv::Point3f p1, cv::Vec3f v2, cv::Point3f p2, cv::Vec3f v3, cv::Point3f p3, bool &isFound); public: Beamer(); + ~Beamer(); - const char ESCAPE_CHAR = 27; const unsigned int MAX_LINEAR_LINE_POINTS = 3; //number of point to calculate 1 vector const double LINEAR_REGRESSION_FACT = -20.0; // used for linear regression @@ -79,14 +33,13 @@ class Beamer{ setHeight(res.height); } - FrameProcessProfil* getProfil(){ return &profil; }; - void setProfil(FrameProcessProfil p){ profil = p; }; + FrameProcessProfil* getProfil(){ return profil; }; + void setProfil(FrameProcessProfil p){ profil->setProfil(p); }; - int findBeamerFrom(Camera *camera); cv::Mat editContrast(cv::Mat image, double contrast, int brightness); cv::Point3f deprojectPixel(cv::Point2i circle, cv::Mat *depth, Camera *camera); std::vector<cv::Point2i> getCrossList(); - cv::Mat getCrossFrame(cv::Point2i projectedCross, int step, int max, bool circlesFound); + cv::Mat buildCrossFrame(cv::Point2i projectedCross, int step, int max, bool circlesFound); cv::Point3d approximatePosition(std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions); void findLinearLineFrom(std::vector<cv::Point3f> *capturedPoints, std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions); std::vector<cv::Point3i> findCircles(cv::Mat &rgb, double contrast, int brightness, double centersMinDist, int cannyEdgeThreshold, int houghAccThreshold, double minRadius, double maxRadius); diff --git a/inc/borderedit.h b/inc/borderedit.h deleted file mode 100644 index 15a2796e1a5920f42523ec2f048dd319574ac096..0000000000000000000000000000000000000000 --- a/inc/borderedit.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef BORDEREDIT_H -#define BORDEREDIT_H - -#include <opencv2/opencv.hpp> - -class BorderEdit{ - private: - static const int margeClick = 10; - static constexpr char *wndname = (char *)"Sandbox Border Finder"; - static cv::Mat frameImage; - - // OPENCV - MANUEL RECT CHANGE - static void drawSquare(cv::Point *p, int n); - static int findPoints(int x, int y, std::vector<cv::Point> &posSandbox); - static void mouseHandler(int event, int x, int y, int, void *param); - static const char ESCAPE_CHAR = 27; - - public: - static int edit(cv::Mat frame, std::vector<cv::Point> *posSandbox); - -}; -#endif \ No newline at end of file diff --git a/inc/frameProcessProfil.h b/inc/frameProcessProfil.h new file mode 100644 index 0000000000000000000000000000000000000000..5a0bfe6b77b95cdfd92d68b98226e8e74b23653f --- /dev/null +++ b/inc/frameProcessProfil.h @@ -0,0 +1,62 @@ +#ifndef SANDBOX_FRAME_PROCESS_PROFIL_H +#define SANDBOX_FRAME_PROCESS_PROFIL_H + +class FrameProcessProfil{ + private: + // Profil to process on gray scaled images + double contrast; // ]0, 255] + int brightness; // [-2^16, 255] + uint minDistance; // [1, 100] % of the frame's width + uint cannyEdgeThreshold; // [0, 255] the strongest the contrast in the image is, the higher this param should be + uint houghAccThreshold; // [0, n] where n = width*height of the frame + uint minRadius; // [1, 100] % of the frame's width + uint maxRadius; // [1, 100] % of the frame's width + + public: + FrameProcessProfil(double c=1.0, int b=0, int d=15, uint cannyThreshold=100, uint accThreshold=50, uint minR=10, uint maxR=50){ + contrast = c; + brightness = b; + minDistance = d; + cannyEdgeThreshold = cannyThreshold; + houghAccThreshold = accThreshold; + minRadius = minR; + maxRadius = maxR; + }; + double getContrast(){ return contrast; }; + void setContrast(double c){ contrast = c; }; + int getBrightness(){ return brightness; }; + void setBrightness(int b){ brightness = b; }; + uint getMinDistance(){ return minDistance; }; + void setMinDistance(uint d){ minDistance = d; }; + uint getCannyEdgeThreshold(){ return cannyEdgeThreshold; }; + void setCannyEdgeThreshold(uint cannyThreshold){ cannyEdgeThreshold = cannyThreshold; }; + uint getHoughAccThreshold(){ return houghAccThreshold; }; + void setHoughAccThreshold(uint accThreshold){ houghAccThreshold = accThreshold; }; + uint getMinRadius(){ return minRadius; }; + void setMinRadius(uint min){ minRadius = min; }; + uint getMaxRadius(){ return maxRadius; }; + void setMaxRadius(uint max){ maxRadius = max; }; + + void setProfil(FrameProcessProfil p){ + contrast = p.getContrast(); + brightness = p.getBrightness(); + minDistance = p.getMinDistance(); + cannyEdgeThreshold = p.getCannyEdgeThreshold(); + houghAccThreshold = p.getHoughAccThreshold(); + minRadius = p.getMinRadius(); + maxRadius = p.getMaxRadius(); + } + + void print(){ + std::cout << contrast << std::endl; + std::cout << brightness << std::endl; + std::cout << minDistance << std::endl; + std::cout << cannyEdgeThreshold << std::endl; + std::cout << houghAccThreshold << std::endl; + std::cout << minRadius << std::endl; + std::cout << maxRadius << std::endl; + } + +}; + +#endif \ No newline at end of file diff --git a/inc/beamerProjection.h b/inc/projection.h similarity index 86% rename from inc/beamerProjection.h rename to inc/projection.h index 6d492c71175719e64c3c5b8dec9c9cddb1aa61e9..e486fd0b887d36c6f67321c5f1662516ed20ebe8 100644 --- a/inc/beamerProjection.h +++ b/inc/projection.h @@ -1,21 +1,21 @@ -#ifndef BEAMERPROJECTION_H -#define BEAMERPROJECTION_H +#ifndef SANDBOX_PROJECTION_H +#define SANDBOX_PROJECTION_H #include <opencv2/opencv.hpp> #include "beamer.h" #include "camera.h" -class BeamerProjection{ +class Projection{ private: cv::Mat adjustingMatrix; - float distanceTopSandbox = 1.0f; + float distanceTopSandbox; cv::Point2i findMatchingPixel(int i, int j, float z, Camera *camera, cv::Point3f beamer_pos); void copyPixelsInto(cv::Point2i pixel_dst, cv::Mat &dst, cv::Point2i pixel_src, cv::Mat &src, cv::Rect base); cv::Size getMatchingSize(cv::Mat &src, cv::Rect base); public: - BeamerProjection(); + Projection(); void setAdjustingMatrix(cv::Mat matrix){ adjustingMatrix = matrix; } cv::Mat getAdjustingMatrix(){ return adjustingMatrix; } diff --git a/inc/sandbox.h b/inc/sandbox.h index 182a86aed35beb21caa78b9998cf0c5d096a09a3..64311677df1dec2d0d213ea1fcb11d5f4ac36221 100644 --- a/inc/sandbox.h +++ b/inc/sandbox.h @@ -3,36 +3,31 @@ #include <opencv2/opencv.hpp> #include "camera.h" -#include "beamerProjection.h" +#include "projection.h" #include "beamer.h" #include "sandboxConfig.h" class Sandbox{ private: char *defaultConfigFilePath = (char *)"./sandbox_conf.yaml"; - char *defaultWindowsName = (char*) "ShowApp"; - BeamerProjection projection; - Camera camera; - Beamer beamer; - - void initWindowsFullScreen(char *windowName); - void showImage(cv::Mat* image, char *windowName); + Projection *projection; + Camera *camera; + Beamer *beamer; public: Sandbox(); + ~Sandbox(); - Camera* getCamera(){ return &camera; }; - Beamer* getBeamer(){ return &beamer; }; - BeamerProjection* getProjection(){ return &projection; }; + Camera* getCamera(){ return camera; }; + Beamer* getBeamer(){ return beamer; }; + Projection* getProjection(){ return projection; }; void init(); cv::Mat getColorFrame(); cv::Mat getDepthFrame(); cv::Mat adjustProjection(cv::Mat frame); - void showImage(cv::Mat &image); int loadConfig(); int loadConfigFrom(char *path); - void initWindowsFullScreen(); }; diff --git a/inc/sandboxConfig.h b/inc/sandboxConfig.h index 0cef219e0b4244efa2ea8fee0340549a63ae9997..8bf5306e1cfbfa68cbfc9b69092ff3441c6b76d9 100644 --- a/inc/sandboxConfig.h +++ b/inc/sandboxConfig.h @@ -1,10 +1,10 @@ -#ifndef SANDBOXCONFIG_H -#define SANDBOXCONFIG_H +#ifndef SANDBOX_CONFIG_H +#define SANDBOX_CONFIG_H #include <yaml-cpp/yaml.h> #include <opencv2/opencv.hpp> #include "camera.h" -#include "beamerProjection.h" +#include "projection.h" #include "beamer.h" #define SCFG_MASK "CroppingMask" @@ -26,8 +26,8 @@ class SandboxConfig{ static int saveBeamerResolutionInto(char *path, cv::Size resolution); static int saveFrameProcessProfil(char *path, FrameProcessProfil profil); - static int loadAdjustingMatrixFrom(char *path, BeamerProjection *projection); - static int loadDistanceToSandboxTop(char *path, BeamerProjection *projection); + static int loadAdjustingMatrixFrom(char *path, Projection *projection); + static int loadDistanceToSandboxTop(char *path, Projection *projection); static int loadCroppingMaskFrom(char *path, Camera *camera); static int loadBeamerPositionFrom(char *path, Beamer *beamer); static int loadBeamerResolutionFrom(char *path, Beamer *beamer); diff --git a/inc/sandboxSetup.h b/inc/sandboxSetup.h index 3460544e1c43b9d4a13c2783ee63570c04ec30db..3d2e37036dd9dc28172477c5e3b42e78a129da02 100644 --- a/inc/sandboxSetup.h +++ b/inc/sandboxSetup.h @@ -1,46 +1,40 @@ -#ifndef SANDBOXSETUP_H -#define SANDBOXSETUP_H +#ifndef SANDBOX_SETUP_H +#define SANDBOX_SETUP_H #include <opencv2/opencv.hpp> #include "beamer.h" -#include "beamerProjection.h" +#include "projection.h" #include "camera.h" -#include "borderedit.h" #include "sandboxConfig.h" class SandboxSetup{ private: char *defaultConfigFilePath = (char *)"./sandbox_conf.yaml"; - BeamerProjection projection; - Camera camera; - Beamer beamer; + Projection *projection; + Camera *camera; + Beamer *beamer; double toDegrees(double radians); - void initWindowsFullScreen(char *windowName); public: SandboxSetup(); + ~SandboxSetup(); - BeamerProjection* getProjection(){ return &projection; }; - Camera* getCamera(){ return &camera; }; - Beamer* getBeamer(){ return &beamer; }; + Projection* getProjection(){ return projection; }; + Camera* getCamera(){ return camera; }; + Beamer* getBeamer(){ return beamer; }; // save config in file => persistant - int saveConfigFrom(char *path); + int saveConfigInto(char *path); int saveConfig(); + int loadFrameProcessProfilFrom(char *path); int loadFrameProcessProfil(); // edit variables of config => not persistant void setupAdjustMatrix(std::vector<cv::Point> rectPoints, cv::Point center); void setupCroppingMask(std::vector<cv::Point> rectPoints); - - void defaultCaptureBlueScreen(int delay); - int defaultSetupProjection(); - int defaultSetupBeamerResolution(); - int defaultSetupBeamerLocation(); - }; #endif diff --git a/src/components/beamer.cpp b/src/components/beamer.cpp index a1dbd372f78f9b79272439acac6b02f13db7b7ab..b5bbf1283692553d49fab9ff6155f3224602187f 100644 --- a/src/components/beamer.cpp +++ b/src/components/beamer.cpp @@ -4,103 +4,39 @@ Beamer::Beamer(){ beamerPosition = cv::Point3f(0.0f, 0.265f, -0.205f); + profil = new FrameProcessProfil(); } +Beamer::~Beamer(){ + delete profil; +} /* -* Public +* Global purpose */ -int Beamer::findBeamerFrom(Camera *camera){ - - char wname[] = "beamer location"; - cv::namedWindow(wname, CV_WINDOW_NORMAL); - cv::setWindowProperty(wname, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); - - // Setup cross for calibration - std::vector<cv::Point2i> crosses = getCrossList(); - std::vector<cv::Point3d> directions; //vectors calculate for each point - std::vector<cv::Point3d> bases; //1 point for each vector (to calculate constante d) - - for (cv::Point2i cross : crosses){ - - std::vector<cv::Point3f> capturedPoints; - cv::Mat depth; - cv::Mat rgb; - - while( capturedPoints.size() < MAX_LINEAR_LINE_POINTS ){ - - // capture frame - camera->capture(); - depth = camera->getDepthFrame(); - rgb = camera->getColorFrame(); - - // Look for the circle target - double minDist = rgb.cols / (double)profil.getMinDistance(); - double minRadius = (profil.getMinRadius()>0) ? rgb.cols/(double)profil.getMinRadius() : 0; - double maxRadius = (profil.getMaxRadius()>0) ? rgb.cols/(double)profil.getMaxRadius() : 0; - std::vector<cv::Point3i> circles = findCircles( rgb, - profil.getContrast(), - profil.getBrightness(), - minDist, - profil.getCannyEdgeThreshold(), - profil.getHoughAccThreshold(), - minRadius, - maxRadius ); - - // Show black screen with cross - cv::Mat frameImage = getCrossFrame(cross, capturedPoints.size()+1, MAX_LINEAR_LINE_POINTS, !circles.empty()); - - cv::imshow(wname, frameImage); - - // Wait for interaction - int keypressed = cv::waitKey(500); - if(keypressed != -1){ - char keyCode = (char)keypressed; - if (keyCode == ESCAPE_CHAR){ - return 1; - } - else if (keyCode == ' '){ - if(!circles.empty()){ - capturedPoints.push_back( deprojectPixel( cv::Point2i(circles.at(0).x, circles.at(0).y ), &depth, camera) ); - } - } - } - } - - findLinearLineFrom(&capturedPoints, &bases, &directions); - } - - - setPosition( (cv::Point3f)approximatePosition(&bases, &directions) ); - - cv::destroyAllWindows(); - - return 0; -} - cv::Point3f Beamer::deprojectPixel(cv::Point2i circle, cv::Mat *depth, Camera *camera){ float coord[2] = {(float)circle.x, (float)circle.y}; float z = depth->at<float>(circle.y, circle.x); return camera->deprojectPixelToPoint(coord, z); } -void Beamer::findLinearLineFrom(std::vector<cv::Point3f> *capturedPoints, std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions){ - - cv::Vec6f line; - cv::fitLine(*capturedPoints, line, CV_DIST_L2, 0, 0.01, 0.01); - cv::Point3d base = cv::Point3d(line[0], line[1], line[2]); - cv::Point3d direction = cv::Point3d( LINEAR_REGRESSION_FACT * line[3], - LINEAR_REGRESSION_FACT * line[4], - LINEAR_REGRESSION_FACT * line[5] ); - - bases->push_back(base); - directions->push_back(direction); +void Beamer::printPosition(){ + cv::Point3f pos = getPosition(); + std::cout << "(" << pos.x << "," << pos.y << "," << pos.z << ")" << std::endl; } + + + +/* +* Setup config purpose +*/ + + std::vector<cv::Point2i> Beamer::getCrossList(){ std::vector<cv::Point2i> points; @@ -113,7 +49,56 @@ std::vector<cv::Point2i> Beamer::getCrossList(){ } -cv::Mat Beamer::getCrossFrame(cv::Point projectedCross, int step, int max, bool circlesFound){ +cv::Mat Beamer::editContrast(cv::Mat image, double contrast, int brightness){ + + cv::Mat new_image = cv::Mat::zeros( image.size(), image.type() ); + double alpha = contrast; + int beta = brightness; + + // source : https://docs.opencv.org/2.4/doc/tutorials/core/basic_linear_transform/basic_linear_transform.html + for( int y = 0; y < image.rows; y++ ) { + for( int x = 0; x < image.cols; x++ ) { + new_image.at<uchar>(y,x) = cv::saturate_cast<uchar>( alpha*image.at<uchar>(y,x) + beta ); + } + } + + return new_image; +} + + +std::vector<cv::Point3i> Beamer::findCircles(cv::Mat &rgb, double contrast, int brightness, double centersMinDist, int cannyEdgeThreshold, int houghAccThreshold, double minRadius, double maxRadius){ + + cv::Mat src_gray; + cv::cvtColor(rgb, src_gray, CV_BGR2GRAY); + /// Reduce the noise so we avoid false circle detection + cv::GaussianBlur(src_gray, src_gray, cv::Size(9, 9), 2, 2); + std::vector<cv::Vec3f> circles; + circles.clear(); + + src_gray = editContrast(src_gray, (double)contrast, (double)brightness); + + /// Apply the Hough Transform to find the circles + // source, output, method, inverse ratio of resolution, Minimum distance between detected centers, threeshold canny, threeshold center, min radius, max radius + // dp : Inverse resolution for the accumulator matrixe => image_resolution * dp = acc_resolution + // min_dist : Minimal distance between the detected centers + // param_1 : Upper threshold of the canny edge detector, determines if a pixel is an edge + // param_2 : Threshold for the center detection, after the accumulator is complet, threshold to keep only the possible centers + // min_radius : Min radius of the circles drawn on the accumulator + // max_radius : Max radius of the circles drawn on the accumulator + cv::HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, centersMinDist, (double)cannyEdgeThreshold, (double)houghAccThreshold, minRadius, maxRadius); + + std::vector<cv::Point3i> result; + if (!circles.empty()) + { + for(cv::Vec3f circle: circles){ + result.push_back( cv::Point3i(round(circle[0]), round(circle[1]), round(circle[2])) ); + } + } + return result; +} + + +cv::Mat Beamer::buildCrossFrame(cv::Point projectedCross, int step, int max, bool circlesFound){ cv::Mat frameImage(resolution, CV_8UC3, cv::Scalar(0, 0, 0)); cv::Scalar red = cv::Scalar(0, 0, 255); @@ -134,16 +119,21 @@ cv::Mat Beamer::getCrossFrame(cv::Point projectedCross, int step, int max, bool return frameImage; } -void Beamer::printPosition(){ - cv::Point3f pos = getPosition(); - std::cout << "(" << pos.x << "," << pos.y << "," << pos.z << ")" << std::endl; -} +void Beamer::findLinearLineFrom(std::vector<cv::Point3f> *capturedPoints, std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions){ + + cv::Vec6f line; + cv::fitLine(*capturedPoints, line, CV_DIST_L2, 0, 0.01, 0.01); + cv::Point3d base = cv::Point3d(line[0], line[1], line[2]); + cv::Point3d direction = cv::Point3d( LINEAR_REGRESSION_FACT * line[3], + LINEAR_REGRESSION_FACT * line[4], + LINEAR_REGRESSION_FACT * line[5] ); + + bases->push_back(base); + directions->push_back(direction); +} -/* -* Private -*/ /* @@ -208,53 +198,6 @@ int LineLineIntersect( return (true); } -cv::Mat Beamer::editContrast(cv::Mat image, double contrast, int brightness){ - - cv::Mat new_image = cv::Mat::zeros( image.size(), image.type() ); - double alpha = contrast; - int beta = brightness; - - // source : https://docs.opencv.org/2.4/doc/tutorials/core/basic_linear_transform/basic_linear_transform.html - for( int y = 0; y < image.rows; y++ ) { - for( int x = 0; x < image.cols; x++ ) { - new_image.at<uchar>(y,x) = cv::saturate_cast<uchar>( alpha*image.at<uchar>(y,x) + beta ); - } - } - - return new_image; -} - -std::vector<cv::Point3i> Beamer::findCircles(cv::Mat &rgb, double contrast, int brightness, double centersMinDist, int cannyEdgeThreshold, int houghAccThreshold, double minRadius, double maxRadius){ - - cv::Mat src_gray; - cv::cvtColor(rgb, src_gray, CV_BGR2GRAY); - /// Reduce the noise so we avoid false circle detection - cv::GaussianBlur(src_gray, src_gray, cv::Size(9, 9), 2, 2); - std::vector<cv::Vec3f> circles; - circles.clear(); - - src_gray = editContrast(src_gray, (double)contrast, (double)brightness); - - /// Apply the Hough Transform to find the circles - // source, output, method, inverse ratio of resolution, Minimum distance between detected centers, threeshold canny, threeshold center, min radius, max radius - // dp : Inverse resolution for the accumulator matrixe => image_resolution * dp = acc_resolution - // min_dist : Minimal distance between the detected centers - // param_1 : Upper threshold of the canny edge detector, determines if a pixel is an edge - // param_2 : Threshold for the center detection, after the accumulator is complet, threshold to keep only the possible centers - // min_radius : Min radius of the circles drawn on the accumulator - // max_radius : Max radius of the circles drawn on the accumulator - cv::HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1, centersMinDist, (double)cannyEdgeThreshold, (double)houghAccThreshold, minRadius, maxRadius); - - std::vector<cv::Point3i> result; - if (!circles.empty()) - { - for(cv::Vec3f circle: circles){ - result.push_back( cv::Point3i(round(circle[0]), round(circle[1]), round(circle[2])) ); - } - } - return result; -} - cv::Point3d Beamer::approximatePosition(std::vector<cv::Point3d> *bases, std::vector<cv::Point3d> *directions){ diff --git a/src/components/camera.cpp b/src/components/camera.cpp index 5bbc05581fa45cb89dde392aca4a231d79724fec..3442629842e82830d2942981cce96d6d60f4f33f 100644 --- a/src/components/camera.cpp +++ b/src/components/camera.cpp @@ -38,8 +38,8 @@ int Camera::start(){ } // Logs - std::remove("./camera.logs"); - rs2::log_to_file(RS2_LOG_SEVERITY_DEBUG, "./camera.logs"); + //std::remove("./camera.logs"); + //rs2::log_to_file(RS2_LOG_SEVERITY_DEBUG, "./camera.logs"); // Settings // default camera resolution : 640x480 diff --git a/src/components/beamerProjection.cpp b/src/components/projection.cpp similarity index 87% rename from src/components/beamerProjection.cpp rename to src/components/projection.cpp index da649fed1b47a358c9e0dc0fa64e86ade0c6693b..ffccf15324030a0f4d1edc443cb1531a5284a04b 100644 --- a/src/components/beamerProjection.cpp +++ b/src/components/projection.cpp @@ -1,12 +1,13 @@ -#include "../../inc/beamerProjection.h" +#include "../../inc/projection.h" -BeamerProjection::BeamerProjection(){ - //adjustingMatrix = cv::getRotationMatrix2D(cv::Point(0, 0), 0, 1); +Projection::Projection(){ + adjustingMatrix = cv::getRotationMatrix2D(cv::Point(0, 0), 0, 1); + distanceTopSandbox = 1.0f; } -cv::Point2i BeamerProjection::rotatePixel(cv::Point2i pixel){ +cv::Point2i Projection::rotatePixel(cv::Point2i pixel){ cv::Mat tmp = (cv::Mat_<cv::Vec2f>(1, 1) << cv::Vec2f(pixel.x, pixel.y)); cv::transform(tmp, tmp, adjustingMatrix); @@ -15,7 +16,7 @@ cv::Point2i BeamerProjection::rotatePixel(cv::Point2i pixel){ -void BeamerProjection::adjustFrame(cv::Mat depth, cv::Mat src, cv::Mat &dst, Camera *camera, cv::Point3f beamer_pos){ +void Projection::adjustFrame(cv::Mat depth, cv::Mat src, cv::Mat &dst, Camera *camera, cv::Point3f beamer_pos){ cv::Rect mask = camera->getCroppingMask(); cv::Size dst_size = dst.size(); @@ -84,7 +85,7 @@ void BeamerProjection::adjustFrame(cv::Mat depth, cv::Mat src, cv::Mat &dst, Cam cv::warpAffine(dst, dst, adjustingMatrix, dst.size()); } -cv::Size BeamerProjection::getMatchingSize(cv::Mat &src, cv::Rect base){ +cv::Size Projection::getMatchingSize(cv::Mat &src, cv::Rect base){ cv::Size bigSize; bigSize.width = (src.size().width % base.width == 0) ? src.size().width : src.size().width - (src.size().width % base.width) + base.width; bigSize.height = (src.size().height % base.height == 0) ? src.size().height : src.size().height - (src.size().height % base.height) + base.height; @@ -92,7 +93,7 @@ cv::Size BeamerProjection::getMatchingSize(cv::Mat &src, cv::Rect base){ } // pixels coordinates are relative to the camera depth frame -void BeamerProjection::copyPixelsInto(cv::Point2i pixel_dst, cv::Mat &dst, cv::Point2i pixel_src, cv::Mat &src, cv::Rect base){ +void Projection::copyPixelsInto(cv::Point2i pixel_dst, cv::Mat &dst, cv::Point2i pixel_src, cv::Mat &src, cv::Rect base){ if( src.size().width == dst.size().width && src.size().height == dst.size().height ){ @@ -124,7 +125,7 @@ void BeamerProjection::copyPixelsInto(cv::Point2i pixel_dst, cv::Mat &dst, cv::P CP : distance from camera to point (value of depth_frame) CB : distance from camera to beamer (beamer's position is relative to the camera) */ -cv::Point2i BeamerProjection::findMatchingPixel(int i, int j, float z, Camera *camera, cv::Point3f CB){ +cv::Point2i Projection::findMatchingPixel(int i, int j, float z, Camera *camera, cv::Point3f CB){ float pixel[2] = {static_cast<float>(i), static_cast<float>(j)}; cv::Point3f CP = camera->deprojectPixelToPoint(pixel, z); @@ -139,7 +140,7 @@ cv::Point2i BeamerProjection::findMatchingPixel(int i, int j, float z, Camera *c } -void BeamerProjection::printAdjustingMatrix(){ +void Projection::printAdjustingMatrix(){ cv::Mat matrix = getAdjustingMatrix(); for (int y = 0; y < matrix.rows; y++){ diff --git a/src/lib/sandbox.cpp b/src/lib/sandbox.cpp index 98f22066c95c36a97a414cf9aa9309f4974821a8..6ee882aa61971cbb3bd51b9be75214222cf13bef 100644 --- a/src/lib/sandbox.cpp +++ b/src/lib/sandbox.cpp @@ -6,7 +6,15 @@ */ Sandbox::Sandbox(){ - + projection = new Projection(); + camera = new Camera(); + beamer = new Beamer(); +} + +Sandbox::~Sandbox(){ + delete beamer; + delete camera; + delete projection; } @@ -15,25 +23,25 @@ Sandbox::Sandbox(){ */ void Sandbox::init(){ - camera.start(); + camera->start(); } cv::Mat Sandbox::getColorFrame(){ - camera.capture(); - return camera.getColorFrame()(camera.getCroppingMask()); + camera->capture(); + return camera->getColorFrame()(camera->getCroppingMask()); } cv::Mat Sandbox::getDepthFrame(){ - camera.capture(); - return camera.getDepthFrame()(camera.getCroppingMask()); + camera->capture(); + return camera->getDepthFrame()(camera->getCroppingMask()); } cv::Mat Sandbox::adjustProjection(cv::Mat frame){ cv::Mat depth = getDepthFrame(); - cv::Mat imageCalibrate = cv::Mat(cv::Size(beamer.getWidth(), beamer.getHeight()), CV_8UC3, cv::Scalar(0, 0, 0)); - projection.adjustFrame(depth, frame, imageCalibrate, &camera, beamer.getPosition()); + cv::Mat imageCalibrate = cv::Mat(cv::Size(beamer->getWidth(), beamer->getHeight()), CV_8UC3, cv::Scalar(0, 0, 0)); + projection->adjustFrame(depth, frame, imageCalibrate, camera, beamer->getPosition()); // frame after process //cv::dilate(imageCalibrate, imageCalibrate, cv::Mat(), cv::Point(-1, -1), 2, 1, 1); @@ -42,24 +50,17 @@ cv::Mat Sandbox::adjustProjection(cv::Mat frame){ return imageCalibrate; } -void Sandbox::showImage(cv::Mat &image){ - - initWindowsFullScreen(defaultWindowsName); - cv::Mat res = adjustProjection(image); - cv::imshow(defaultWindowsName, res); -} - int Sandbox::loadConfigFrom(char *path){ - int err = SandboxConfig::loadAdjustingMatrixFrom(path, &projection); + int err = SandboxConfig::loadAdjustingMatrixFrom(path, projection); if(err){ return err; } - err = SandboxConfig::loadDistanceToSandboxTop(path, &projection); + err = SandboxConfig::loadDistanceToSandboxTop(path, projection); if(err){ return err; } - err = SandboxConfig::loadCroppingMaskFrom(path, &camera); + err = SandboxConfig::loadCroppingMaskFrom(path, camera); if(err){ return err; } - err = SandboxConfig::loadBeamerResolutionFrom(path, &beamer); + err = SandboxConfig::loadBeamerResolutionFrom(path, beamer); if(err){ return err; } - err = SandboxConfig::loadBeamerPositionFrom(path, &beamer); + err = SandboxConfig::loadBeamerPositionFrom(path, beamer); if(err){ return err; } return 0; } @@ -68,17 +69,3 @@ int Sandbox::loadConfig(){ return loadConfigFrom(defaultConfigFilePath); } - -void Sandbox::initWindowsFullScreen(){ - initWindowsFullScreen(defaultWindowsName); -} - - -/* - * PRIVATE - */ - -void Sandbox::initWindowsFullScreen(char *windowName){ - cv::namedWindow(windowName, CV_WINDOW_NORMAL); - cv::setWindowProperty(windowName, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); -} \ No newline at end of file diff --git a/src/lib/sandboxSetup.cpp b/src/lib/sandboxSetup.cpp index ef179b7519fb4484cd01f068d8b1b00bb8fb85c0..caf24db46a94bd2b3be91f0d0c28ae42167f272a 100644 --- a/src/lib/sandboxSetup.cpp +++ b/src/lib/sandboxSetup.cpp @@ -2,7 +2,15 @@ SandboxSetup::SandboxSetup(){ - + projection = new Projection(); + camera = new Camera(); + beamer = new Beamer(); +} + +SandboxSetup::~SandboxSetup(){ + delete beamer; + delete camera; + delete projection; } // @@ -11,23 +19,23 @@ SandboxSetup::SandboxSetup(){ // return 1 when config can't be saved in file -int SandboxSetup::saveConfigFrom(char *path){ - if(SandboxConfig::saveAdjustingMatrixInto(path, projection.getAdjustingMatrix())) +int SandboxSetup::saveConfigInto(char *path){ + if(SandboxConfig::saveAdjustingMatrixInto(path, projection->getAdjustingMatrix())) return 1; - if(SandboxConfig::saveDistanceToSandboxTop(path, projection.getDistanceTopSandbox())) + if(SandboxConfig::saveDistanceToSandboxTop(path, projection->getDistanceTopSandbox())) return 1; - if(SandboxConfig::saveCroppingMaskInto(path, camera.getCroppingMask())) + if(SandboxConfig::saveCroppingMaskInto(path, camera->getCroppingMask())) return 1; - if(SandboxConfig::saveBeamerResolutionInto(path, cv::Size(beamer.getWidth(), beamer.getHeight()))) + if(SandboxConfig::saveBeamerResolutionInto(path, cv::Size(beamer->getWidth(), beamer->getHeight()))) return 1; - if(SandboxConfig::saveBeamerPositionInto(path, beamer.getPosition())) + if(SandboxConfig::saveBeamerPositionInto(path, beamer->getPosition())) return 1; - if(SandboxConfig::saveFrameProcessProfil(path, *beamer.getProfil())) + if(SandboxConfig::saveFrameProcessProfil(path, *beamer->getProfil())) return 1; return 0; @@ -35,11 +43,15 @@ int SandboxSetup::saveConfigFrom(char *path){ int SandboxSetup::saveConfig(){ - return saveConfigFrom(defaultConfigFilePath); + return saveConfigInto(defaultConfigFilePath); +} + +int SandboxSetup::loadFrameProcessProfilFrom(char *path){ + return SandboxConfig::loadFrameProcessProfil(path, beamer->getProfil()); } int SandboxSetup::loadFrameProcessProfil(){ - return SandboxConfig::loadFrameProcessProfil(defaultConfigFilePath, beamer.getProfil()); + return loadFrameProcessProfilFrom(defaultConfigFilePath); } @@ -49,7 +61,7 @@ void SandboxSetup::setupAdjustMatrix(std::vector<cv::Point> rectPoints, cv::Poin int widthTop = rectPoints[3].x - rectPoints[0].x; double angle1 = atan((double)(rectPoints[3].y - rectPoints[0].y) / widthTop); cv::Mat matRotation = cv::getRotationMatrix2D(center, toDegrees(angle1), 1); // adjustingMatrix - projection.setAdjustingMatrix(matRotation); + projection->setAdjustingMatrix(matRotation); } void SandboxSetup::setupCroppingMask(std::vector<cv::Point> rectPoints){ @@ -57,87 +69,8 @@ void SandboxSetup::setupCroppingMask(std::vector<cv::Point> rectPoints){ // Set cropping mask int widthTop = rectPoints[3].x - rectPoints[0].x; cv::Size rectSize = cv::Size(widthTop, cvRound(widthTop / 1.33333) + 5); - cv::Point p = projection.rotatePixel(rectPoints[0]); - camera.setCroppingMask(cv::Rect(p, rectSize)); // croppingMask -} - - - -// -// Default setup routines -// - -int SandboxSetup::defaultSetupBeamerResolution(){ - int width = 0; - int height = 0; - - std::cout << "Enter width of the frame projected :" << std::endl; - std::cin >> width; - if(std::cin.fail()){ - return 1; - } - std::cout << "Enter height of the frame projected :" << std::endl; - std::cin >> height; - if(std::cin.fail()){ - return 1; - } - - beamer.setHeight(height); - beamer.setWidth(width); - - return 0; -} - - -// return 1 when user exits process -int SandboxSetup::defaultSetupBeamerLocation(){ - - return beamer.findBeamerFrom(&camera); -} - - -// return 1 when user exits process -int SandboxSetup::defaultSetupProjection(){ - - defaultCaptureBlueScreen(300); - - cv::Mat frameData = camera.getDepthFrame(); - cv::Mat coloredFrame = camera.getColorFrame(); - cv::Size s = frameData.size(); - cv::Point center(s.width / 2, s.height / 2); - - // Edit projection - float y = coloredFrame.size().height; - float x = coloredFrame.size().width; - std::vector<cv::Point> rectPoints{ cv::Point(1.0/4*x, 1.0/4*y), cv::Point(1.0/4*x, 3.0/4*y), cv::Point(3.0/4*x, 3.0/4*y), cv::Point(3.0/4*x, 1.0/4*y) }; - if(BorderEdit::edit(coloredFrame, &rectPoints)){ - return 1; - } - cv::destroyAllWindows(); - - - // must be called before setupCroppingMask - setupAdjustMatrix(rectPoints, center); - - setupCroppingMask(rectPoints); - - return 0; -} - - -void SandboxSetup::defaultCaptureBlueScreen(int delay){ - - // Blue screen - char windowName[] = "BlueScreen"; - initWindowsFullScreen(windowName); - cv::Mat frameBeamer(cv::Size(beamer.getWidth(), beamer.getHeight()), CV_8UC3, cv::Scalar(255, 0, 0)); - cv::imshow(windowName, frameBeamer); - delay = (delay==0)? 1 : delay; - cv::waitKey(delay); - - // Take picture - camera.capture(); - cv::destroyAllWindows(); + cv::Point p = projection->rotatePixel(rectPoints[0]); + camera->setCroppingMask(cv::Rect(p, rectSize)); // croppingMask } @@ -150,9 +83,3 @@ void SandboxSetup::defaultCaptureBlueScreen(int delay){ double SandboxSetup::toDegrees(double radians){ return radians * (180.0 / M_PI); } - - -void SandboxSetup::initWindowsFullScreen(char *windowName){ - cv::namedWindow(windowName, CV_WINDOW_NORMAL); - cv::setWindowProperty(windowName, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); -} diff --git a/src/tools/borderedit.cpp b/src/tools/borderedit.cpp deleted file mode 100644 index ae54b2249f840c23ec587ed8662cd265d99fd365..0000000000000000000000000000000000000000 --- a/src/tools/borderedit.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "../../inc/borderedit.h" - - -cv::Mat BorderEdit::frameImage; - - -int BorderEdit::edit(cv::Mat frame, std::vector<cv::Point> *posSandbox){ - - cv::namedWindow(wndname, CV_WINDOW_AUTOSIZE); - frame.copyTo(frameImage); - cv::setMouseCallback(wndname, BorderEdit::mouseHandler, (void *)posSandbox); - BorderEdit::drawSquare(&posSandbox->at(0), (int)posSandbox->size()); - char keyCode = cv::waitKey(0); - if (keyCode == ESCAPE_CHAR){ - return 1; - } - return 0; -} - - -void BorderEdit::mouseHandler(int event, int x, int y, int, void *param){ - - static int selectedPoint = -1; - std::vector<cv::Point> &posSandbox = *((std::vector<cv::Point> *)param); - switch (event) - { - case CV_EVENT_LBUTTONDOWN: //left button press - selectedPoint = BorderEdit::findPoints(x, y, posSandbox); - break; - - case CV_EVENT_LBUTTONUP: //left mouse button release - if (selectedPoint != -1) - selectedPoint = -1; - break; - - case CV_EVENT_MOUSEMOVE: - /* draw a rectangle*/ - if (selectedPoint != -1) - { - posSandbox[selectedPoint].x = x; - posSandbox[selectedPoint].y = y; - BorderEdit::drawSquare(&posSandbox[0], (int)posSandbox.size()); - //Rect r = boundingRect(posSandbox); - //double f = (double)r.width / (double)r.height; - //cout << 4.0 / 3.0 << " == " << f << endl; - } - break; - } -} - - -void BorderEdit::drawSquare(cv::Point *p, int n){ - - cv::Mat imageCopy = frameImage.clone(); - polylines(imageCopy, &p, &n, 1, true, cv::Scalar(0, 255, 0), 1, cv::LINE_AA); - imshow(wndname, imageCopy); -} - - -int BorderEdit::findPoints(int x, int y, std::vector<cv::Point> &posSandbox){ - - for (int i = 0; i < (int)posSandbox.size(); i++) - { - //check if the point is clicked - if ((x >= (posSandbox[i].x - margeClick)) && (x <= (posSandbox[i].x + margeClick)) && (y >= (posSandbox[i].y - margeClick)) && (y <= (posSandbox[i].y + margeClick))) - return i; - } - return -1; //not found -} - diff --git a/src/tools/sandboxConfig.cpp b/src/tools/sandboxConfig.cpp index c75c292d14da82a49228bbbe7ac30128ce3affe5..001a6337f21260e2ac7250de6331de56609e4fd1 100644 --- a/src/tools/sandboxConfig.cpp +++ b/src/tools/sandboxConfig.cpp @@ -144,7 +144,7 @@ int SandboxConfig::saveFrameProcessProfil(char *path, FrameProcessProfil profil) -int SandboxConfig::loadAdjustingMatrixFrom(char *path, BeamerProjection *projection){ +int SandboxConfig::loadAdjustingMatrixFrom(char *path, Projection *projection){ YAML::Node config; @@ -190,7 +190,7 @@ int SandboxConfig::loadAdjustingMatrixFrom(char *path, BeamerProjection *project } -int SandboxConfig::loadDistanceToSandboxTop(char *path, BeamerProjection *projection){ +int SandboxConfig::loadDistanceToSandboxTop(char *path, Projection *projection){ YAML::Node config;