Skip to content

Commit

Permalink
Integrated SVM into project; Added precompiled header & modified
Browse files Browse the repository at this point in the history
CMakeLists to automatically use it
  • Loading branch information
sxyu committed Nov 18, 2017
1 parent 361efb7 commit b83d11f
Show file tree
Hide file tree
Showing 35 changed files with 3,844 additions and 1,752 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ project.fragment.lock.json
*.meta
*.obj
*.pch
*.gch
*.pdb
*.pgc
*.pgd
Expand Down
42 changes: 37 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 2.8)

project( OpenARK )

set(CMAKE_CXX_STACK_SIZE "10000000")
Expand All @@ -18,7 +19,8 @@ else()
endif()

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC ON)
set(Boost_USE_STATIC ON)

find_package( PCL REQUIRED )

find_package( OpenCV REQUIRED )
Expand Down Expand Up @@ -71,6 +73,9 @@ set(
Util.cpp
Visualizer.cpp
Converter.cpp
HandFeatureExtractor.cpp
HandClassifier.cpp
libSVM/svm.cpp
)

if(NOT RSSDK_FOUND)
Expand All @@ -89,6 +94,30 @@ endif(NOT PMDSDK_FOUND)

configure_file(Version.h.in ${PROJECT_SOURCE_DIR}/version.h)

macro(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
if(MSVC)
get_filename_component(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
set(PrecompiledBinary "$(IntDir)/${PrecompiledBasename}.pch")
set(Sources ${${SourcesVar}})

if(NOT ${PrecompiledSource} STREQUAL "")
set(Sources ${Sources} main.cpp)
set_source_files_properties(${PrecompiledSource}
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_OUTPUTS "${PrecompiledBinary}")
endif(NOT ${PrecompiledSource} STREQUAL "")

set_source_files_properties(${Sources}
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
OBJECT_DEPENDS "${PrecompiledBinary}")
list(APPEND ${SourcesVar} ${PrecompiledSource})
endif(MSVC)
endmacro(ADD_MSVC_PRECOMPILED_HEADER)

if (MSVC)
ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" SOURCES)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)

add_executable( OpenARK main.cpp ${SOURCES} )
target_link_libraries( OpenARK ${DEPENDENCIES} )
Expand All @@ -106,6 +135,13 @@ if(${BUILD_TESTS})
# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/OpenARK_test)
endif(NOT EXISTS ${PROJECT_SOURCE_DIR}/OpenARK_test)

set(
TEST_SOURCES
OpenARK_test/test.cpp
OpenARK_test/TestCamera.cpp
)

ADD_MSVC_PRECOMPILED_HEADER("../stdafx.h" "" TEST_SOURCES)

add_executable( OpenARK_test OpenARK_test/test.cpp
OpenARK_test/TestCamera.cpp ${SOURCES})
Expand All @@ -116,7 +152,3 @@ endif(${BUILD_TESTS})







2 changes: 2 additions & 0 deletions Calibration.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "stdafx.h"
#include "Calibration.h"
#include "Util.h"


void Calibration::XYZToUnity(DepthCamera& depth_cam, int num_boards, int board_w, int board_h)
Expand Down
13 changes: 1 addition & 12 deletions Calibration.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
#pragma once
//C++ libraries
#include <stdio.h>

// OpenCV Libraries
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/video/tracking.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/features2d/features2d.hpp>

// Eigen Libaries
#include <Eigen/SVD>
#include "stdafx.h"

// OpenARK Libraries
#include "Visualizer.h"
Expand Down
2 changes: 1 addition & 1 deletion Converter.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "stdafx.h"
#include "Converter.h"


/***
Returns the next frame if next frame is recorded
Returns the previous frame if next frame is not recorded
Expand Down
6 changes: 3 additions & 3 deletions Converter.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma once

#include "stdafx.h"

//Intel RealSense 3D SDK libraries
#include "RealSense/SampleReader.h"
#include "RealSense/Session.h"

//OpenCV libraries
#include <opencv2/opencv.hpp>

/**
* Class for converting Intel RealSense images to OpenCV image format
*/
Expand Down
123 changes: 41 additions & 82 deletions DepthCamera.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "stdafx.h"
#include "DepthCamera.h"
#include <iostream>

DepthCamera::~DepthCamera()
{
Expand All @@ -20,28 +20,33 @@ void DepthCamera::computeClusters(double max_distance, double min_size, int floo
cv::Mat depthMap;

cv::Mat eKernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
// size 1x2 works well (by trial and error...)
cv::Mat dKernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(1, 2));

cv::erode(xyzMap, depthMap, eKernel);
depthMap = xyzMap.clone();

//cv::medianBlur(xyzMap, depthMap, 3);

cv::Mat mask = cv::Mat::zeros(depthMap.rows, depthMap.cols, depthMap.type());
std::vector<cv::Point> pts(depthMap.rows * depthMap.cols + 1);

for (auto r = depthMap.rows - 1; r >= 0; r-=floodfill_interval)
for (int r = depthMap.rows - 1; r >= 0; r-=floodfill_interval)
{
for (auto c = 0; c < depthMap.cols; c+=floodfill_interval)
cv::Vec3f * ptr = depthMap.ptr<cv::Vec3f>(r);
for (int c = 0; c < depthMap.cols; c+=floodfill_interval)
{
if (depthMap.at<cv::Vec3f>(r, c)[2] > 0.2)
if (ptr[c][2] > 0.2)
{
mask.setTo(cv::Scalar(0, 0, 0));
int pts = floodFill(c, r, depthMap, mask, max_distance);
int comp_size = floodFill(c, r, depthMap, mask, max_distance, &pts);

if (pts > min_size)
if (comp_size > min_size)
{
//cv::medianBlur(mask, mask, 3);
cv::dilate(mask, mask, dKernel);
clusters.push_back(mask.clone());
cv::Mat cluster;
cv::dilate(mask, cluster, dKernel);
clusters.push_back(cluster);
}

for (int i = 0; i < comp_size; ++i) {
mask.at<cv::Vec3f>(pts[i]) = cv::Vec3f(0, 0, 0);
}
}
}
Expand All @@ -51,40 +56,41 @@ void DepthCamera::computeClusters(double max_distance, double min_size, int floo
/***
Performs floodfill on depthMap
***/
int DepthCamera::floodFill(int seed_x, int seed_y, cv::Mat& depthMap, cv::Mat& mask, double max_distance)
int DepthCamera::floodFill(int seed_x, int seed_y, cv::Mat& depthMap, cv::Mat& mask, double max_distance, std::vector <cv::Point> * output_points)
{
static std::vector<cv::Point> stk;

if (stk.size() <= depthMap.rows * depthMap.cols) {
// permanently allocate the space for a stack
stk.resize(depthMap.rows * depthMap.cols + 1);
}

stk[0] = cv::Point(seed_x, seed_y);
int stkPtr = 1;

int total = 0;
int stkPtr = 1, total = 0;

while (stkPtr) {
int x = stk[--stkPtr].x, y = stk[stkPtr].y;

if (x < 0 || x >= depthMap.cols || y < 0 || y >= depthMap.rows || depthMap.at<cv::Vec3f>(y, x)[2] < 0.1)
continue;

total += (depthMap.at<cv::Vec3f>(y, x)[2] > 0.2);

mask.at<cv::Vec3f>(y, x) = depthMap.at<cv::Vec3f>(y, x);
depthMap.at<cv::Vec3f>(y, x) = cv::Vec3f(0, 0, 0);

cv::Point nxtPoints[4] = { cv::Point(x + 1, y), cv::Point(x - 1, y), cv::Point(x, y + 1), cv::Point(x, y - 1) };
// set output point
if (output_points) (*output_points)[total++] = cv::Point(x, y);

cv::Point nxtPoints[4] =
{ cv::Point(x + 1, y), cv::Point(x - 1, y), cv::Point(x, y + 1), cv::Point(x, y - 1) };

for (int i = 0; i < sizeof nxtPoints / sizeof(nxtPoints[0]); ++i) {
cv::Point adjPt = nxtPoints[i];

if (adjPt.x < 0 || adjPt.x >= depthMap.cols || adjPt.y < 0 || adjPt.y >= depthMap.rows ||
depthMap.at<cv::Vec3f>(adjPt.y, adjPt.x)[2] == 0)
depthMap.at<cv::Vec3f>(adjPt.y, adjPt.x)[2] < 0.1)
continue;

double dist = Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x),
double dist = Util::euclideanDistance3D(depthMap.at<cv::Vec3f>(y, x),
depthMap.at<cv::Vec3f>(adjPt.y, adjPt.x));

if (dist < max_distance) {
Expand All @@ -96,84 +102,37 @@ int DepthCamera::floodFill(int seed_x, int seed_y, cv::Mat& depthMap, cv::Mat& m
return total;
}

///***
//Check whether candidate point is close enough to neighboring points
//***/
//bool DepthCamera::closeEnough(int x, int y, cv::Mat& depthMap, int num_neighbors, double max_distance)
//{
// auto num_close = 0;
// if (x - 1 < 0 || depthMap.at<cv::Vec3f>(y, x - 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x - 1)) < max_distance) {
// num_close++;
// }
// if (x + 1 >= depthMap.cols || depthMap.at<cv::Vec3f>(y, x + 1)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y, x + 1)) < max_distance) {
// num_close++;
// }
// if (y - 1 < 0 || depthMap.at<cv::Vec3f>(y - 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y - 1, x)) < max_distance) {
// num_close++;
// }
// if (y + 1 >= depthMap.rows || depthMap.at<cv::Vec3f>(y + 1, x)[2] == 0 || Util::euclidianDistance3D(depthMap.at<cv::Vec3f>(y, x), depthMap.at<cv::Vec3f>(y + 1, x)) < max_distance) {
// num_close++;
// }
//
// if (num_close >= num_neighbors) {
// return true;
// }
//
// return false;
//}

/***
Remove noise on zMap and xyzMap based on INVALID_FLAG_VALUE and CONFIDENCE_THRESHOLD
***/
void DepthCamera::removeNoise()
{

for (auto y = 0; y < xyzMap.rows; y++)
int nonZero = 0;
for (int r = 0; r < xyzMap.rows; ++r)
{
for (auto x = 0; x < xyzMap.cols; x++)
cv::Vec3f * ptr = xyzMap.ptr<cv::Vec3f>(r);
float * ampptr = ampMap.ptr<float>(r);

for (int c = 0; c < xyzMap.cols; ++c)
{
if (ampMap.data != nullptr)
{
if (xyzMap.at<cv::Vec3f>(y, x)[2] > 0.9f || ampMap.at<float>(y, x) < CONFIDENCE_THRESHHOLD)
{
xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
}
}
else
{
if (xyzMap.at<cv::Vec3f>(y, x)[2] > 0.9f)
{
xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
if (ptr[c][2] > 0.0f) {
++nonZero;
if (ptr[c][2] > 0.9f && (ampMap.data == nullptr || ampptr[c] < CONFIDENCE_THRESHHOLD)) {
ptr[c][0] = ptr[c][1] = ptr[c][2] = 0.0f;
}
}
}
}

cv::Mat channels[3];
cv::split(xyzMap, channels);

if (static_cast<float>(cv::countNonZero(channels[2])) / (xyzMap.rows*xyzMap.cols) > 0.5)
{
badInput = true;
}
else {
badInput = false;
}
badInput = (static_cast<float>(nonZero) / (xyzMap.rows*xyzMap.cols) > 0.9);
}

void DepthCamera::removePoints(std::vector<cv::Point2i> points)
{
for (auto i = 0; i < points.size(); i++)
for (int i = 0; i < points.size(); i++)
{
auto x = points[i].x;
auto y = points[i].y;
xyzMap.at<cv::Vec3f>(y, x)[0] = 0;
xyzMap.at<cv::Vec3f>(y, x)[1] = 0;
xyzMap.at<cv::Vec3f>(y, x)[2] = 0;
int x = points[i].x, y = points[i].y;
xyzMap.at<cv::Vec3f>(y, x) = cv::Vec3f(0, 0, 0);
}
}

Expand Down
4 changes: 3 additions & 1 deletion DepthCamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,11 @@ class DepthCamera
* @param [in] zMap the xyzMap point cloud
* @param [out] mask the resulting region of the floodfill
* @param max_distance the maximum euclidean distance allowed between neighbors
* @param output_points optionally, pointer to a vector in which we will
store the points in the component. This vector should be AT LEAST the size of the xyz map
* @returns number of points in component
*/
static int floodFill(int seed_x, int seed_y, cv::Mat& zMap, cv::Mat& mask, double max_distance);
static int floodFill(int seed_x, int seed_y, cv::Mat& zMap, cv::Mat& mask, double max_distance, std::vector <cv::Point> * output_points = nullptr);

///**
// * Analyze the candidate point with its neighbors to determine whether they belong to the same cluster.
Expand Down
Loading

0 comments on commit b83d11f

Please sign in to comment.