Esempio n. 1
0
cv::Mat performSuperpixelSegmentation_VariableSandM(std::vector<std::vector<double> > &kseeds, std::vector<double> &kseedsx, std::vector<double> &kseedsy, const std::vector<cv::Mat> &vec, const cv::Size &size, const int &STEP, const int &NUMITR = 10) {
    
    int sz = size.width*size.height;
	const int numk = (int) kseedsx.size();
	int numitr = 0;
    
	int offset = (STEP < 10) ? STEP*1.5 : STEP;
    
    cv::Mat klabels = cv::Mat(size, cv::DataType<int>::type);
    klabels = -1;
    
    std::vector<std::vector<double> > sigmac(0);
    for (int c = 0; c < vec.size(); c++) {
        sigmac.push_back(std::vector<double>(numk, 0));
    }
    std::vector<double> sigmax(numk, 0);
    std::vector<double> sigmay(numk, 0);
    std::vector<int> clustersize(numk, 0);
    std::vector<double> inv(numk, 0);//to store 1/clustersize[k] values
    std::vector<double> distxy(sz, DBL_MAX);
    std::vector<double> distc(sz, DBL_MAX);
    std::vector<double> distvec(sz, DBL_MAX);
    std::vector<double> maxc(numk, 10*10);//THIS IS THE VARIABLE VALUE OF M, just start with 10
    std::vector<double> maxxy(numk, STEP*STEP);//THIS IS THE VARIABLE VALUE OF M, just start with 10
    
	double invxywt = 1.0/(STEP*STEP);//NOTE: this is different from how usual SLIC/LKM works
    
	while( numitr < NUMITR )
	{
		//------
		//cumerr = 0;
		numitr++;
		//------
        
		distvec.assign(sz, DBL_MAX);
		for( int n = 0; n < numk; n++ )
		{
			int y1 = std::max(double(0), kseedsy[n]-offset);
			int y2 = std::min(double(size.height),	kseedsy[n]+offset);
			int x1 = std::max(double(0), kseedsx[n]-offset);
			int x2 = std::min(double(size.width),	kseedsx[n]+offset);
            
			for( int y = y1; y < y2; y++ )
			{
				for( int x = x1; x < x2; x++ )
				{
					int i = y*size.width + x;
					if( !(y < size.height && x < size.width && y >= 0 && x >= 0) ) {
                        throw cv::Exception();
                    }
                    
					distc[i] =	0;
                    for (int c = 0; c < vec.size(); c++) {
                        distc[i] += (vec[c].ptr<double>()[i] - kseeds[c][n]) * (vec[c].ptr<double>()[i] - kseeds[c][n]);
                    }
                    
					distxy[i] =		(x - kseedsx[n])*(x - kseedsx[n]) + (y - kseedsy[n])*(y - kseedsy[n]);
                    
					double dist = distc[i]/maxc[n] + distxy[i]*invxywt;//only varying m, prettier superpixels
					
					if( dist < distvec[i] )
					{
						distvec[i] = dist;
						klabels.ptr<int>()[i]  = n;
					}
				}
			}
		}
		//-----------------------------------------------------------------
		// Assign the max color distance for a cluster
		//-----------------------------------------------------------------
		if(0 == numitr)
		{
			maxc.assign(numk,1);
			maxxy.assign(numk,1);
		}
		{for( int i = 0; i < sz; i++ )
		{
			if(maxc[klabels.ptr<int>()[i]] < distc[i]) maxc[klabels.ptr<int>()[i]] = distc[i];
			if(maxxy[klabels.ptr<int>()[i]] < distxy[i]) maxxy[klabels.ptr<int>()[i]] = distxy[i];
		}}
		//-----------------------------------------------------------------
		// Recalculate the centroid and store in the seed values
		//-----------------------------------------------------------------
        
        for (int c = 0; c < sigmac.size(); c++) {
            sigmac[c].assign(numk, 0);
        }
		sigmax.assign(numk, 0);
		sigmay.assign(numk, 0);
		clustersize.assign(numk, 0);
        
		for( int j = 0; j < sz; j++ )
		{
			if(!(klabels.ptr<int>()[j] >= 0))
                throw cv::Exception();
            
            for (int c = 0; c < sigmac.size(); c++) {
                sigmac[c][klabels.ptr<int>()[j]] += vec[c].ptr<double>()[j];
            }
			sigmax[klabels.ptr<int>()[j]] += (j%size.width);
			sigmay[klabels.ptr<int>()[j]] += (j/size.width);
            
			clustersize[klabels.ptr<int>()[j]]++;
		}
        
		{for( int k = 0; k < numk; k++ )
		{
			if( clustersize[k] <= 0 ) clustersize[k] = 1;
			inv[k] = 1.0/double(clustersize[k]);//computing inverse now to multiply, than divide later
		}}
		
		{for( int k = 0; k < numk; k++ )
		{
            for (int c = 0; c < kseeds.size(); c++) {
                kseeds[c][k] = sigmac[c][k] * inv[k];
            }
			kseedsx[k] = sigmax[k]*inv[k];
			kseedsy[k] = sigmay[k]*inv[k];
		}}
	}
    
    return klabels;
}
//===========================================================================
///	PerformSuperpixelSegmentation_VariableSandM
///
///	Magic SLIC - no parameters
///
///	Performs k mean segmentation. It is fast because it looks locally, not
/// over the entire image.
/// This function picks the maximum value of color distance as compact factor
/// M and maximum pixel distance as grid step size S from each cluster (13 April 2011).
/// So no need to input a constant value of M and S. There are two clear
/// advantages:
///
/// [1] The algorithm now better handles both textured and non-textured regions
/// [2] There is not need to set any parameters!!!
///
/// SLICO (or SLIC Zero) dynamically varies only the compactness factor S,
/// not the step size S.
//===========================================================================
void SLIC::PerformSuperpixelSegmentation_VariableSandM(
	vector<double>&				kseedsl,
	vector<double>&				kseedsa,
	vector<double>&				kseedsb,
	vector<double>&				kseedsx,
	vector<double>&				kseedsy,
	int*						klabels,
	const int&					STEP,
	const int&					NUMITR)
{
	int sz = m_width*m_height;
	const int numk = kseedsl.size();
	//double cumerr(99999.9);
	int numitr(0);

	//----------------
	int offset = STEP;
	if(STEP < 10) offset = STEP*1.5;
	//----------------

	vector<double> sigmal(numk, 0);
	vector<double> sigmaa(numk, 0);
	vector<double> sigmab(numk, 0);
	vector<double> sigmax(numk, 0);
	vector<double> sigmay(numk, 0);
	vector<int> clustersize(numk, 0);
	vector<double> inv(numk, 0);//to store 1/clustersize[k] values
	vector<double> distxy(sz, DBL_MAX);
	vector<double> distlab(sz, DBL_MAX);
	vector<double> distvec(sz, DBL_MAX);
	vector<double> maxlab(numk, 10*10);//THIS IS THE VARIABLE VALUE OF M, just start with 10
	vector<double> maxxy(numk, STEP*STEP);//THIS IS THE VARIABLE VALUE OF M, just start with 10

	double invxywt = 1.0/(STEP*STEP);//NOTE: this is different from how usual SLIC/LKM works

	while( numitr < NUMITR )
	{
		//------
		//cumerr = 0;
		numitr++;
		//------

		distvec.assign(sz, DBL_MAX);
		for( int n = 0; n < numk; n++ )
		{
			int y1 = max(0,			static_cast<int>(kseedsy[n])-offset);
			int y2 = min(m_height,	static_cast<int>(kseedsy[n])+offset);
			int x1 = max(0,			static_cast<int>(kseedsx[n])-offset);
			int x2 = min(m_width,	static_cast<int>(kseedsx[n])+offset);

			for( int y = y1; y < y2; y++ )
			{
				for( int x = x1; x < x2; x++ )
				{
					int i = y*m_width + x;
					_ASSERT( y < m_height && x < m_width && y >= 0 && x >= 0 );

					double l = m_lvec[i];
					double a = m_avec[i];
					double b = m_bvec[i];

					distlab[i] =	(l - kseedsl[n])*(l - kseedsl[n]) +
									(a - kseedsa[n])*(a - kseedsa[n]) +
									(b - kseedsb[n])*(b - kseedsb[n]);

					distxy[i] =		(x - kseedsx[n])*(x - kseedsx[n]) +
									(y - kseedsy[n])*(y - kseedsy[n]);

					//------------------------------------------------------------------------
					double dist = distlab[i]/maxlab[n] + distxy[i]*invxywt;//only varying m, prettier superpixels
					//double dist = distlab[i]/maxlab[n] + distxy[i]/maxxy[n];//varying both m and S
					//------------------------------------------------------------------------
					
					if( dist < distvec[i] )
					{
						distvec[i] = dist;
						klabels[i]  = n;
					}
				}
			}
		}
		//-----------------------------------------------------------------
		// Assign the max color distance for a cluster
		//-----------------------------------------------------------------
		if(0 == numitr)
		{
			maxlab.assign(numk,1);
			maxxy.assign(numk,1);
		}
		{for( int i = 0; i < sz; i++ )
		{
			if(maxlab[klabels[i]] < distlab[i]) maxlab[klabels[i]] = distlab[i];
			if(maxxy[klabels[i]] < distxy[i]) maxxy[klabels[i]] = distxy[i];
		}}
		//-----------------------------------------------------------------
		// Recalculate the centroid and store in the seed values
		//-----------------------------------------------------------------
		sigmal.assign(numk, 0);
		sigmaa.assign(numk, 0);
		sigmab.assign(numk, 0);
		sigmax.assign(numk, 0);
		sigmay.assign(numk, 0);
		clustersize.assign(numk, 0);

		for( int j = 0; j < sz; j++ )
		{
			int temp = klabels[j];
			_ASSERT(klabels[j] >= 0);
			sigmal[klabels[j]] += m_lvec[j];
			sigmaa[klabels[j]] += m_avec[j];
			sigmab[klabels[j]] += m_bvec[j];
			sigmax[klabels[j]] += (j%m_width);
			sigmay[klabels[j]] += (j/m_width);

			clustersize[klabels[j]]++;
		}

		{for( int k = 0; k < numk; k++ )
		{
			//_ASSERT(clustersize[k] > 0);
			if( clustersize[k] <= 0 ) clustersize[k] = 1;
			inv[k] = 1.0/double(clustersize[k]);//computing inverse now to multiply, than divide later
		}}
		
		{for( int k = 0; k < numk; k++ )
		{
			kseedsl[k] = sigmal[k]*inv[k];
			kseedsa[k] = sigmaa[k]*inv[k];
			kseedsb[k] = sigmab[k]*inv[k];
			kseedsx[k] = sigmax[k]*inv[k];
			kseedsy[k] = sigmay[k]*inv[k];
		}}
	}
}
Esempio n. 3
0
int main() {

  std::mt19937 rng;
  rng.seed(std::random_device()());
  std::uniform_int_distribution<std::mt19937_64::result_type> distxy(-25, 25);
  std::uniform_int_distribution<std::mt19937_64::result_type> distz(1, DEPTH);
    
  for (int i = 0; i < NUM_STARS; i++) {
    stars[i].x = distxy(rng);
    stars[i].y = distxy(rng);
    stars[i].z = distz(rng);
  }

  sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "SFML Starfield");
  window.setFramerateLimit(FRAMES_PER_SECOND);

  sf::Texture texture;

  if (!texture.loadFromFile("res/sprites/star_flare_default.png")) {
    return 1;
  }

  sf::Sprite sprite;

  sprite.setTexture(texture);
  sprite.setOrigin(256, 256);
  
  window.clear(sf::Color::Black);
  window.display();

  while (window.isOpen()) {

    sf::Event event;

    while (window.pollEvent(event)) {
      if (event.type == sf::Event::Closed) {
	window.close();
      }
    }

    window.clear(sf::Color::Black);
    
    for (int i = 0; i < NUM_STARS; i++) {
      stars[i].z -= 0.1;

      if (stars[i].z <= 0) {
	stars[i].x = distxy(rng);
	stars[i].y = distxy(rng);
	stars[i].z = DEPTH;
      }

      float k = 256 / stars[i].z;
      float xPos = (stars[i].x * k) + WINDOW_HALF_WIDTH;
      float yPos = (stars[i].y * k) + WINDOW_HALF_HEIGHT;

      if (xPos >= 0 && xPos < WINDOW_WIDTH && yPos >= 0 && yPos < WINDOW_HEIGHT) {
	sprite.setPosition(sf::Vector2f(xPos, yPos));
	
	sprite.setScale(sf::Vector2f((float)(1 - stars[i].z / DEPTH) * .03,
				     (float)(1 - stars[i].z / DEPTH) * .03));
	window.draw(sprite);
      }
      
    }
    
    window.display();
  }
  
  return 0;
}