From 66160b306237c41a1d5a6dd8673254fbbe38df32 Mon Sep 17 00:00:00 2001 From: Scott Klum Date: Tue, 2 Jul 2013 17:11:37 -0400 Subject: [PATCH] Procrustes transform: R matrix calculated --- openbr/plugins/regions.cpp | 5 ++++- openbr/plugins/stasm4.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/openbr/plugins/regions.cpp b/openbr/plugins/regions.cpp index b6bba45..791f2e5 100644 --- a/openbr/plugins/regions.cpp +++ b/openbr/plugins/regions.cpp @@ -201,9 +201,11 @@ class RectFromPointsTransform : public UntrainableTransform Q_PROPERTY(QList indices READ get_indices WRITE set_indices RESET reset_indices STORED false) Q_PROPERTY(double padding READ get_padding WRITE set_padding RESET reset_padding STORED false) Q_PROPERTY(double aspectRatio READ get_aspectRatio WRITE set_aspectRatio RESET reset_aspectRatio STORED false) + Q_PROPERTY(bool crop READ get_crop WRITE set_crop RESET reset_crop STORED false); BR_PROPERTY(QList, indices, QList()) BR_PROPERTY(double, padding, 0) BR_PROPERTY(double, aspectRatio, 1.0) + BR_PROPERTY(bool, crop, true) void project(const Template &src, Template &dst) const { @@ -236,7 +238,8 @@ class RectFromPointsTransform : public UntrainableTransform double deltaHeight = width/aspectRatio - height; height += deltaHeight; - dst.m() = src.m()(Rect(std::max(0.0, minX - deltaWidth/2.0), std::max(0.0, minY - deltaHeight/2.0), std::min((double)src.m().cols, width), std::min((double)src.m().rows, height))); + if (crop) dst.m() = src.m()(Rect(std::max(0.0, minX - deltaWidth/2.0), std::max(0.0, minY - deltaHeight/2.0), std::min((double)src.m().cols, width), std::min((double)src.m().rows, height))); + else dst.m() = src.m(); } }; diff --git a/openbr/plugins/stasm4.cpp b/openbr/plugins/stasm4.cpp index d4c5685..cb184c2 100644 --- a/openbr/plugins/stasm4.cpp +++ b/openbr/plugins/stasm4.cpp @@ -1,7 +1,11 @@ #include #include -#include +#include #include "openbr_internal.h" +#include "openbr/core/qtutils.h" +#include "openbr/core/opencvutils.h" +#include +#include using namespace cv; @@ -79,6 +83,109 @@ class StasmTransform : public UntrainableTransform BR_REGISTER(Transform, StasmTransform) +#include + +/*! + * \ingroup transforms + * \brief Wraps STASM key point detector + * \author Scott Klum \cite sklum + */ +class ProcrustesTransform : public Transform +{ + Q_OBJECT + + Q_PROPERTY(QString principalShapePath READ get_principalShapePath WRITE set_principalShapePath RESET reset_principalShapePath STORED false) + BR_PROPERTY(QString, principalShapePath, QString()) + + Eigen::MatrixXf meanShape; + + void train(const TemplateList &data) + { + QList< QList > normalizedPoints; + + // Normalize all sets of points + foreach (br::Template datum, data) { + QList points = OpenCVUtils::toPoints(datum.file.points()); + + if (points.empty()) { + continue; + } + + cv::Scalar mean = cv::mean(points.toVector().toStdVector()); + for (int i = 0; i < points.size(); i++) { + points[i].x -= mean[0]; + points[i].y -= mean[1]; + } + + float norm = cv::norm(points.toVector().toStdVector()); + for (int i = 0; i < points.size(); i++) { + points[i].x /= norm; + points[i].y /= norm; + } + + normalizedPoints.append(points); + } + + // Determine mean shape + Eigen::MatrixXf shapeTest(normalizedPoints[0].size(), 2); + + cv::Mat shapeBuffer(normalizedPoints[0].size(), 2, CV_32F); + + for (int i = 0; i < normalizedPoints[0].size(); i++) { + + double x = 0; + double y = 0; + + for (int j = 0; j < normalizedPoints.size(); j++) { + x += normalizedPoints[j][i].x; + y += normalizedPoints[j][i].y; + } + + x /= (double)normalizedPoints.size(); + y /= (double)normalizedPoints.size(); + + shapeBuffer.at(i,0) = x; + shapeBuffer.at(i,1) = y; + + shapeTest(i,0) = x; + shapeTest(i,1) = y; + } + + meanShape = shapeTest; + } + + void project(const Template &src, Template &dst) const + { + QList points = src.file.points(); + + cv::Scalar mean = cv::mean(OpenCVUtils::toPoints(points).toVector().toStdVector()); + + for (int i = 0; i < points.size(); i++) points[i] -= QPointF(mean[0],mean[1]); + + float norm = cv::norm(OpenCVUtils::toPoints(points).toVector().toStdVector()); + + Eigen::MatrixXf srcPoints(points.size(), 2); + for (int i = 0; i < points.size(); i++) { + srcPoints(i,0) = points[i].x()/norm; + srcPoints(i,1) = points[i].y()/norm; + } + + Eigen::JacobiSVD svd(srcPoints.transpose()*meanShape, Eigen::ComputeThinU | Eigen::ComputeThinV); + + Eigen::MatrixXf R = svd.matrixU()*svd.matrixV().transpose(); + + std::cout << R(1,0) << std::endl; + // Determine transformation matrix + + // Apply transformation matrix + //dst.file.setPoints(meanShape);*/ + dst.m() = src.m(); + } + +}; + +BR_REGISTER(Transform, ProcrustesTransform) + } // namespace br #include "stasm4.moc" -- libgit2 0.21.4