void HxCPDSpatialGraphWarp::resamplePairs(McDArray<McVec3f>& p1, McDArray<McVec3f>& p2) { int numPairs = p1.size(); for (int i = p1.size() - 1; i > -1; i--) { bool resetI = false; for (int j = i - 1; j > -1; j--) { // std::cout<<"\nCompare "<<i<<" and "<<j; McVec3f set1Coord = p1[i]; McVec3f set2Coord = p1[j]; float dist = (set1Coord - set2Coord).length(); if (dist < portSampleDist.getValue()) { std::cout << "\ndist between " << i << " and " << j << " is " << dist; } if (dist < portSampleDist.getValue()) { p1.remove(j, 1); p2.remove(j, 1); resetI = true; } } if (resetI) { i = p1.size() - 1; } } std::cout << "\n" << p1.size() << " point from " << numPairs << " left after resampling."; }
void BruteForceOptMatching::getMaxProbAssignments( const BP& ia, const FactorGraph& fg, const ConnectedFactorGraph& graph, McDArray<McVec2i>& pairs) { for (int i = 0; i < graph.variables.size(); i++) { McDArray<int> possibleAssignments; getAssignmentsForVariable(graph.variables[i], possibleAssignments); Factor belief = ia.belief(Var(graph.variables[i], possibleAssignments.size() + 1)); float maxVal = -1 * FLT_MAX; int maxIdx = -1; for (int j = 0; j < possibleAssignments.size() + 1; j++) { if (belief.get(j) > maxVal) { maxVal = belief.get(j); maxIdx = j; } } int indexOfAssignmentInVertexList = mapVariableAssignmentToIndexInVertexList(graph.variables[i], maxIdx); McVec2i pair = McVec2i(graph.variables[i], indexOfAssignmentInVertexList); pairs.append(pair); } outputSingleFactorValues(graph); // std::vector<std::size_t> maxes= ia.findMaximum(); // vector<std::size_t>::iterator it=maxes.begin(); }
void HxIteratePointMatchingUntilConvergence::addEvidenceForNodes( const McDArray<int>& nodesToAssign) { HxSpatialGraph* graph = hxconnection_cast<HxSpatialGraph>(portData); const EdgeVertexAttribute* evidenceAttrib = dynamic_cast<const EdgeVertexAttribute*>(graph->findAttribute( HxSpatialGraph::VERTEX, "UserDefinedMatchings")); McDArray<int> pairNodes(nodesToAssign.size()); pairNodes.fill(-1); for (int j = 0; j < nodesToAssign.size(); j++) { int nodeJLabel = evidenceAttrib->getIntDataAtIdx(nodesToAssign[j]); if (nodeJLabel == 0) { pairNodes[j] = -1; continue; } for (int i = 0; i < graph->getNumVertices(); i++) { if (i != nodesToAssign[j]) { int nodeILabel = evidenceAttrib->getIntDataAtIdx(i); if (nodeILabel == nodeJLabel) { pairNodes[j] = i; } } } } for (int j = 0; j < nodesToAssign.size(); j++) { addEvidence(nodesToAssign[j], pairNodes[j]); } }
static McDArray<McVec2d> asVec2dArray(const McDArray<McVec3f>& a) { McDArray<McVec2d> b; b.resize(a.size()); for (long i = 0; i < a.size(); i++) { b[i].x = a[i].x; b[i].y = a[i].y; } return b; }
void BruteForceOptMatching::computeAngleProbs(McDArray<float>& angles) { float sumAngles = 0; for (int i = 0; i < angles.size(); i++) { angles[i] = 180.0 - angles[i]; angles[i] = exp((float)(-angles[i] / 10.0)); sumAngles += angles[i]; } for (int i = 0; i < angles.size(); i++) angles[i] /= sumAngles; }
void BruteForceOptMatching::computeProjDistProbs(McDArray<float>& dists) { float sumDists = 0.0; for (int i = 0; i < dists.size(); i++) { if (dists[i] != FLT_MAX) { dists[i] = exp((float)(-dists[i] / 100.0)); } else dists[i] = 0; sumDists += dists[i]; } for (int i = 0; i < dists.size(); i++) dists[i] /= sumDists; }
// creates all singleton factors for one connected component // does not set the values void BruteForceOptMatching::createSingletonFactors( const McDArray<int>& connectedComp, vector<Factor>& singletonFactorList) { for (int i = 0; i < connectedComp.size(); i++) { McDArray<int> assigmentsForIthVariable; int curVar = connectedComp[i]; getAssignmentsForVariable(curVar, assigmentsForIthVariable); Var pi(curVar, assigmentsForIthVariable.size() + 1); Factor faci(pi); singletonFactorList.push_back(faci); } }
// Computes all variables that form a connected component in the // adjacenceMatrix. // The connected component chosen is arbitrary - it takes the first it finds. bool BruteForceOptMatching::getConnectedComponent( const McDMatrix<int>& adjacenceMatrix, McDMatrix<int>& adjacenceMatrixWithoutConnctedComponent, McDArray<int>& connComp) { adjacenceMatrixWithoutConnctedComponent.resize(adjacenceMatrix.nRows(), adjacenceMatrix.nCols()); memcpy(adjacenceMatrixWithoutConnctedComponent.dataPtr(), adjacenceMatrix.dataPtr(), sizeof(int) * adjacenceMatrix.nRows() * adjacenceMatrix.nCols()); // find first a startpoint int start = -1; connComp.resize(0); for (int i = 0; i < adjacenceMatrix.nRows(); i++) { for (int j = i; j < adjacenceMatrix.nCols(); j++) { if (adjacenceMatrix[i][j] == 1) { start = i; break; } } } if (start == -1) return false; McDArray<int> queue; queue.append(start); connComp.clear(); while (queue.size() > 0) { int cur = queue.last(); connComp.append(cur); queue.pop_back(); for (int i = 0; i < adjacenceMatrixWithoutConnctedComponent.nCols(); i++) { if (adjacenceMatrixWithoutConnctedComponent[cur][i] == 1) { queue.push(i); adjacenceMatrixWithoutConnctedComponent[cur][i] = 0; } } } // remove duplicates connComp.sort(&mcStandardCompare); int cur = connComp.last(); for (int i = connComp.size() - 2; i >= 0; i--) { if (cur == connComp[i]) connComp.remove(i, 1); else cur = connComp[i]; } return true; }
void BruteForceOptMatching::compute3dDistProbs(McDArray<float>& dists) { float sumDists = 0.0; // This should be a user parameter... float probParam = 500.0; for (int i = 0; i < dists.size(); i++) { if (dists[i] != FLT_MAX) { dists[i] = exp(-dists[i] / probParam); } else dists[i] = 0; sumDists += dists[i]; } for (int i = 0; i < dists.size(); i++) dists[i] /= sumDists; }
void BruteForceOptMatching::getSingletonProbs( const McDMatrix<float>& angleMatrix, const McDMatrix<float>& projDistanceMatrix, const McDMatrix<float>& distanceMatrix3d, const McDMatrix<int>& variableAssignmentMat, const McDArray<int>& assignments, const int varLabel, McDArray<double>& probs) { McDArray<float> floatProbs; getSingletonProbs(angleMatrix, projDistanceMatrix, distanceMatrix3d, variableAssignmentMat, assignments, varLabel, floatProbs); probs.resize(floatProbs.size()); for (int i = 0; i < floatProbs.size(); ++i) probs[i] = floatProbs[i]; }
void BruteForceOptMatching::projectToPlaneApproxDirection( const McDArray<McVec3f>& vertices, const McDArray<McVec3f>& directions, const float planeZ, McDArray<McVec3f>& result) { for (int i = 0; i < vertices.size(); i++) { McPlane theZPlane(McVec3f(0, 0, 1), planeZ); McVec3f vertexCoord = vertices[i]; McVec3f dir = directions[i] * -1; dir.normalize(); float angle = dir.angle(McVec3f(0, 0, 1)); if (angle > M_PI / 2.0) angle = M_PI - angle; McLine theLine(vertexCoord, vertexCoord + directions[i]); McVec3f intersectionPoint; bool intersected = theZPlane.intersect(theLine, intersectionPoint); // if(fabs(angle)<0.1) // cout<<"\n Angle for vertex "<<i <<" too low: "<< angle; if (intersected && (fabs(angle) < (M_PI / 2.0 - M_PI / 8.0))) { result.append(intersectionPoint); } else { result.append(McVec3f(vertexCoord.x, vertexCoord.y, planeZ)); } } }
float BruteForceOptMatching::getMedianZ(const McDArray<McVec3f>& vertices) { if (!vertices.size()) return -1 * FLT_MAX; McDArray<float> zs; float mean = 0.0; for (int i = 0; i < vertices.size(); i++) { zs.append(vertices[i].z); mean += vertices[i].z; } zs.sort(&mcStandardCompare); int medianIdx = zs.size() / 2.0; // cout <<"MeanZ: "<<mean/vertices.size(); // return mean/vertices.size(); return zs[medianIdx]; }
void HxCPDSpatialGraphWarp::preparePoints(McDArray<McVec3f>& p1, McDArray<McVec3f>& p2, SpatialGraphSelection& slice2, const HxSpatialGraph* spatialGraph) { ma::SliceSelector selectionHelper(spatialGraph, "TransformInfo"); ma::EndPointParams params; params.endPointRegion = 30; params.projectionPlane = selectionHelper.computeMidPlane(0, 1); params.projectionType = ma::P_ORTHOGONAL; params.refSliceNum = 0; params.transSliceNum = 1; params.useAbsoluteValueForEndPointRegion = false; params.maxDistForAngle = 2000; params.angleToPlaneFilter = 0.01; SpatialGraphSelection slice1; ma::FacingPointSets pr = ma::projectEndPoints(spatialGraph, slice1, slice2, params); McDArray<McVec3f> refCoords = pr.ref.positions; McDArray<McVec3f> transCoords = pr.trans.positions; mcassert(refCoords.size() == slice1.getNumSelectedVertices()); mcassert(transCoords.size() == slice2.getNumSelectedVertices()); p1.resize(refCoords.size()); for (int i = 0; i < refCoords.size(); i++) { McVec3f coord = refCoords[i]; p1[i] = McVec3f(coord.x, coord.y, 0); } p2.resize(transCoords.size()); for (int i = 0; i < transCoords.size(); i++) { McVec3f coord = transCoords[i]; p2[i] = McVec3f(coord.x, coord.y, 0); } mcassert(p2.size() == slice2.getNumSelectedVertices()); }
void BruteForceOptMatching::checkAmbiguities(const BP& ia, const FactorGraph& fg, const ConnectedFactorGraph& graph, McDArray<int>& ambiguities) { for (int h = 0; h < graph.variables.size(); h++) { McDArray<int> possibleAssignments; getAssignmentsForVariable(graph.variables[h], possibleAssignments); Factor belief = ia.belief(Var(graph.variables[h], possibleAssignments.size() + 1)); float maxProb = belief.max(); int countSame = 0; for (int k = 0; k < possibleAssignments.size() + 1; k++) { float curProb = belief.get(k); if (fabs(curProb - maxProb) < 0.1) countSame++; } ///// cout << "\n Belief for var " << graph.variables[h] << "\n"; for (int k = 0; k < possibleAssignments.size() + 1; k++) { float curProb = belief.get(k); cout << curProb << " "; } cout << "\n"; //// if (countSame > 1) { // oh no! We found an ambiguos assignment! ambiguities.append(graph.variables[h]); // print it out: cout << "Found an ambiguous assignemnt to variable " << graph.variables[h] << "\n"; for (int k = 0; k < possibleAssignments.size() + 1; k++) { float curProb = belief.get(k); cout << curProb << " "; } cout << "\n"; } } }
float AssignEModulus::averageVoxels( const OBLelement3D* FEelement, const McDArray<McVec3f>& vertices, HxUniformScalarField3* field ) { if ( !FEelement ) { return 0; } McVec3f pcoords; // Create an instance of HxLoc3Regular instead of HxLocation3, // because we know we are dealing with a uniform scalar field and // we want access to the voxelindices //HxLoc3Regular* location = image->coords()->createLocation(); HxLoc3Regular* location = (HxLoc3Regular*)field->createLocation(); // determine bounding box of voxel indices within element location->set( vertices[0][0], vertices[0][1], vertices[0][2] ); int indexbbox[6] = { location->ix, location->ix, location->iy, location->iy, location->iz, location->iz }; for ( int el = 1; el < vertices.size(); el++ ) { location->move( vertices[el][0], vertices[el][1], vertices[el][2] ); if ( location->ix < indexbbox[0] ) { indexbbox[0] = location->ix; } if ( location->ix > indexbbox[1] ) { indexbbox[1] = location->ix; } if ( location->iy < indexbbox[2] ) { indexbbox[2] = location->iy; } if ( location->iy > indexbbox[3] ) { indexbbox[3] = location->iy; } if ( location->iz < indexbbox[4] ) { indexbbox[4] = location->iz; } if ( location->iz > indexbbox[5] ) { indexbbox[5] = location->iz; } } float sum = 0.0; int count = 0; for ( int k = indexbbox[4]; k <= indexbbox[5]; k++ ) { for ( int j = indexbbox[2]; j <= indexbbox[3]; j++ ) { for ( int i = indexbbox[0]; i <= indexbbox[1]; i++ ) { float point[3]; field->lattice.coords()->pos( i, j, k, point ); int inside = FEelement->getIsoParam( vertices, McVec3f(point[0],point[1], point[2]), pcoords ); if ( inside == 1 ) { location->move( point ); float value; field->eval( location, &value ); sum += value; count++; } } } } delete location; return ( count > 0 ) ? ( sum/count ) : 0.0; }
int BruteForceOptMatching::getEvidenceAssignment( const ConnectedFactorGraph& graph, const int varLabel, int& evidenceAssignmentIndexInGraph) { int evidenceAssignmentIndexInWholeModel = -1; McVec2i evidence(-1, -1); for (int i = 0; i < mEvidence.size(); i++) { if (mEvidence[i].x == varLabel) { evidence = mEvidence[i]; } } // get assignment if (evidence.x == varLabel) { evidenceAssignmentIndexInWholeModel = evidence.y; } else { // if there was no assignment, we return -1 evidenceAssignmentIndexInGraph = -1; return evidenceAssignmentIndexInWholeModel; } // The varaible was assigned, let's see to which one. McDArray<int> assignementsForVariable; getAssignmentsForVariable(varLabel, assignementsForVariable); if (evidenceAssignmentIndexInWholeModel == -1) { // if the assigned vaue is the dummy value, // assign the dummy value, but return -1 anyway, because there is no // label for the assignment evidenceAssignmentIndexInGraph = assignementsForVariable.size(); return evidenceAssignmentIndexInWholeModel; } for (int i = 0; i < assignementsForVariable.size(); i++) { if (assignementsForVariable[i] == evidenceAssignmentIndexInWholeModel) { // assign the index of assignment in the current graph but return // the index in the full model evidenceAssignmentIndexInGraph = i; return evidenceAssignmentIndexInWholeModel; } } // not OK evidenceAssignmentIndexInGraph = -2; return evidenceAssignmentIndexInWholeModel; }
int BruteForceOptMatching::mapVariableAssignmentToIndexInVertexList( const int variableLabel, const int assignment) { McDArray<int> possibleAssignments; getAssignmentsForVariable(variableLabel, possibleAssignments); // see if the assignment was the dummy variable if (assignment == possibleAssignments.size()) return -1; return possibleAssignments[assignment]; }
// `resamplePairs()` removes points that are closer than `sampleDist` in `p1`. // The corresponding points are also removed from `p2`. The two arrays are // required to have the same size. static void resamplePairs(McDArray<McVec3f>& p1, McDArray<McVec3f>& p2, const float sampleDist) { mcrequire(p1.size() == p2.size()); const int numPairs = p1.size(); for (int i = p1.size() - 1; i > -1; i--) { bool resetI = false; for (int j = i - 1; j > -1; j--) { const McVec3f set1Coord = p1[i]; const McVec3f set2Coord = p1[j]; const float dist = (set1Coord - set2Coord).length(); if (dist < sampleDist) { p1.remove(j, 1); p2.remove(j, 1); resetI = true; } } if (resetI) i = p1.size() - 1; } }
// creates a pairwise factor for each adjacent variables in one connected // component // does not set the values yet void BruteForceOptMatching::createConnectionFactors( const McDMatrix<int>& adjMat, const McDArray<int> connectedComp, vector<Factor>& pairFactorList) { for (int i = 0; i < connectedComp.size(); i++) { int curVar = connectedComp[i]; McDArray<int> assigmentsForIthVariable; getAssignmentsForVariable(curVar, assigmentsForIthVariable); Var pi(curVar, assigmentsForIthVariable.size() + 1); for (int j = curVar + 1; j < adjMat.nCols(); j++) { if (adjMat[curVar][j] == 1) { McDArray<int> assigmentsForJthVariable; getAssignmentsForVariable(j, assigmentsForJthVariable); Var pj(j, assigmentsForJthVariable.size() + 1); Factor facij(VarSet(pi, pj)); pairFactorList.push_back(facij); } } } }
void BruteForceOptMatching::getAssignedValuesForVar( const McDMatrix<float>& allValues, const McDMatrix<int>& variableAssignmentMat, const McDArray<int>& possibleAssignments, const int label, const float zeroVal, McDArray<float>& values) { values.resize(0); for (int i = 0; i < possibleAssignments.size(); i++) { if (variableAssignmentMat[label][possibleAssignments[i]] > 1.e-6) { values.append(allValues[label][possibleAssignments[i]]); } else values.append(zeroVal); } }
void BruteForceOptMatching::getSingletonProbs( const McDMatrix<float>& angleMatrix, const McDMatrix<float>& projDistanceMatrix, const McDMatrix<float>& distanceMatrix3d, const McDMatrix<int>& variableAssignmentMat, const McDArray<int>& assignments, const int varLabel, McDArray<float>& probs) { McDArray<float> angleValues; getAssignedValuesForVar(angleMatrix, variableAssignmentMat, assignments, varLabel, 0, angleValues); mcassert(angleValues.size() == assignments.size()); // add dummy angleValues.append(mAngleThreshold / 2.0); // compute actual prob representation computeAngleProbs(angleValues); McDArray<float> projDistValues; getAssignedValuesForVar(projDistanceMatrix, variableAssignmentMat, assignments, varLabel, FLT_MAX, projDistValues); // add dummy projDistValues.append(mDistanceThresholdProjected / 2.0); // compute actual prob representation computeProjDistProbs(projDistValues); McDArray<float> distValues3d; getAssignedValuesForVar(distanceMatrix3d, variableAssignmentMat, assignments, varLabel, FLT_MAX, distValues3d); // add dummy distValues3d.append(mDistanceThreshold3d / 2.0); // compute actual prob representation compute3dDistProbs(distValues3d); probs.resize(assignments.size() + 1); // set values of factors: Multiply angle and dist threshold for (int j = 0; j < probs.size(); j++) { probs[j] = projDistValues[j] * angleValues[j]; } }
void ma::cpdElastic(const ma::FacingPointSets& points, ma::WarpResult& warpResult, const ma::CPDParams& params, ma::Context* ctx) { if (!ctx) { ctx = &defaultContext(); } CPDElasticAligner cpd; cpd.setContext(ctx); cpd.params = params.elastic; if (params.elastic.useDirections) { FacingPointSets copy = points; for (int i = 0; i < copy.trans.directions.size(); i++) { copy.trans.directions[i] *= -1; } cpd.setPoints(copy); } else { cpd.setPoints(points); } // Solve. AlignInfo info; McDArray<McVec3f> transCoords = cpd.align(info); McDArray<McVec3f> origCoords = points.trans.positions; const int nbefore = origCoords.size(); resamplePairs(origCoords, transCoords, params.elastic.sampleDistForWarpingLandmarks); ctx->print(QString("%1 of %2 points left after resampling.") .arg(nbefore) .arg(origCoords.size())); warpResult.type = WT_ELASTIC; warpResult.mlsParams.alpha = params.alphaForMLS; warpResult.mlsParams.ps = asVec2dArray(origCoords); warpResult.mlsParams.qs = asVec2dArray(transCoords); warpResult.alignInfo = info; }
void BruteForceOptMatching::checkAmbiguitiesInAssignments( const ConnectedFactorGraph& graph, const McDArray<McVec2i>& matchedPointPairs, McDArray<int>& ambiguities) { McBitfield assignedAlready(mCoords2.size()); assignedAlready.unsetAll(); for (int i = 0; i < matchedPointPairs.size(); i++) { if (matchedPointPairs[i].y < 0) continue; if (assignedAlready[matchedPointPairs[i].y]) ambiguities.append(matchedPointPairs[i].x); assignedAlready.set(matchedPointPairs[i].y); } }
void MicrotubuleTransformOperation::undo() { SbMatrix invMat = mMat.inverse(); SpatialGraphSelection::Iterator iter(mSelection); iter.vertices.reset(); int vNum = iter.vertices.nextSelected(); while (vNum != -1) { McVec3f c = graph->getVertexCoords(vNum); SbVec3f t(c.x, c.y, c.z); SbVec3f res; invMat.multVecMatrix(t, res); graph->setVertexCoords(vNum, McVec3f(res[0], res[1], res[2])); vNum = iter.vertices.nextSelected(); } iter.edges.reset(); int eNum = iter.edges.nextSelected(); while (eNum != -1) { McDArray<McVec3f> points = graph->getEdgePoints(eNum); for (int p = 0; p < points.size(); p++) { SbVec3f t(points[p].x, points[p].y, points[p].z); SbVec3f res; invMat.multVecMatrix(t, res); points[p] = McVec3f(res[0], res[1], res[2]); } graph->setEdgePoints(eNum, points); eNum = iter.edges.nextSelected(); } int numPoints = mSelection.getNumSelectedPoints(); for (int i = 0; i < numPoints; ++i) { SpatialGraphPoint p = mSelection.getSelectedPoint(i); McDArray<McVec3f> points = graph->getEdgePoints(p.edgeNum); SbVec3f t(points[p.pointNum].x, points[p.pointNum].y, points[p.pointNum].z); SbVec3f res; invMat.multVecMatrix(t, res); points[p.pointNum] = McVec3f(res[0], res[1], res[2]); graph->setEdgePoints(p.edgeNum, points); } // update the transform parameters for (int i = 0; i < mTransParams.size(); ++i) { appendTransform(mTransParams[i], invMat); } }
void BruteForceOptMatching::get3dShiftProbs( const McVec3f pointCoord1, const McVec3f pointCoord2, const McDArray<McVec3f>& assignmentCoordsVar1, const McDArray<McVec3f>& assignmentCoordsVar2, McDMatrix<float>& probs) { float probParam = 50.0; float dummyDistance = mDistanceThresholdProjected / 2.0; for (int i = 0; i < assignmentCoordsVar1.size(); i++) { for (int j = 0; j < assignmentCoordsVar2.size(); j++) { McVec3f dir1 = pointCoord1 - assignmentCoordsVar1[i]; McVec3f dir2 = pointCoord2 - assignmentCoordsVar2[j]; float dist1 = dir1.length(); float dist2 = dir2.length(); dir1.normalize(); dir2.normalize(); dir1 *= -1; dir2 *= -1; McVec3f p2Projected = dir1 * dist2 + pointCoord2; McVec3f p1Projected = dir2 * dist1 + pointCoord1; float distP1Projected = (assignmentCoordsVar1[i] - p1Projected).length(); float distP2Projected = (assignmentCoordsVar2[j] - p2Projected).length(); float maxDist = distP1Projected > distP2Projected ? distP1Projected : distP2Projected; probs[i][j] = exp(-maxDist / probParam); } } for (int i = 0; i <= assignmentCoordsVar1.size(); i++) { probs[i][assignmentCoordsVar2.size()] = exp(-dummyDistance / probParam); } for (int i = 0; i <= assignmentCoordsVar2.size(); i++) { probs[(int)(assignmentCoordsVar1.size())][i] = exp(-dummyDistance / probParam); } // normalize float sumDists = 0.0; for (int i = 0; i < probs.nCols() * probs.nRows(); i++) sumDists += probs.dataPtr()[i]; for (int i = 0; i < probs.nCols() * probs.nRows(); i++) probs.dataPtr()[i] /= sumDists; }
int HxIteratePointMatchingUntilConvergence::getNumberOfPointsToAssign() { McDArray<int> nodesToAssign; getListOfNeededEvidenceNodes(nodesToAssign); return nodesToAssign.size(); }