Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature enhancement: PnP algorithm for pose Matrix calculation and other functions improves #23

Merged
merged 35 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c22785c
creating WebARKitPattern struct see #21
kalwalt Nov 1, 2023
e91098e
using push_back to avoid an Seg fault
kalwalt Nov 1, 2023
5e2d37b
getPoseMatrix function and improved computePose
kalwalt Nov 2, 2023
0647381
trying to find the root of the pose matrix issue
kalwalt Nov 3, 2023
d383ac9
cleaning the code
kalwalt Nov 4, 2023
40017fc
The issue arise the wrong camera matrix data
kalwalt Nov 4, 2023
d13feef
this seems to be correct!
kalwalt Nov 4, 2023
bfcebc9
improved classes and features
kalwalt Nov 4, 2023
684d9c6
new WebARKitGL collection of GL functions
kalwalt Nov 5, 2023
809471e
fix for wrong cv headers
kalwalt Nov 5, 2023
e3997cb
values and params should be double
kalwalt Nov 6, 2023
ad15a7f
make GL mfunctions part of ebarkit namespace
kalwalt Nov 6, 2023
d01a0a1
revert to old syntax pattern
kalwalt Nov 6, 2023
0d74031
new cameraProjectionMatrix with gtest
kalwalt Nov 6, 2023
dce5a2a
getCameraProjectioMatrix with gtest
kalwalt Nov 6, 2023
ce4fe4d
fix for: Test issue: impossible to load a jpeg image with imread (Ope…
kalwalt Nov 9, 2023
fe46f86
add to initTracker colorSpace option to let use other colors channels
kalwalt Nov 10, 2023
f6dfcbc
pinball image is 3 channels add support for this type to initTracker
kalwalt Nov 10, 2023
218eda8
processFrameData now may process also RGB data input
kalwalt Nov 10, 2023
022b559
new convert2Grayscale function to avoid repetitions
kalwalt Nov 11, 2023
47e102f
oveloaded convert2Grayscale function and other fixes
kalwalt Nov 13, 2023
8cc8572
testing matrix and cameraProjmatrix
kalwalt Nov 16, 2023
a68af51
sphere is displayed but don't move
kalwalt Nov 18, 2023
bd21912
_isDetected = false should be outside clear_output()
kalwalt Nov 18, 2023
2dff6c4
initTracker as templatized function
kalwalt Nov 18, 2023
04a5bb2
Fix swapImage and other related code
kalwalt Dec 5, 2023
e3cdf48
small improves
kalwalt Mar 3, 2024
63946b4
fix for MIN_NUM_MATCHES failed test
kalwalt Mar 4, 2024
e754f20
move marker dected message inside processFrame
kalwalt Mar 8, 2024
e9c7fb1
new extractFeatures method
kalwalt Mar 15, 2024
afac6e7
new boolean option enablleBlur
kalwalt Mar 20, 2024
6043029
more modularity in the C++ code
kalwalt Mar 31, 2024
16dd102
fix for getMatches function
kalwalt Mar 31, 2024
c78ef5c
fix for numMatches
kalwalt Mar 31, 2024
ef898c4
fix for numMatches format display
kalwalt Mar 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions WebARKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ if(${EMSCRIPTEN_COMP} EQUAL 1)
message("Fetching opencv for emscripten compilation from webarkit/opencv-em ...")
FetchContent_Declare(
build_opencv
URL https://github.com/webarkit/opencv-em/releases/download/0.1.3/opencv-js-4.7.0-emcc-3.1.26.zip
URL https://github.com/webarkit/opencv-em/releases/download/0.1.4/opencv-js-4.7.0-emcc-3.1.26.zip
)
else()
message("Fetching opencv from webarkit/opencv-em ...")
FetchContent_Declare(
build_opencv
URL https://github.com/webarkit/opencv-em/releases/download/0.1.3/opencv-4.7.0.zip
URL https://github.com/webarkit/opencv-em/releases/download/0.1.4/opencv-4.7.0.zip
)
endif()

Expand All @@ -35,15 +35,19 @@ ${PARENT_DIR}/WebARKitTrackers/WebARKitOpticalTracking/include/WebARKitTrackers/
${PARENT_DIR}/WebARKitTrackers/WebARKitOpticalTracking/include/WebARKitTrackers/WebARKitOpticalTracking/WebARKitUtils.h
${PARENT_DIR}/include/WebARKitCamera.h
${PARENT_DIR}/include/WebARKitLog.h
${PARENT_DIR}/include/WebARKitGL.h
${PARENT_DIR}/include/WebARKitManager.h
${PARENT_DIR}/include/WebARKitPattern.h
)

set(SOURCE
${PARENT_DIR}/WebARKitTrackers/WebARKitOpticalTracking/WebARKitConfig.cpp
${PARENT_DIR}/WebARKitTrackers/WebARKitOpticalTracking/WebARKitTracker.cpp
${PARENT_DIR}/WebARKitCamera.cpp
${PARENT_DIR}/WebARKitLog.cpp
${PARENT_DIR}/WebARKitGL.cpp
${PARENT_DIR}/WebARKitManager.cpp
${PARENT_DIR}/WebARKitPattern.cpp
)

add_library(
Expand All @@ -65,4 +69,9 @@ target_include_directories(WebARKitLib PRIVATE
"${build_opencv_SOURCE_DIR}/libs/opencv/modules/imgproc/include"
"${build_opencv_SOURCE_DIR}/libs/opencv/modules/video/include"
"${build_opencv_SOURCE_DIR}/libs/opencv_contrib/modules/xfeatures2d/include"
)
)

target_link_libraries(WebARKitLib
jpeg
"${build_opencv_SOURCE_DIR}/3rdparty/lib/liblibopenjp2.a"
)
81 changes: 81 additions & 0 deletions WebARKit/WebARKitGL.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <WebARKitGL.h>

namespace webarkit {

void arglCameraViewRHf(float para[3][4], float m_modelview[16], const float scale) {
m_modelview[0 + 0 * 4] = para[0][0]; // R1C1
m_modelview[0 + 1 * 4] = para[0][1]; // R1C2
m_modelview[0 + 2 * 4] = para[0][2];
m_modelview[0 + 3 * 4] = para[0][3];
m_modelview[1 + 0 * 4] = -para[1][0]; // R2
m_modelview[1 + 1 * 4] = -para[1][1];
m_modelview[1 + 2 * 4] = -para[1][2];
m_modelview[1 + 3 * 4] = -para[1][3];
m_modelview[2 + 0 * 4] = -para[2][0]; // R3
m_modelview[2 + 1 * 4] = -para[2][1];
m_modelview[2 + 2 * 4] = -para[2][2];
m_modelview[2 + 3 * 4] = -para[2][3];
m_modelview[3 + 0 * 4] = 0.0f;
m_modelview[3 + 1 * 4] = 0.0f;
m_modelview[3 + 2 * 4] = 0.0f;
m_modelview[3 + 3 * 4] = 1.0f;
if (scale != 0.0f) {
m_modelview[12] *= scale;
m_modelview[13] *= scale;
m_modelview[14] *= scale;
}
}

void arglCameraViewRHf(cv::Mat para, std::array<double, 16>& m_modelview, const double scale) {
m_modelview[0 + 0 * 4] = para.at<double>(0, 0); // R1C1
m_modelview[0 + 1 * 4] = para.at<double>(0, 1); // R1C2
m_modelview[0 + 2 * 4] = para.at<double>(0, 2);
m_modelview[0 + 3 * 4] = para.at<double>(0, 3);
m_modelview[1 + 0 * 4] = -para.at<double>(1, 0); // R2
m_modelview[1 + 1 * 4] = -para.at<double>(1, 1);
m_modelview[1 + 2 * 4] = -para.at<double>(1, 2);
m_modelview[1 + 3 * 4] = -para.at<double>(1, 3);
m_modelview[2 + 0 * 4] = -para.at<double>(2, 0); // R3
m_modelview[2 + 1 * 4] = -para.at<double>(2, 1);
m_modelview[2 + 2 * 4] = -para.at<double>(2, 2);
m_modelview[2 + 3 * 4] = -para.at<double>(2, 3);
m_modelview[3 + 0 * 4] = 0.0f;
m_modelview[3 + 1 * 4] = 0.0f;
m_modelview[3 + 2 * 4] = 0.0f;
m_modelview[3 + 3 * 4] = 1.0f;
if (scale != 0.0f) {
m_modelview[12] *= scale;
m_modelview[13] *= scale;
m_modelview[14] *= scale;
}
}

void cameraProjectionMatrix(const std::array<double, 9>& calibration, double nearPlane, double farPlane, int screenWidth, int screenHeight, std::array<double, 16>& projectionMatrix)
{
// Camera parameters
double f_x = calibration.at(0); // Focal length in x axis
double f_y = calibration.at(4); // Focal length in y axis (usually the same?)
double c_x = calibration.at(2); // Camera primary point x
double c_y = calibration.at(5); // Camera primary point y

projectionMatrix[0] = -2.0f * f_x / screenWidth;
projectionMatrix[1] = 0.0f;
projectionMatrix[2] = 0.0f;
projectionMatrix[3] = 0.0f;

projectionMatrix[4] = 0.0f;
projectionMatrix[5] = 2.0f * f_y / screenHeight;
projectionMatrix[6] = 0.0f;
projectionMatrix[7] = 0.0f;

projectionMatrix[8] = 2.0f * c_x / screenWidth - 1.0f;
projectionMatrix[9] = 2.0f * c_y / screenHeight - 1.0f;
projectionMatrix[10] = -( farPlane + nearPlane) / ( farPlane - nearPlane );
projectionMatrix[11] = -1.0f;

projectionMatrix[12] = 0.0f;
projectionMatrix[13] = 0.0f;
projectionMatrix[14] = -2.0f * farPlane * nearPlane / ( farPlane - nearPlane );
projectionMatrix[15] = 0.0f;
}
} // namespace webarkit
38 changes: 34 additions & 4 deletions WebARKit/WebARKitManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,25 @@ bool WebARKitManager::initialiseBase(webarkit::TRACKER_TYPE trackerType, int fra
return true;
}

bool WebARKitManager::initTracker(uchar* refData, size_t refCols, size_t refRows) {
bool WebARKitManager::initTracker(cv::Mat refData, size_t refCols, size_t refRows, ColorSpace colorSpace) {
WEBARKIT_LOGd("WebARKitManager::initTracker(...)\n");
if (refData.empty() || refCols <= 0 || refRows <= 0) {
WEBARKIT_LOGe("Error initialising tracker.\n");
return false;
}
m_tracker->initTracker(refData, refCols, refRows, colorSpace);
state = WAITING_FOR_VIDEO;
WEBARKIT_LOGd("WebARKitManager::initTracker() done.\n");
return true;
}

bool WebARKitManager::initTracker(uchar* refData, size_t refCols, size_t refRows, ColorSpace colorSpace) {
WEBARKIT_LOGd("WebARKitManager::initTracker(...)\n");
if (!refData || refCols <= 0 || refRows <= 0) {
WEBARKIT_LOGe("Error initialising tracker.\n");
return false;
}
m_tracker->initTracker(refData, refCols, refRows);
m_tracker->initTracker(refData, refCols, refRows, colorSpace);
state = WAITING_FOR_VIDEO;
WEBARKIT_LOGd("WebARKitManager::initTracker() done.\n");
return true;
Expand All @@ -67,7 +79,7 @@ bool WebARKitManager::shutdown() {
return true;
};

void WebARKitManager::processFrameData(uchar* frameData, size_t frameCols, size_t frameRows, ColorSpace colorSpace) {
void WebARKitManager::processFrameData(uchar* frameData, size_t frameCols, size_t frameRows, ColorSpace colorSpace, bool enableBlur) {
WEBARKIT_LOGd("WebARKitManager::processFrameData(...)\n");
if (state < WAITING_FOR_VIDEO) {
WEBARKIT_LOGe("processFrameData called without init the tracker. Call first initTracker.\n");
Expand All @@ -76,7 +88,7 @@ void WebARKitManager::processFrameData(uchar* frameData, size_t frameCols, size_
WEBARKIT_LOGe("Error initialising processFrameData.\n");
//return false;
}
m_tracker->processFrameData(frameData, frameCols, frameRows, colorSpace);
m_tracker->processFrameData(frameData, frameCols, frameRows, colorSpace, enableBlur);
state = DETECTION_RUNNING;
WEBARKIT_LOGd("WebARKitManager::processFrameData() done\n");
}
Expand All @@ -85,6 +97,24 @@ std::vector<double> WebARKitManager::getOutputData() {
return m_tracker->getOutputData();
};

cv::Mat WebARKitManager::getPoseMatrix() {
return m_tracker->getPoseMatrix();
}

cv::Mat WebARKitManager::getGLViewMatrix() {
return m_tracker->getGLViewMatrix();
}

std::array<double, 16> WebARKitManager::getTransformationMatrix() {
std::array<double, 16> transformationMatrix;
webarkit::arglCameraViewRHf(m_tracker->getPoseMatrix(), transformationMatrix, 1.0f);
return transformationMatrix;
}

std::array<double, 16> WebARKitManager::getCameraProjectionMatrix() {
return m_tracker->getCameraProjectionMatrix();
}

bool WebARKitManager::isValid() {
return m_tracker->isValid();
}
Expand Down
58 changes: 58 additions & 0 deletions WebARKit/WebARKitPattern.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <WebARKitPattern.h>
#include <opencv2/calib3d.hpp>

WebARKitPatternTrackingInfo::WebARKitPatternTrackingInfo() {
pose3d = cv::Mat::zeros(4, 4, CV_64FC1);
glViewMatrix = cv::Mat::zeros(4, 4, CV_64F);
m_scale = 1.0f;
}

void WebARKitPatternTrackingInfo::computePose(std::vector<cv::Point3f>& treeDPoints,
std::vector<cv::Point2f>& imgPoints, const cv::Matx33f& caMatrix,
const cv::Mat& distCoeffs) {
//cv::Mat rvec = cv::Mat::zeros(3, 1, CV_64FC1); // output rotation vector
//cv::Mat tvec = cv::Mat::zeros(3, 1, CV_64FC1); // output translation vector
cv::Mat rvec, tvec;

cv::solvePnPRansac(treeDPoints, imgPoints, caMatrix, distCoeffs, rvec, tvec);

cv::Mat rMat;
cv::Rodrigues(rvec, rMat);
//cv::hconcat(rMat, tvec, pose3d);

for (unsigned int row = 0; row < 3; ++row) {
for (unsigned int col = 0; col < 3; ++col) {
pose3d.at<double>(row, col) = rMat.at<double>(row, col);
}
pose3d.at<double>(row, 3) = tvec.at<double>(row, 0);
}
pose3d.at<double>(3, 3) = 1.0f;

invertPose();
}

void WebARKitPatternTrackingInfo::computeGLviewMatrix() {
cv::transpose(pose3d , glViewMatrix);
}

void WebARKitPatternTrackingInfo::invertPose() {

/*cv::Mat invertPose(3, 4, CV_64FC1);
for (auto j = 0; j < 3; j++) {
invertPose.at<double>(j, 0) = pose3d.at<double>(j, 0);
invertPose.at<double>(j, 1) = -pose3d.at<double>(j, 1);
invertPose.at<double>(j, 2) = -pose3d.at<double>(j, 2);
//invertPose.at<double>(j, 3) = pose3d.at<double>(j, 3) * m_scale * 0.001f * 1.64f;
invertPose.at<double>(j, 3) = pose3d.at<double>(j, 3);
}*/

cv::Mat cvToGl = cv::Mat::zeros(4, 4, CV_64F);
cvToGl.at<double>(0, 0) = 1.0f;
cvToGl.at<double>(1, 1) = -1.0f; // Invert the y axis
cvToGl.at<double>(2, 2) = -1.0f; // invert the z axis
cvToGl.at<double>(3, 3) = 1.0f;

pose3d = cvToGl * pose3d;

// pose3d = invertPose;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extern const double TEBLID_NN_MATCH_RATIO = 0.8f;
extern const int DEFAULT_MAX_FEATURES = 8000;
extern const int TEBLID_MAX_FEATURES = 10000;
extern const int N = 10;
extern const int MIN_NUM_MATCHES = 50;
extern const int MIN_NUM_MATCHES = 8;
extern const int maxLevel = 3; ///< Maximum number of levels in optical flow image pyramid.
extern const cv::Size winSize(31, 31);
extern const cv::TermCriteria termcrit(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 20, 0.03);
Expand Down
Loading
Loading