MatrixX3f Surface::compute_normals(const MatrixX3f& rr, const MatrixX3i& tris) { printf("\tcomputing normals\n"); // first, compute triangle normals MatrixX3f r1(tris.rows(),3); MatrixX3f r2(tris.rows(),3); MatrixX3f r3(tris.rows(),3); for(qint32 i = 0; i < tris.rows(); ++i) { r1.row(i) = rr.row(tris(i, 0)); r2.row(i) = rr.row(tris(i, 1)); r3.row(i) = rr.row(tris(i, 2)); } MatrixX3f x = r2 - r1; MatrixX3f y = r3 - r1; MatrixX3f tri_nn(x.rows(),y.cols()); tri_nn.col(0) = x.col(1).cwiseProduct(y.col(2)) - x.col(2).cwiseProduct(y.col(1)); tri_nn.col(1) = x.col(2).cwiseProduct(y.col(0)) - x.col(0).cwiseProduct(y.col(2)); tri_nn.col(2) = x.col(0).cwiseProduct(y.col(1)) - x.col(1).cwiseProduct(y.col(0)); // Triangle normals and areas MatrixX3f tmp = tri_nn.cwiseProduct(tri_nn); VectorXf normSize = tmp.rowwise().sum(); normSize = normSize.cwiseSqrt(); for(qint32 i = 0; i < normSize.size(); ++i) if(normSize(i) != 0) tri_nn.row(i) /= normSize(i); MatrixX3f nn = MatrixX3f::Zero(rr.rows(), 3); for(qint32 p = 0; p < tris.rows(); ++p) { Vector3i verts = tris.row(p); for(qint32 j = 0; j < verts.size(); ++j) nn.row(verts(j)) = tri_nn.row(p); } tmp = nn.cwiseProduct(nn); normSize = tmp.rowwise().sum(); normSize = normSize.cwiseSqrt(); for(qint32 i = 0; i < normSize.size(); ++i) if(normSize(i) != 0) nn.row(i) /= normSize(i); return nn; }
Image smooth_detector(const Image& source, Interpolation level, int r) { Image output(source.rows(), source.columns(), 1, numeric_limits<float>::max()); const MatrixXf reg_matrix = ComputeRegMatrix(level, r); const LDLT<MatrixXf> solver = (reg_matrix.transpose() * reg_matrix).ldlt(); for (int pr = 0; pr <= source.rows() - r; ++pr) { for (int pc = 0; pc <= source.columns() - r; ++pc) { VectorXf dist = VectorXf::Zero(r * r); for (int ch = 0; ch < source.channels(); ++ch) { EigenImage y = ExtractPatch(source, r, pr, pc, ch); VectorXf reg_surf = solver.solve(reg_matrix.transpose() * y.asvector()); dist += (reg_matrix * reg_surf - y.asvector()).cwiseAbs2(); } dist = dist.cwiseSqrt(); for (int row = pr; row < min(output.rows(), pr + r); ++row) { for (int col = pc; col < min(output.columns(), pc + r); ++col) { output.val(col, row) = min(output.val(col, row), dist((row - pr) * r + col - pc)); } } } } return output; }