Commit e214a85a7017d14f186e81fe3738aa11d9cef2af
1 parent
faf5f230
remove delaunay
Showing
1 changed file
with
0 additions
and
172 deletions
openbr/plugins/metadata/delaunay.cpp deleted
| 1 | -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
| 2 | - * Copyright 2012 The MITRE Corporation * | ||
| 3 | - * * | ||
| 4 | - * Licensed under the Apache License, Version 2.0 (the "License"); * | ||
| 5 | - * you may not use this file except in compliance with the License. * | ||
| 6 | - * You may obtain a copy of the License at * | ||
| 7 | - * * | ||
| 8 | - * http://www.apache.org/licenses/LICENSE-2.0 * | ||
| 9 | - * * | ||
| 10 | - * Unless required by applicable law or agreed to in writing, software * | ||
| 11 | - * distributed under the License is distributed on an "AS IS" BASIS, * | ||
| 12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * | ||
| 13 | - * See the License for the specific language governing permissions and * | ||
| 14 | - * limitations under the License. * | ||
| 15 | - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
| 16 | - | ||
| 17 | -#include <opencv2/imgproc/imgproc.hpp> | ||
| 18 | -#include <Eigen/Dense> | ||
| 19 | - | ||
| 20 | -#include <openbr/plugins/openbr_internal.h> | ||
| 21 | -#include <openbr/core/opencvutils.h> | ||
| 22 | - | ||
| 23 | -using namespace cv; | ||
| 24 | - | ||
| 25 | -namespace br | ||
| 26 | -{ | ||
| 27 | - | ||
| 28 | -/*! | ||
| 29 | - * \ingroup transforms | ||
| 30 | - * \brief Creates a Delaunay triangulation based on a set of points | ||
| 31 | - * \author Scott Klum \cite sklum | ||
| 32 | - */ | ||
| 33 | -class DelaunayTransform : public UntrainableTransform | ||
| 34 | -{ | ||
| 35 | - Q_OBJECT | ||
| 36 | - | ||
| 37 | - Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) | ||
| 38 | - Q_PROPERTY(bool warp READ get_warp WRITE set_warp RESET reset_warp STORED false) | ||
| 39 | - BR_PROPERTY(float, scaleFactor, 1) | ||
| 40 | - BR_PROPERTY(bool, warp, true) | ||
| 41 | - | ||
| 42 | - void project(const Template &src, Template &dst) const | ||
| 43 | - { | ||
| 44 | - QList<QPointF> points = src.file.points(); | ||
| 45 | - QList<QRectF> rects = src.file.rects(); | ||
| 46 | - | ||
| 47 | - if (points.empty() || rects.empty()) { | ||
| 48 | - dst = src; | ||
| 49 | - if (Globals->verbose) qWarning("Delauney triangulation failed because points or rects are empty."); | ||
| 50 | - return; | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - int cols = src.m().cols; | ||
| 54 | - int rows = src.m().rows; | ||
| 55 | - | ||
| 56 | - // Assume rect appended last was bounding box | ||
| 57 | - points.append(rects.last().topLeft()); | ||
| 58 | - points.append(rects.last().topRight()); | ||
| 59 | - points.append(rects.last().bottomLeft()); | ||
| 60 | - points.append(rects.last().bottomRight()); | ||
| 61 | - | ||
| 62 | - Subdiv2D subdiv(Rect(0,0,cols,rows)); | ||
| 63 | - // Make sure points are valid for Subdiv2D | ||
| 64 | - // TODO: Modify points to make them valid | ||
| 65 | - for (int i = 0; i < points.size(); i++) { | ||
| 66 | - if (points[i].x() < 0 || points[i].y() < 0 || points[i].y() >= rows || points[i].x() >= cols) { | ||
| 67 | - dst = src; | ||
| 68 | - if (Globals->verbose) qWarning("Delauney triangulation failed because points lie on boundary."); | ||
| 69 | - return; | ||
| 70 | - } | ||
| 71 | - subdiv.insert(OpenCVUtils::toPoint(points[i])); | ||
| 72 | - } | ||
| 73 | - | ||
| 74 | - std::vector<Vec6f> triangleList; | ||
| 75 | - subdiv.getTriangleList(triangleList); | ||
| 76 | - | ||
| 77 | - QList<QPointF> validTriangles; | ||
| 78 | - | ||
| 79 | - for (size_t i = 0; i < triangleList.size(); i++) { | ||
| 80 | - // Check the triangle to make sure it's falls within the matrix | ||
| 81 | - bool valid = true; | ||
| 82 | - | ||
| 83 | - QList<QPointF> vertices; | ||
| 84 | - vertices.append(QPointF(triangleList[i][0],triangleList[i][1])); | ||
| 85 | - vertices.append(QPointF(triangleList[i][2],triangleList[i][3])); | ||
| 86 | - vertices.append(QPointF(triangleList[i][4],triangleList[i][5])); | ||
| 87 | - for (int j = 0; j < 3; j++) if (vertices[j].x() > cols || vertices[j].y() > rows || vertices[j].x() < 0 || vertices[j].y() < 0) valid = false; | ||
| 88 | - | ||
| 89 | - if (valid) validTriangles.append(vertices); | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - if (warp) { | ||
| 93 | - dst.m() = Mat::zeros(rows,cols,src.m().type()); | ||
| 94 | - | ||
| 95 | - QList<float> procrustesStats = src.file.getList<float>("ProcrustesStats"); | ||
| 96 | - | ||
| 97 | - Eigen::MatrixXf R(2,2); | ||
| 98 | - R(0,0) = procrustesStats.at(0); | ||
| 99 | - R(1,0) = procrustesStats.at(1); | ||
| 100 | - R(1,1) = procrustesStats.at(2); | ||
| 101 | - R(0,1) = procrustesStats.at(3); | ||
| 102 | - | ||
| 103 | - cv::Scalar mean(2); | ||
| 104 | - mean[0] = procrustesStats.at(4); | ||
| 105 | - mean[1] = procrustesStats.at(5); | ||
| 106 | - | ||
| 107 | - float norm = procrustesStats.at(6); | ||
| 108 | - | ||
| 109 | - QList<Point2f> mappedPoints; | ||
| 110 | - | ||
| 111 | - for (int i = 0; i < validTriangles.size(); i+=3) { | ||
| 112 | - // Matrix to store original (pre-transformed) triangle vertices | ||
| 113 | - Eigen::MatrixXf srcMat(3, 2); | ||
| 114 | - | ||
| 115 | - for (int j = 0; j < 3; j++) { | ||
| 116 | - srcMat(j,0) = (validTriangles[i+j].x()-mean[0])/norm; | ||
| 117 | - srcMat(j,1) = (validTriangles[i+j].y()-mean[1])/norm; | ||
| 118 | - } | ||
| 119 | - | ||
| 120 | - Eigen::MatrixXf dstMat = srcMat*R; | ||
| 121 | - | ||
| 122 | - Point2f srcPoints[3]; | ||
| 123 | - for (int j = 0; j < 3; j++) srcPoints[j] = OpenCVUtils::toPoint(validTriangles[i+j]); | ||
| 124 | - | ||
| 125 | - Point2f dstPoints[3]; | ||
| 126 | - for (int j = 0; j < 3; j++) { | ||
| 127 | - // Scale and shift destination points | ||
| 128 | - Point2f warpedPoint = Point2f(dstMat(j,0)*scaleFactor+cols/2,dstMat(j,1)*scaleFactor+rows/2); | ||
| 129 | - dstPoints[j] = warpedPoint; | ||
| 130 | - mappedPoints.append(warpedPoint); | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - Mat buffer(rows,cols,src.m().type()); | ||
| 134 | - | ||
| 135 | - warpAffine(src.m(), buffer, getAffineTransform(srcPoints, dstPoints), Size(cols,rows)); | ||
| 136 | - | ||
| 137 | - Mat mask = Mat::zeros(rows, cols, CV_8UC1); | ||
| 138 | - Point maskPoints[1][3]; | ||
| 139 | - maskPoints[0][0] = dstPoints[0]; | ||
| 140 | - maskPoints[0][1] = dstPoints[1]; | ||
| 141 | - maskPoints[0][2] = dstPoints[2]; | ||
| 142 | - const Point* ppt = { maskPoints[0] }; | ||
| 143 | - | ||
| 144 | - fillConvexPoly(mask, ppt, 3, Scalar(255,255,255), 8); | ||
| 145 | - | ||
| 146 | - Mat output(rows,cols,src.m().type()); | ||
| 147 | - | ||
| 148 | - if (i > 0) { | ||
| 149 | - Mat overlap; | ||
| 150 | - bitwise_and(dst.m(),mask,overlap); | ||
| 151 | - mask.setTo(0, overlap!=0); | ||
| 152 | - } | ||
| 153 | - | ||
| 154 | - bitwise_and(buffer,mask,output); | ||
| 155 | - | ||
| 156 | - dst.m() += output; | ||
| 157 | - } | ||
| 158 | - | ||
| 159 | - // Overwrite any rects | ||
| 160 | - Rect boundingBox = boundingRect(mappedPoints.toVector().toStdVector()); | ||
| 161 | - dst.file.setRects(QList<QRectF>() << OpenCVUtils::fromRect(boundingBox)); | ||
| 162 | - } else dst = src; | ||
| 163 | - | ||
| 164 | - dst.file.setList<QPointF>("DelaunayTriangles", validTriangles); | ||
| 165 | - } | ||
| 166 | -}; | ||
| 167 | - | ||
| 168 | -BR_REGISTER(Transform, DelaunayTransform) | ||
| 169 | - | ||
| 170 | -} // namespace br | ||
| 171 | - | ||
| 172 | -#include "metadata/delaunay.moc" |