// k := window size void MotionGraph::genCandidates(std::ofstream &os, int motionIdxA, int motionIdxB, int k) { Skeleton *skeleton = library->getSkeleton(); Motion *motionA = library->getMotion(motionIdxA); Motion *motionB = library->getMotion(motionIdxB); if (skeleton == NULL || motionA == NULL || motionB == NULL) { printf("Error: in genCandidates().\n"); exit(-1); } int numFramesA = motionA->GetNumFrames(); int numFramesB = motionB->GetNumFrames(); printf("motionIdxA = %d, motionIdxB = %d\n", motionIdxA, motionIdxB); printf("numFramesA = %d, numFramesB = %d\n", numFramesA, numFramesB); os << "#motionIndex" << std::endl << motionIdxA << ' ' << motionIdxB << std::endl; os << "#motionName" << std::endl << library->getName(motionIdxA) << ' ' << library->getName(motionIdxB) << std::endl; os << "#numFrames" << std::endl << numFramesA << ' ' << numFramesB << std::endl; PointCloud **pcListA = new PointCloud *[numFramesA]; PointCloud **pcListB = new PointCloud *[numFramesB]; for (int i = 0; i < numFramesA; i++) { skeleton->setPosture(*(motionA->GetPosture(i))); pcListA[i] = new PointCloud(skeleton); } for (int i = 0; i < numFramesB; i++) { skeleton->setPosture(*(motionB->GetPosture(i))); pcListB[i] = new PointCloud(skeleton); } printf("Form distance matrix...\n"); double *dist = new double[numFramesA * numFramesB](); // distance of any pair of windows int iBegin = 0; int iEnd = numFramesA - k; int jBegin = k - 1; int jEnd = numFramesB - 1; printf("Calculating distances...\n"); for (int i = iBegin; i <= iEnd; i++) // window of motionA: [i..i+k-1] { if (i % 10 == 0) printf("Calculating (%d, %d)...\n", i, 0); for (int j = jBegin; j <= jEnd; j++) // window of motionB: [j-k+1..j] { // form point cloud over k frames PointCloud pcA(&pcListA[i], k); PointCloud pcB(&pcListB[j - k + 1], k); int index = i * numFramesB + j; dist[index] = distance(&pcA, &pcB); // distance } } printf("Calculating distances... done.\n"); //std::vector< std::pair<int, int> > minList; // local minimum list // local minimum list std::vector<WindowPair> minList; // search local minimums //bool *mark = new bool[numFramesA * numFramesB](); // traversed for (int i = iBegin; i <= iEnd; i++) { for (int j = jBegin; j <= jEnd; j++) { int index = i * numFramesB + j; bool isMin = true; for (int ii = i - 2; ii <= i + 2; ii++) { for (int jj = j - 2; jj <= j + 2; jj++) { if (ii >= iBegin && ii <= iEnd && jj >= jBegin && jj <= jEnd && dist[index] > dist[ii * numFramesB + jj]) isMin = false; } } if (isMin) { WindowPair pair; pair.i = i; pair.j = j; pair.dist = dist[index]; minList.push_back(pair); } } } std::sort(minList.begin(), minList.end()); printf("Local minimum list:\n"); int minListSize = 0; for (size_t i = 0; i < minList.size(); i++) { if (!(motionIdxA == motionIdxB && minList[i].i + 39 == minList[i].j)) minListSize++; } os << "#minListSize" << std::endl << minListSize << std::endl; os << "#i j distance theta x0 z0" << std::endl; for (size_t i = 0; i < minList.size(); i++) { double theta, x0, z0; PointCloud pcA(&pcListA[minList[i].i], k); PointCloud pcB(&pcListB[minList[i].j - k + 1], k); distance(&pcA, &pcB, &theta, &x0, &z0); //printf("%4d %4d %8.4lf %lf %lf %lf\n", minList[i].i, minList[i].j, minList[i].dist, theta, x0, z0); if (!(motionIdxA == motionIdxB && minList[i].i + 39 == minList[i].j)) os << minList[i].i << ' ' << minList[i].j << ' ' << minList[i].dist << ' ' << theta << ' ' << x0 << ' ' << z0 << std::endl; } delete [] dist; for (int i = 0; i < numFramesA; i++) delete pcListA[i]; for (int i = 0; i < numFramesB; i++) delete pcListB[i]; delete [] pcListA; delete [] pcListB; printf("genCandidates(): done.\n"); }