void silhouette_ksearch::process(const dataset & p_data, silhouette_ksearch_data & p_result) {
    if (m_kmax > p_data.size()) {
        throw std::invalid_argument("K max value '" + std::to_string(m_kmax) + 
            "' should be bigger than amount of objects '" + std::to_string(p_data.size()) + "' in input data.");
    }

    p_result.scores().reserve(m_kmax - m_kmin);

    for (std::size_t k = m_kmin; k < m_kmax; k++) {
        cluster_sequence clusters;
        m_allocator->allocate(k, p_data, clusters);

        if (clusters.size() != k) {
            p_result.scores().push_back(std::nan("1"));
            continue;
        }
        
        silhouette_data result;
        silhouette().process(p_data, clusters, result);

        const double score = std::accumulate(result.get_score().begin(), result.get_score().end(), (double) 0.0) / result.get_score().size();
        p_result.scores().push_back(score);

        if (score > p_result.get_score()) {
            p_result.set_amount(k);
            p_result.set_score(score);
        }
    }
}
Beispiel #2
0
OCL_PERF_TEST_P(UpdateMotionHistoryFixture, UpdateMotionHistory, OCL_TEST_SIZES)
{
    const Size size = GetParam();
    checkDeviceMaxMemoryAllocSize(size, CV_32FC1);

    UMat silhouette(size, CV_8UC1), mhi(size, CV_32FC1);
    randu(silhouette, -5, 5);
    declare.in(mhi, WARMUP_RNG);

    OCL_TEST_CYCLE() cv::updateMotionHistory(silhouette, mhi, 1, 0.5);

    SANITY_CHECK(mhi);
}
/*
 * Calculates the Silhouette index for a graph. Returns a vector
 * with the SI for the whole graph in position 0 and for each cluster
 * in the position of it's identifier.
 */
std::vector<double> ClusterEvaluator::getSilhouetteIndex() {
     hmap_i_i::iterator it;
     hmap_i_i spaths;
     hmap::iterator node;
     //int ccount;
     double an = 0.0;
     int bn = MAXIMUM;
     hmap_i_i ccount;
     hmap_i_i acc;
     std::vector<double> silhouette(clusters->size()+1);
     std::vector<int> node_count(clusters->size()+1);
     // Initializing average counters
     for (int i = 0; i < clusters->size()+1; ++i) {
          silhouette[i] = 0.0;
          node_count[i] = 0;
     }
     // For each node n in the graph
     unsigned int mycluster;
     std::set<uint>* ctmp;
     std::set<uint>::iterator itcl;
     for (node = graph->graph_map.begin(); node != graph->graph_map.end();
               ++node){
          // We will not calculate the Silhouette index for the
          // cluster 0, as it is not really a cluster
          std::set<uint>::iterator sit;
          for (sit = node_cluster->find(node->first)->second->begin();
                    sit != node_cluster->find(node->first)->second->end();
                    ++sit) {
               //mycluster = (node_cluster->find(node->first)->second);
               mycluster = *sit;
               if (mycluster != 0) {
                    // Calculate the shortest paths for all nodes
                    spaths = graph->dijkstra(node->first);
                    acc.clear();
                    ccount.clear();
                    for (it = spaths.begin(); it != spaths.end(); ++it) {
                         if (it->first != node->first){
                              ctmp = node_cluster->find(it->first)->second;
                              // Iterate through all of its clusters
                              for (itcl = ctmp->begin(); itcl != ctmp->end();
                                        ++itcl) { 
                                   if (acc.find(*itcl) == acc.end()) {
                                        // New cluster!
                                        acc[*itcl] = it->second;
                                        ccount[*itcl] = 1;
                                   } else {
                                        // Already exists. Accumulate
                                        acc[*itcl] = acc[*itcl] + it->second;
                                        ccount[*itcl] = ccount[*itcl] + 1;
                                   }
                              }
                         }
                    }
                    // Calculate average cluster distances
                    an = 0.0;
                    bn = MAXIMUM;
                    for (it = acc.begin(); it != acc.end(); ++it) {
                         if (it->first == mycluster) {
                              // Average distance to own cluster
                              an = it->second/(double)ccount[it->first];
                         } else {
                              // Minimum average distance to other clusters
                              double btmp = it->second/
                                   (double)ccount[it->first];
                              if (btmp < bn) bn = btmp;
                         }
                    }
                    //an = an/(double)ccount;
                    // His Silhouette index is Sn = (bn - an)/max(an, bn)
                    silhouette[mycluster] += (bn - an)/
                         ((an > (double) bn)? an:(double)bn);
                    node_count[mycluster] += 1;
               }
          }
     }
     for (int i = 1; i < silhouette.size(); ++i) {
          // Average Silhouette index for cluster i
          silhouette[i] = silhouette[i]/(double)node_count[i];
          // Average silhouete index for the whole graph
          silhouette[0] += silhouette[i]/(double)(silhouette.size()-1);
     }
     return silhouette;
}
Beispiel #4
0
void Extruder::extrude(){
	if (silhouette().empty())
	{
		Log::error("Extrusion::extrude(): no silhouette defined.\n");
		this->errFlag = true;
		return ;
	}
	if (positionPath().empty())
	{
		Log::error("Extrusion::extrude() needs at least a non empty positionPath().\n");
		this->errFlag = true;
		return ;
	}
	if (!scalingPath().empty() && scalingPath().size() != positionPath().size()-2)
	{
		Log::error("Extrusion::extrude(): scalingPath() must have the same number of control points as positionPath().\n");
		this->errFlag = true;
		return ;
	}
	if (!rotationPath().empty() && rotationPath().size() != positionPath().size()-2)
	{
		Log::error("Extrusion::extrude(): rotationPath() must have the same number of control points as positionPath().\n");
		this->errFlag = true;
		return ;
	}
	if (!colorPath().empty() && colorPath().size() != positionPath().size()-2)
	{
		Log::error("Extrusion::extrude(): colorPath() must have the same number of control points as positionPath().\n");
		this->errFlag = true;
		return ;
	}

	size_t segments = positionPath().size()-2;
	currPos = vertices.size();

	vertices.resize( currPos + silhouette().size() * segments );

	vl::fmat4 m = fmat4::getRotation(fvec3(0,1,0),positionPath()[1]-positionPath()[0]);

	// initialize silhouette on the x/z plane
	std::vector<vl::fvec3> projected_sil;
	projected_sil.resize(silhouette().size());
	for(unsigned i=0; i<silhouette().size(); ++i)
	{
		projected_sil[i] = m * vl::fvec3(silhouette()[i].x(),0,silhouette()[i].y()) + positionPath()[0];
	}

	// initialize plane normals from 1 to n-1 (end points are excluded)
	std::vector<fvec3> plane_normals;
	plane_normals.resize(positionPath().size());
	for(unsigned i=1; i<plane_normals.size()-1; ++i)
	{
		fvec3 p0 = positionPath()[i-1] - positionPath()[i];
		fvec3 p1 = positionPath()[i+1] - positionPath()[i];
		p0.normalize();
		p1.normalize();
		plane_normals[i] = (p1-p0).normalize();
	}

	for(unsigned i=1; i<positionPath().size()-1; ++i)
	{
		for(int j=0; j<(int)silhouette().size(); ++j)
		{
		  fvec3 V = (positionPath()[i] - positionPath()[i-1]).normalize();
		  const fvec3& P = projected_sil[j];
		  const fvec3& orig = positionPath()[i];
		  const fvec3& N = plane_normals [i];
		  float d = dot(N,orig);
		  float t = dot(V,N) ? (d-dot(P,N))/dot(V,N) : 0;
		  // project current projected_sil on next plane along p0->p1 vector
		  vertices.at(currPos+j+silhouette().size()*(i-1)) = projected_sil[j] = P + V*t;
		}
	}


	// rotation
	if(!rotationPath().empty())
	{
		for(unsigned i=1; i<positionPath().size()-1; ++i)
		{
			fvec3 r = (positionPath()[i+1] - positionPath()[i]).normalize();
			fmat4 mat = vl::fmat4::getRotation(rotationPath()[i-1],r);
			fvec3 c;
			for(int j=0; j<(int)silhouette().size(); ++j)
			c += vertices.at(currPos+j+silhouette().size()*(i-1));
			c /= (float)silhouette().size();
			for(int j=0; j<(int)silhouette().size(); ++j)
			vertices.at(currPos+j+silhouette().size()*(i-1)) = (mat*(vertices.at(currPos+j+silhouette().size()*(i-1))-c))+c;
		}
	}

	// scaling
	if(!scalingPath().empty())
	{
		for(unsigned i=1; i<positionPath().size()-1; ++i)
		{
			float s = scalingPath()[i-1];
			fvec3 c;
			for(int j=0; j<(int)silhouette().size(); ++j)
			c += vertices.at(currPos+j+silhouette().size()*(i-1));
			c /= (float)silhouette().size();
			for(int j=0; j<(int)silhouette().size(); ++j)
			vertices.at(currPos+j+silhouette().size()*(i-1)) = (s*(vertices.at(currPos+j+silhouette().size()*(i-1))-c))+c;
		}
	}

	int prof_count = silhouetteMode() == SilhouetteClosed ? (int)silhouette().size() : (int)silhouette().size()-1;
	currDE = de->indexBuffer()->size();
	de->indexBuffer()->resize(currDE + 4 * prof_count * (segments-1));
	for(size_t iseg=0; iseg<segments-1; ++iseg)
	{
		for(int iquad=0; iquad<prof_count; ++iquad)
		{
			de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 3) = currPos +  (iseg + 0) * (GLuint)silhouette().size() + iquad;
			de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 2) = currPos +(iseg + 0) * (GLuint)silhouette().size() + (iquad+1)%silhouette().size();
			de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 1) = currPos +(iseg + 1) * (GLuint)silhouette().size() + (iquad+1)%silhouette().size();
			de->indexBuffer()->at(currDE + iquad*4+iseg*4*prof_count + 0) = currPos +(iseg + 1) * (GLuint)silhouette().size() + iquad;
		}
	}

	// bottom/top caps

	size_t tess_bottom_count = 0;
	size_t tess_top_count    = 0;

	if(fillBottom())
	{
		size_t start = vertices.size();
		Tessellator tessellator;
		tessellator.contours().push_back((int)silhouette().size());
		for(unsigned i=0; i<silhouette().size(); ++i){
			tessellator.contourVerts().push_back((dvec3)vertices[currPos+i]);
		}
		tessellator.setWindingRule(vl::TW_TESS_WINDING_NONZERO);
		tessellator.tessellate();
		for(unsigned i=0; i<tessellator.tessellatedTris().size(); ++i){
			vertices.push_back(tessellator.tessellatedTris()[i]);
		}
		if (tessellator.tessellatedTris().size()){
			geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, start, tessellator.tessellatedTris().size()) );
		}tess_bottom_count = tessellator.tessellatedTris().size();
	}
	if(fillTop())
	{
		size_t start = vertices.size();
		Tessellator tessellator;
		tessellator.contours().push_back(silhouette().size());
		for(unsigned i=0; i<silhouette().size(); ++i){
			tessellator.contourVerts().push_back((dvec3)vertices[vertices.size()-i-1-tess_bottom_count]);
		}
		tessellator.setWindingRule(vl::TW_TESS_WINDING_NONZERO);
		tessellator.tessellate();
		for(unsigned i=0; i<tessellator.tessellatedTris().size(); ++i){
			vertices.push_back(tessellator.tessellatedTris()[i]);
		}
		if (tessellator.tessellatedTris().size()){
			geom->drawCalls()->push_back( new DrawArrays(PT_TRIANGLES, start, tessellator.tessellatedTris().size()) );
		}
		tess_top_count = tessellator.tessellatedTris().size();
	}

}