コード例 #1
0
ファイル: stattest6.cpp プロジェクト: Mathayo/CPP
int main(int argc, char* argv[])
{
  std::vector<NumberType> input(0);
  std::ifstream ifs;
  if (argc < 2) // expects keyboard input
  {
    if (sizeof(NumberType) == sizeof(char))
      // keyboard input of type char is un-intuitve
      // when interpreted as a numerical type
    {
      std::cout << "Please provide filename containing data.\n";
      exit(EXIT_SUCCESS);
    }
    std::cout << "Enter numerical data: ";
    ReadData(input, std::cin);
  }
  else // reads from file - command line argument
  {
    ifs.open(argv[1]);
    if (ifs.fail())
    {
      std::cerr << "** Unable to open file " << argv[1] << " -- please try again\n";
      exit(EXIT_FAILURE);
    }
    ReadData(input, ifs);
  }

  // show data in original object:
  std::cout << "Data as entered: ";
  DisplayData(input, std::cout, ' ');
  std::cout << '\n';
  // */

  // display mean and median:
  std::cout << "Mean:   " << Mean(input) << '\n';
  std::cout << "Median: " << Median(input) << '\n';

  // display data after calls:
  std::cout << "Data after sort: ";
  DisplayData(input, std::cout, ' ');
  std::cout << '\n';
  // */

  return 0;
}
コード例 #2
0
ファイル: caasCLR4Tx1.cpp プロジェクト: JieZou1/CAAS
void caasCLR4Tx1::FindIsolatorAngle()
{
	//We cut 4/5 width of isolator out
	int height = 3 * (isolatorBottomEdge - isolatorTopEdge) / 2; int middle = (isolatorBottomEdge + isolatorTopEdge) / 2;
	Rect rect = Rect(isolatorRightEdge - 4 * isolatorWidth / 5, middle - height / 2, 4 * isolatorWidth / 5, height);
	Mat imageIsolator = imageGray(rect);
	int scale = 4;
	resize(imageIsolator, imageIsolator, Size(imageIsolator.cols / scale, imageIsolator.rows / scale));
#if _DEBUG
	imwrite("Isolator.jpg", imageIsolator);
#endif

	//sharpen the image
	//Unsharping masking: Use a Gaussian smoothing filter and subtract the smoothed version from the original image (in a weighted way so the values of a constant area remain constant). 
	Mat imageBlurred, imageGraySharpened;	double GAUSSIAN_RADIUS = 4.0;
	GaussianBlur(imageIsolator, imageBlurred, Size(0, 0), GAUSSIAN_RADIUS);
	addWeighted(imageIsolator, 1.5, imageBlurred, -0.5, 0, imageGraySharpened);
#if _DEBUG
	//imageGraySharpened = imageGrayQuarter;
	imwrite("IsolatorSharpened.jpg", imageGraySharpened);
#endif

	imageGraySharpened = imageIsolator;

	//Histogram Equalization
	equalizeHist(imageGraySharpened, imageGraySharpened);
#if _DEBUG
	imwrite("IsolatorEqualized.jpg", imageGraySharpened);
#endif

	//Otsu binarization
	Mat imageOtsu; threshold(imageGraySharpened, imageOtsu, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
#if _DEBUG
	imwrite("IsolatorOtsu.jpg", imageOtsu);
#endif

	//Canny Edge Detection
	int median = Median(imageGraySharpened);
	Mat imageCanny;  Canny(imageGraySharpened, imageCanny, 0.66 * median, 1.33 * median);
#if _DEBUG
	imwrite("IsolatorCanny.jpg", imageCanny);
#endif

}
コード例 #3
0
void testcases()
{
	int lv1,median=0;
	for(lv1=0;lv1<6;lv1++)
	{
		nodetype *head;
		head=createlist(test[lv1].input);
		median=Median(head);
		if(test[lv1].output==median)
		{}
		else
		{
			printf("test%d is failed",lv1+1);
			return ;
		}
		//display(head);
	}

	printf("tests are passed");
	return ;
}
コード例 #4
0
ファイル: caasCLR4Tx1.cpp プロジェクト: JieZou1/CAAS
void caasCLR4Tx1::RefineIsolator()
{
	//int width = isolatorRightEdge - isolatorLeftEdge;
	//int height = isolatorBottomEdge - isolatorTopEdge;
	//Expand horizontally 1 time to the right; expand vertically 1/2

	int left = isolatorLeftEdge;
	int right = left + 2 * isolatorWidth; if (right > targetLeftEdge - 20) right = targetLeftEdge - 20;
	int top = isolatorTopEdge - isolatorHeight / 4;
	int bottom = top + isolatorHeight + isolatorHeight / 2;
	Rect roi = Rect(left, top, right - left, bottom - top);
	imageIsolatorRoi = imageGray(roi);
#if _DEBUG
	imwrite("5.1.IsolatorRoi.jpg", imageIsolatorRoi);
#endif

	int scale = 4;
	resize(imageIsolatorRoi, imageIsolatorRoi, Size(imageIsolatorRoi.cols / scale, imageIsolatorRoi.rows / scale));

	Mat imageBlurred, imageGraySharpened;	double GAUSSIAN_RADIUS = 4.0;
	GaussianBlur(imageIsolatorRoi, imageBlurred, Size(0, 0), GAUSSIAN_RADIUS);
	addWeighted(imageIsolatorRoi, 2.5, imageBlurred, -1.5, 0, imageGraySharpened);
#if _DEBUG
	imwrite("5.2.IsolatorRoiSharpened.jpg", imageGraySharpened);
#endif

	int median = Median(imageGraySharpened);
	Mat imageCanny; Canny(imageGraySharpened, imageCanny, 0.66 * median, 1.33 * median);
#if _DEBUG
	imwrite("5.3.IsolatorRoiCanny.jpg", imageCanny);
#endif

	Mat Points;	findNonZero(imageCanny, Points);
	Rect Min_Rect = boundingRect(Points);
	isolatorRightEdge = roi.x + (Min_Rect.x + Min_Rect.width) * scale;
	RotatedRect rect = minAreaRect(Points);
	isolatorAngle = rect.angle;
}
コード例 #5
0
void main()
{
	long i,j,t,sort;

	/*freopen("in.txt","r",stdin);*/

	while(scanf("%d",&a[index])!=EOF)
	{
		if(index==1) printf("%ld\n",a[1]);
		else
		{
			sort=0;

			for(i=1; i<=index-1; i++)
			{
				if(a[index]<a[i])
				{
					sort=1;
					break;
				}
			}
			if(sort)
			{
				t=a[i];
				a[i]=a[index];
				for(j=index; j>i+1; j--)
				{
					a[j]=a[j-1];
				}
				a[i+1]=t;
			}

			Median();
		}
		index++;
	}
}
コード例 #6
0
ファイル: ministat.c プロジェクト: cemeyer/ministat-linux
static void
PlotSet(struct dataset *ds, int val)
{
	struct plot *pl;
	int i, j, m, x;
	unsigned n;
	int bar;

	pl = &plot;
	if (pl->span == 0)
		return;

	if (pl->separate_bars)
		bar = val-1;
	else
		bar = 0;

	if (pl->bar == NULL) {
		pl->bar = malloc(sizeof(char *) * pl->num_datasets);
		memset(pl->bar, 0, sizeof(char*) * pl->num_datasets);
	}
	if (pl->bar[bar] == NULL) {
		pl->bar[bar] = malloc(pl->width);
		memset(pl->bar[bar], 0, pl->width);
	}
	
	m = 1;
	i = -1;
	j = 0;
	for (n = 0; n < ds->n; n++) {
		x = (ds->points[n] - pl->x0) / pl->dx;
		if (x == i) {
			j++;
			if (j > m)
				m = j;
		} else {
			j = 1;
			i = x;
		}
	}
	m += 1;
	if (m > pl->height) {
		pl->data = realloc(pl->data, pl->width * m);
		memset(pl->data + pl->height * pl->width, 0,
		    (m - pl->height) * pl->width);
	}
	pl->height = m;
	i = -1;
	for (n = 0; n < ds->n; n++) {
		x = (ds->points[n] - pl->x0) / pl->dx;
		if (x == i) {
			j++;
		} else {
			j = 1;
			i = x;
		}
		pl->data[j * pl->width + x] |= val;
	}
	if (!isnan(Stddev(ds))) {
		x = ((Avg(ds) - Stddev(ds)) - pl->x0) / pl->dx;
		m = ((Avg(ds) + Stddev(ds)) - pl->x0) / pl->dx;
		pl->bar[bar][m] = '|';
		pl->bar[bar][x] = '|';
		for (i = x + 1; i < m; i++)
			if (pl->bar[bar][i] == 0)
				pl->bar[bar][i] = '_';
	}
	x = (Median(ds) - pl->x0) / pl->dx;
	pl->bar[bar][x] = 'M';
	x = (Avg(ds) - pl->x0) / pl->dx;
	pl->bar[bar][x] = 'A';
}
コード例 #7
0
ファイル: main.cpp プロジェクト: mgrebenkin/IPLabs
void main()
{
	std::string strInputFile;
	std::cout << "Input image file: ";	//запрос открываемого файла
	std::getline(std::cin, strInputFile);

	size_t nReqSize = NPngProc::readPngFile(strInputFile.c_str(), 0, 0, 0, 0);
	if (nReqSize == NPngProc::PNG_ERROR)
	{
		std::cout << std::endl << "Error ocured while png file was read." << std::endl;
		std::getchar();
		return;
	}

	unsigned char* pInputBits = new unsigned char[nReqSize];
	if (!pInputBits)
	{
		std::cout << "Can't allocate memory for image, required size is " << nReqSize << std::endl;
		std::getchar();
		return;
	}

	unsigned char* pOutputBits = new unsigned char[nReqSize];
	if (!pInputBits)
	{
		std::cout << "Can't allocate memory for image, required size is " << nReqSize << std::endl;
		std::getchar();
		return;
	}

	size_t nWidth, nHeight;
	unsigned int nBPP;

	size_t nRetSize = NPngProc::readPngFileGray(strInputFile.c_str(),
		pInputBits, &nWidth, &nHeight/*, &nBPP*/);
	nBPP = 8;


	NPngProc::SImage in(pInputBits, nWidth, nHeight, 8);
	NPngProc::SImage out(pOutputBits, nWidth, nHeight, 8);

	NPngProc::SImage apt(0, 0, 0, 8);

	MakeApt(apt);

	Median(in, out, apt);

	//получение имени нового файла

	std::string strOutputFile(strInputFile);
	int dotPos = strOutputFile.find_last_of('.');
	strOutputFile.insert(dotPos, "_proc");
	std::cout << "Name of output file is " << strOutputFile << std::endl;

	if (NPngProc::writePngFile(strOutputFile.c_str(),
		out.pBits, out.nWidth, out.nHeight, nBPP) == NPngProc::PNG_ERROR)
	{
		std::cout << "Error occured during png file was written." << std::endl;
		std::getchar();
		return;
	}

	std::getchar();
	return;
}
コード例 #8
0
char* CoronaSwingPosition (char* timeframe)
{

    static char timeframee[1000];
    strncpy(timeframee, timeframe, 1000);
    TimeFrame=atoi(timeframee);
    // Put your indicator C++ code here
int limit, y, i, shift, n, cnt_bars=1000; //IndicatorCounted(); 
   arrayofdoubles price, mDomCyc, DC, SmoothHP, HP, mPsn, Lead60, BP2;
price.assign(0);
mDomCyc.assign(0);
DC.assign(0);
SmoothHP.assign(0);
HP.assign(0);
mPsn.assign(0);
Lead60.assign(0);
BP2.assign(0);
double dB;
double Width;
   
   double pi = 4 * atan(1);
   
   //win = WindowFind(short_name);
      
   //if(TimeFrame!=Period()) int mBars = iBars(NULL,TimeFrame); else mBars = Bars; 
   int mBars = 666; //chartbars[displayedfile];  
   /*
   if(mBars != pBars)
   {
   ArrayResize(price,mBars);
   ArrayResize(mDomCyc,mBars);
   ArrayResize(DC,mBars);
   ArrayResize(SmoothHP,mBars);
   ArrayResize(HP,mBars);
   ArrayResize(mPsn,mBars);
   ArrayResize(Lead60,mBars);
   ArrayResize(BP2,mBars);   
      if(Price > 6 && Price <= 10)
      {
      ArrayResize(haClose,mBars);
      ArrayResize(haOpen,mBars);
      ArrayResize(haHigh,mBars);
      ArrayResize(haLow,mBars);
      }
  
   pBars = mBars;
   } 
*/ 
   pBars = mBars;

   if(cnt_bars<1)
   {
      //for(i=bars-1;i>0;i--) CoronaSwingPositionbuffer[i]=0;
	for(i=666-1;i>0;i--) CoronaSwingPositionbuffer[i]=0;
   mcnt_bars = 0;
   }
CoronaSwingPositionbuffer.assign(0);

//---- 
   if(mcnt_bars > 0) mcnt_bars--;
   
   //for(y=mcnt_bars+1;y<mBars;y++)
   for(y=0;y<mBars;y++)
   {
      if(Price <= 6) price[y] = ima(TimeFrame,1,0,0,Price,mBars-y-1);   
      else
      if(Price > 6 && Price <= 10) price[y] = HeikenAshi(TimeFrame,Price-7,mBars-y-1);
     
   double alpha1 = (1 - sin(2*pi/30)) / cos(2*pi/30);
   HP[y] = 0.5*(1 + alpha1)*(price[y] - price[y-1]) + alpha1*HP[y-1];
   SmoothHP[y] = (HP[y] + 2.0*HP[y-1] + 3.0*HP[y-2] + 3.0*HP[y-3] + 2.0*HP[y-4] + HP[y-5]) / 12.0;
   if(y < 6)  SmoothHP[y] = price[y] - price[y-1];
   if(y == 0) SmoothHP[y] = 0;
   
   double delta = -0.015*(y+1) + 0.5;
   if(delta < 0.1) delta = 0.1;
   
      if(y > 11)
      {
         if(itimeb(TimeFrame,mBars-y-1) != pTime)
         {
            for(n = 11; n<= 59; n++)
            { 
            OlderI[n] = OldI[n];
            OldI[n] = I[n];
            OlderQ[n] = OldQ[n];
            OldQ[n] = Q[n];
            OlderReal[n] = OldReal[n];
            OldReal[n] = Real[n];
            OlderImag[n] = OldImag[n];
            OldImag[n] = Imag[n];
            OldDB[n] = DB[n];
            }
         pTime = itimeb(TimeFrame,mBars-y-1);
         }
         
         for(n = 11; n<= 59; n++)
         { 	
         double beta = cos(4*pi/(n+1));
         double gamma = 1.0/cos(8*pi*delta/(n+1));
         double alpha = gamma - sqrt(gamma*gamma - 1);
         Q[n] = ((n+1)/4/pi)*(SmoothHP[y] - SmoothHP[y-1]);
         I[n] = SmoothHP[y];
         Real[n] = 0.5*(1 - alpha)*(I[n] - OlderI[n]) + beta*(1 + alpha)*OldReal[n] - alpha*OlderReal[n];
         Imag[n] = 0.5*(1 - alpha)*(Q[n] - OlderQ[n]) + beta*(1 + alpha)*OldImag[n] - alpha*OlderImag[n];
         Ampl[n] = (Real[n]*Real[n] + Imag[n]*Imag[n]);
         }	  
      
      MaxAmpl = Ampl[11];
      for(n = 11; n<= 59; n++) 
         if(Ampl[n] > MaxAmpl) {MaxAmpl = Ampl[n]; int nmax = n;}
   
         for(n = 11; n<= 59; n++)
         {
         if(MaxAmpl != 0) 
            if (Ampl[n] / MaxAmpl > 0) dB = -10.0*log(0.01/(1 - 0.99*Ampl[n]/MaxAmpl))/log(10.0);
         
         DB[n] = 0.33*dB + 0.67*OldDB[n];
         if(DB[n] > 20) DB[n] = 20;
         }   
         
         double Num = 0;
         double Denom = 0;
         for(n = 11; n<= 59; n++)
         {
            if(DB[n] <= 6) 
            {  
            Num = Num + (n+1)*(20 - DB[n]);
            Denom = Denom + (20 - DB[n]);
            }      
                 
         if(Denom != 0) DC[y] = 0.5*Num / Denom;
         else DC[y] = DC[y-1];
         }
      mDomCyc[y] = Median(DC, 5, y); 
      if(mDomCyc[y] < 6) mDomCyc[y] = 6; 
      
      double delta2 = 0.1;
      double beta2 = cos(2*pi/mDomCyc[y]);
      double gamma2 = 1.0/cos(4*pi*delta2/mDomCyc[y]);
      double alpha2 = gamma2 - sqrt(gamma2*gamma2 - 1);
      BP2[y] = 0.5*(1 - alpha2)*(price[y] - price[y-2]) + beta2*(1 + alpha2)*BP2[y-1] - alpha2*BP2[y-2];
      double Q2 = (mDomCyc[y]/2/pi)*(BP2[y] - BP2[y-1]);
      Lead60[y] = 0.5*BP2[y] + 0.866*Q2;

         double HL = Lead60[y];
         double LL = Lead60[y];
         for (i = 0; i<=50; i++)
         {
         if(Lead60[y-i] > HL) HL = Lead60[y-i];
         if(Lead60[y-i] < LL) LL = Lead60[y-i];
         }
      
      if((HL - LL) != 0) mPsn[y] = (Lead60[y] - LL)/(HL - LL);
      
         HL = mPsn[y];
         LL = mPsn[y];
         for (i = 0; i<=20; i++)
         { 
         if(mPsn[y-i] > HL) HL = mPsn[y-i];
	      if(mPsn[y-i] < LL) LL = mPsn[y-i];
         }
       
      if((HL - LL) > 0.85) Width = 0.01; else Width = 0.15*(HL - LL);	
      
         for(n = 1; n<= 50; n++)
         {
         Raster[n] = 20;
	      if(n <  round(50*mPsn[y]) && Width > 0) Raster[n] = 0.5*(pow(( 20*mPsn[y] - 0.4*n)/Width,0.95) + 0.5*OldRaster[n]);
	      if(n >  round(50*mPsn[y]) && Width > 0) Raster[n] = 0.5*(pow((-20*mPsn[y] + 0.4*n)/Width,0.95) + 0.5*OldRaster[n]);
	      if(n == round(50*mPsn[y])) Raster[n] = 0.5*OldRaster[n];
	  	   if(Raster[n] <   0) Raster[n] =  0;
	      if(Raster[n] >  20) Raster[n] = 20;
	      if((HL - LL) > 0.8) Raster[n] = 20;
	      OldRaster[n] = Raster[n];
         }
      }      
   
   //if(TimeFrame == Period() && VisualMode != 2) Psn[mBars-y-1] = 10*mPsn[y] - 5;
CoronaSwingPositionbuffer[mBars-y-1] = 10*mPsn[y] - 5;
   
   /*
   if(VisualMode != 1 && ((CoronaBars > 0 && y > mBars - CoronaBars)||(CoronaBars == 0 && y > draw_begin)))
      for(n = 1; n<= 50; n++)
      {
         if(Raster[n] <= 10)
         {
         int Color1 = LineR + Raster[n]*(FuzzR - LineR) / 10.0;
         int Color2 = LineG + Raster[n]*(FuzzG - LineG) / 10.0;
		   int Color3 = LineB + Raster[n]*(FuzzB - LineB) / 10.0;
         }
         else
         if(Raster[n] > 10)
         {
         Color1 = FuzzR*(2 - Raster[n] / 10.0);
         Color2 = FuzzG*(2 - Raster[n] / 10.0);
		   Color3 = FuzzB*(2 - Raster[n] / 10.0);
         }
      
     
      Plot(TimeFrame,FuzzWidth*n - 5 - 0.5*FuzzWidth,win+"CSP"+n+"_"+y, RGB(Color1, Color2, Color3),FuzzWidth,mBars-y-1);
      }   
   
   */
   
   
   mcnt_bars = mBars-1;
   }
   /*
   if(TimeFrame > Period() && VisualMode != 2)
   { 
      if(cnt_bars>0) cnt_bars--;
      limit = bars-cnt_bars+TimeFrame/Period()-1;
      
      for(shift=0,y=0;shift<limit;shift++)
      {
      if (Time[shift] < iTime(NULL,TimeFrame,y)) y++; 
      CoronaSwingPositionbuffer[shift] = 10* mPsn[mBars-y-1] - 5;
      }
   }
*/
//----------   
   //WindowRedraw();
   return(0);
}
コード例 #9
0
ファイル: caasCLR4Tx1.cpp プロジェクト: JieZou1/CAAS
/**
Step 2: Find the left edge of the target
Currently we use around 0.75 pixel per micron. So, 10 microns correspond to 7.5 pixels.
We reduce width and height to 1/4, which makes 10 microns correspond to 1.875 pixels, 50 microns --> 9.375 pixels, 
which should be large enough to have a dark strip between isolator right edge and target left edge. This dark strip is for detecting left edge of target.

We assume the target area should have high gradients, and the drak strip should have almost no gradients. 
So, we inspect the center 1/2 of the height of the image, and look for sudden gradient changes.
*/
void caasCLR4Tx1::FindTargetLeftEdge()
{
	int scale = 4; //We reduce the original image resolution

	resize(this->imageGray, imageOneFourth, Size(this->imageGray.cols / scale, this->imageGray.rows / scale));
	//Rect roi = Rect(0, 0, targetRightEdge / scale, imageGrayQuarter.rows);
	Rect roi = Rect(0, imageOneFourth.rows / 4, targetRightEdge / scale, imageOneFourth.rows / 2);
	imageOneFourthMiddleHalf = imageOneFourth(roi);
#if _DEBUG
	imwrite("2.1.OneFourthMiddleHalf.jpg", imageOneFourthMiddleHalf);
#endif

	//sharpen the image
	//Unsharping masking: Use a Gaussian smoothing filter and subtract the smoothed version from the original image (in a weighted way so the values of a constant area remain constant). 
	Mat imageBlurred, imageGraySharpened;	double GAUSSIAN_RADIUS = 4.0;
	GaussianBlur(imageOneFourthMiddleHalf, imageBlurred, Size(0, 0), GAUSSIAN_RADIUS);
	addWeighted(imageOneFourthMiddleHalf, 1.5, imageBlurred, -0.5, 0, imageGraySharpened);
#if _DEBUG
	//imageGraySharpened = imageGrayQuarter;
	imwrite("2.2.OneFourthMiddleHalfSharpened.jpg", imageGraySharpened);
#endif

	//Histogram Equalization
	equalizeHist(imageGraySharpened, imageGraySharpened);
#if _DEBUG
	imwrite("2.3.OneFourthMiddleHalfEqualized.jpg", imageGraySharpened);
#endif

	//Canny Edge Detection
	int median = Median(imageGraySharpened);
	Canny(imageGraySharpened, imageOneFourthMiddleHalfCanny, 0.66 * median, 1.33 * median);
#if _DEBUG
	imwrite("2.4.OneFourthMiddleHalfCanny.jpg", imageOneFourthMiddleHalfCanny);
#endif

	//vertical projection profile
	Mat verProjection(1, imageOneFourthMiddleHalfCanny.cols, CV_32FC1);
	reduce(imageOneFourthMiddleHalfCanny, verProjection, 0, CV_REDUCE_SUM, CV_32FC1); //Vertical projection generate Horizontal profile

	float minValue = -1.0, maxValue = -1.0; int minIndex, maxIndex; float values[4000]; float gradients[4000];
	ProjectionProfileAnalysis(verProjection, minValue, minIndex, maxValue, maxIndex, values);
	
	//Gradient(imageOneFourthMiddleHalfCanny.cols, values, gradients);
	////Find the largest gradient, that is the position of right edge of target
	////From left to right, this is a positive gradient, i.e., from low gradent value to high gradent value
	//float maxGrad = gradients[imageOneFourthMiddleHalfCanny.cols - 1]; int maxGradIndex = imageOneFourthMiddleHalfCanny.cols - 1;
	//for (int i = 1; i < 2 * (targetWidth / scale); i++) //We search in only 2 times of the expected target width
	//{
	//	int index = imageOneFourthMiddleHalfCanny.cols - 1 - i;
	//	if (gradients[index] > maxGrad) { maxGrad = gradients[index]; maxGradIndex = index; }
	//}
	//targetLeftEdge = maxGradIndex * scale;
	//return;

	//Find the average profile vaule in 3/4 of the target region
	float average = 0; int w = 3 * (targetWidth / 4) / 4;
	for (int i = 0; i < w; i++)		average += values[imageOneFourthMiddleHalfCanny.cols - 1 - i];
	average /= w;
	
	//Find the left edge of target
	//Search to left for a targtWidth, and find adrupt change
	float max_diff = -1; int max_pos = -1;
	for (int i = 0; i < targetWidth / scale; i++)
	{
		float value0 = values[imageOneFourthMiddleHalfCanny.cols - 1 - w - i];
		float value1 = values[imageOneFourthMiddleHalfCanny.cols - w - i];
		if (value0 > average / 2) continue;	//We are expecting the left of the edge has a lot less edges than arerage target area.
		//if (value1 < average) continue;	//We are expecting the edge has a lot less edges than the average target area.
		float diff = value1 - value0;
		if (diff > max_diff)
		{
			max_diff = diff; max_pos = imageOneFourthMiddleHalfCanny.cols - 1 - w - i;
		}
	}
	targetLeftEdge = max_pos * scale;
}
コード例 #10
0
ファイル: caasCLR4Tx1.cpp プロジェクト: JieZou1/CAAS
/**
Step 4: Find Isolator and its orientation
Currently we use around 0.75 pixel per micron. So, 10 microns correspond to 7.5 pixels.
We reduce width and height to 1/4, which makes 10 microns correspond to 1.875 pixels, 50 microns --> 9.375 pixels,

We assume the isolator has high texture, and therefore high gradients, and the regions between isolator and target has less gradients.
*/
void caasCLR4Tx1::FindIsolator()
{
	int high = targetBottomEdge - targetTopEdge, top = targetTopEdge + high / 4;
	RoiTargetLeftMiddleHalf = Rect(0, top, targetLeftEdge, high / 2); //We assume the isolator will be in the middle part of the target.
	imageTargetLeftMiddleHalf = imageGray(RoiTargetLeftMiddleHalf);
#if _DEBUG
	imwrite("4.1.TargetLeftMiddleHalf.jpg", imageTargetLeftMiddleHalf);
#endif

	int scale = 4; //We reduce the original image resolution

	resize(imageTargetLeftMiddleHalf, imageOneFourthTargetLeftMiddleHalf, Size(imageTargetLeftMiddleHalf.cols / scale, imageTargetLeftMiddleHalf.rows / scale));
#if _DEBUG
	imwrite("4.2.OneFourthTargetLeftMiddleHalf.jpg", imageOneFourthTargetLeftMiddleHalf);
#endif

	//sharpen the image
	//Unsharping masking: Use a Gaussian smoothing filter and subtract the smoothed version from the original image (in a weighted way so the values of a constant area remain constant). 
	Mat imageBlurred, imageGraySharpened;	double GAUSSIAN_RADIUS = 4.0;
	GaussianBlur(imageOneFourthTargetLeftMiddleHalf, imageBlurred, Size(0, 0), GAUSSIAN_RADIUS);
	addWeighted(imageOneFourthTargetLeftMiddleHalf, 1.5, imageBlurred, -0.5, 0, imageGraySharpened);
#if _DEBUG
	//imageGraySharpened = imageGrayQuarter;
	imwrite("4.3.OneFourthTargetLeftMiddleHalfSharpened.jpg", imageGraySharpened);
#endif

	//Histogram Equalization
	equalizeHist(imageGraySharpened, imageGraySharpened);
#if _DEBUG
	imwrite("4.4.OneFourthTargetLeftMiddleHalfEqualized.jpg", imageGraySharpened);
#endif

	//Canny Edge Detection
	int median = Median(imageGraySharpened);
	Canny(imageGraySharpened, imageOneFourthTargetLeftMiddleHalfCanny, 0.66 * median, 1.33 * median);
#if _DEBUG
	imwrite("4.5.OneFourthTargetLeftMiddleHalfCanny.jpg", imageOneFourthTargetLeftMiddleHalfCanny);
#endif

	{	//Find the isolator right edge
		//vertical projection profile
		Mat verProjection(1, imageOneFourthTargetLeftMiddleHalfCanny.cols, CV_32FC1);
		reduce(imageOneFourthTargetLeftMiddleHalfCanny, verProjection, 0, CV_REDUCE_SUM, CV_32FC1); //Vertical projection generate Horizontal profile
		float minValue = -1.0, maxValue = -1.0; int minIndex, maxIndex; float values[4000];
		ProjectionProfileAnalysis(verProjection, minValue, minIndex, maxValue, maxIndex, values);

		//Set the start and end 3 to be zero for convenience
		vector<int> starts, ends; int start, end;
		for (int i = 0; i < 3; i++)		{			values[verProjection.cols - 1 - i] = 0;			values[i] = 0;		}

		//Find all non-zero runs
		for (int i = verProjection.cols - 2; i >= 0; i--)
		{
			if (values[i + 1] < 0.5 && values[i] < 0.5) continue;
			if (values[i + 1] > 0.5 && values[i] > 0.5) continue;
			if (values[i + 1] < 0.5 && values[i] > 0.5) { end = i; continue; }
			if (values[i + 1] > 0.5 && values[i] < 0.5)
			{
				start = i + 1; starts.push_back(start); ends.push_back(end);
			}
		}

		//Check every runs, cut 3/4 of the expected isolator width, and we expect to see many edges (high profile values)
		for (int i = 0; i < starts.size(); i++)
		{
			end = ends[i]; start = end - 3 * (isolatorWidth / scale) / 4;
			float average = 0;
			for (int k = start; k <= end; k++)			average += values[k];
			average /= (float)(end - start + 1);

			if (average < 3) continue; //Has to be larger than a threshold

			isolatorRightEdge = end * scale;
			break;
		}
	}
	{	//Find isolator top and bottom edges
		//We just look at the half width of the isolator, trying to find its top and bottom edges
		isolatorLeftEdge = isolatorRightEdge - isolatorWidth / 2;
		Rect roi = Rect(isolatorLeftEdge / scale, 0, (isolatorRightEdge - isolatorLeftEdge) / scale, imageOneFourthTargetLeftMiddleHalfCanny.rows);
		imageIsolatorRoiCanny = imageOneFourthTargetLeftMiddleHalfCanny(roi);
#if _DEBUG
		imwrite("4.6.IsolatorRoiCanny.jpg", imageIsolatorRoiCanny);
#endif

		//horizontal projection profile
		Mat horProjection(imageIsolatorRoiCanny.rows, 1, CV_32FC1);
		reduce(imageIsolatorRoiCanny, horProjection, 1, CV_REDUCE_SUM, CV_32FC1); //horizontal projection generate vertical profile
		float minValue = -1.0, maxValue = -1.0; int minIndex, maxIndex; float values[4000];
		ProjectionProfileAnalysis(horProjection, minValue, minIndex, maxValue, maxIndex, values);

		//Find all 0's and remove 0's which are smaller than a threshold
		float prev, curr; vector<int> starts, ends;
		for (int i = 0; i <= imageIsolatorRoiCanny.rows; i++)
		{
			prev = i == 0 ? prev = 1 : values[i - 1];
			curr = i == imageIsolatorRoiCanny.rows ? 1 : values[i];

			if (prev > 0.5 && curr < 0.5) starts.push_back(i);
			if (prev < 0.5 && curr > 0.5) ends.push_back(i);
		}
		if (starts.size() == 0)
		{
			isolatorTopEdge = roi.y * scale; 
			isolatorBottomEdge = (roi.y + roi.height) * scale;
		}
		else
		{
			vector<int> zero_starts, zero_ends;
			for (int i = 0; i < starts.size(); i++)
			{
				int length = ends[i] - starts[i];
				if (length > 5) { zero_starts.push_back(starts[i]); zero_ends.push_back(ends[i]); }
			}
			//Pick one 1's, which is closest to the expected isolator width
			vector<int> one_starts, one_ends;
			if (zero_starts[0] != 0) { one_starts.push_back(0); one_ends.push_back(zero_starts[0]); }
			for (int i = 0; i < zero_starts.size() - 1; i++)
			{
				one_starts.push_back(zero_ends[i]);
				one_ends.push_back(zero_starts[i + 1]);
			}
			if (zero_ends[zero_ends.size() - 1] != imageIsolatorRoiCanny.rows) { one_starts.push_back(zero_ends[zero_ends.size() - 1]); one_ends.push_back(imageIsolatorRoiCanny.cols); }

			int min_index, min_diff = 4000;
			for (int i = 0; i < one_starts.size(); i++)
			{
				int length = one_ends[i] - one_starts[i];
				int diff = std::abs(length - this->isolatorWidth / scale);
				if (diff < min_diff) { min_diff = diff; min_index = i; }
			}

			isolatorTopEdge = this->RoiTargetLeftMiddleHalf.y + (roi.y + one_starts[min_index]) * scale;
			isolatorBottomEdge = this->RoiTargetLeftMiddleHalf.y + (roi.y + one_ends[min_index]) * scale;
		}
#if _DEBUG
		roi = Rect(isolatorLeftEdge, isolatorTopEdge, isolatorRightEdge - isolatorLeftEdge, isolatorBottomEdge - isolatorTopEdge);
		imageIsolator = imageGray(roi);
		imwrite("4.7.Isolator.jpg", imageIsolator);
#endif
	}
}
コード例 #11
0
ファイル: RV01.cpp プロジェクト: dpisarewski/rv
  void RV02::operator()(int argc,char *argv[]) {

	/*********************************************/
	/**** has always to be started (AMei)     ****/
    /**** if program is without gtk-Widgets   ****/
	/*********************************************/

	gtkServer server;
    server.start();

	/******************************************/
	/**** instantiation of used components ****/
	/******************************************/

	/*---------------------*/
	/* loaders and viewers */
    /*---------------------*/
    loadBMP loader;                         // object for loading .bmp-images

    viewer view("Original");                // object for visualizing images


	/*---------------------*/
	/* images & channels   */
    /*---------------------*/
    image img;                              // normalized (color) image
	channel8  src;  // source picture       // 8-bit-image (source)
    channel8  med;  // destination picture  // 8-bit-image (source) 
    channel8  grad;  // destination picture  // 8-bit-image (source) 
    channel8  dir;  // destination picture  // 8-bit-image (source) 


	/*-----------------------------*/
	/* Image processing components */
	/*-----------------------------*/

    // object to split image into hue, saturation and intensity
	// hue        = Farbton
	// saturation = Farbsättigung
	// intensity  = Intensität (Grauwert)
    splitImageToHSI splitter;



	/******************************************/
	/*    the program                         */
	/******************************************/

    // load the source image
    loader.load("shaft.bmp",img);
    
    // extract the intensity channel only
    splitter.getIntensity(img,src);
    splitter.getIntensity(img,med);
    splitter.getIntensity(img,grad);
    splitter.getIntensity(img,dir);

    // determine image size
    const int rowSize    = src.rows();
    const int columnSize = src.columns();


    // set destination size to source size 
    med.resize(rowSize,columnSize,0,false,true);
    grad.resize(rowSize,columnSize,0,false,true);
    dir.resize(rowSize,columnSize,0,false,true);

	// MEDIAN
    Median(src,med,9,9);

    view.show(src);
	viewer viewMed("Median");
    viewMed.show(med);

	// SOBEL
	Sobel(src, grad, dir);

    view.show(src);
	viewer viewGrad("Gradient");
	viewer viewDir("Direction");
    viewGrad.show(grad);
    viewDir.show(dir);
	


	// view pictures

    getchar();

  }
コード例 #12
0
ファイル: Sorting.cpp プロジェクト: mrevow/interviews-Sorting
int main(int argc, char* argv[])
{
	int seed = 40;
	int n = 10;
	int max = 100;

	int *a = nullptr;

	// Insertion sort
	a = CreatA(a, n, seed, max);
	printArray(a, n, "Original");

	InsertionSort(a, n);
	//printArray(a, n, "InsertSort");
	VerifySorted(a, n);

	// Selection sort
	a = CreatA(a, n, seed, max);
	SelectionSort(a, n);
	//printArray(a, n, "selectSort");
	VerifySorted(a, n);

	a = CreatA(a, n, seed, max);
	MergeSort(a, n);
	//printArray(a, n, "MergeSort");
	VerifySorted(a, n);

	a = CreatA(a, n, seed, max);
	QuickSort(a, n);
	//printArray(a, n, "QuickSort");
	VerifySorted(a, n);

	a = CreatA(a, n, seed, max);
	BubbleSort(a, n);
	printArray(a, n, "BubbleSort");
	VerifySorted(a, n);

	int value = 22;
	//BinarySearch(a, n, value);
	//BinarySearchIter(a, n, value);
	//RunBinarySearchCircular(a, n, value);

	value = 27;
	/*BinarySearch(a, n, value);
	BinarySearchIter(a, n, value);
	RunBinarySearchCircular(a, n, value);
*/
	a = CreatA(a, n, seed, max);
	printArray(a, n, "Pre  min heap sort");
	RunSortMinHeap(a, n);
	printArray(a, n, "MinHeapSort");
	VerifySorted(a, n);

	a = CreatA(a, n, seed, max);
	printArray(a, n, "Pre  max heap sort");
	RunSortMaxHeap(a, n);
	printArray(a, n, "MaxHeapSort");
	VerifySorted(a, n);

	printf("\nMedian %d\n", Median(a, n));

	return 0;
}
コード例 #13
0
ファイル: Histogram.cpp プロジェクト: assutech/isis3
 /**
  * Computes and returns the skew. If there are no valid pixels then NULL8 is
  * returned. Recognize that because of the binning which occurs, in order to
  * generate the histogram, the skew may not be precise but will be very close.
  *
  * @return The skew.
  */
 double Histogram::Skew() const {
   if (ValidPixels() < 1) return Isis::NULL8;
   double sdev = StandardDeviation();
   if (sdev == 0.0) return 0.0;
   return 3.0 * (Average() - Median()) / sdev;
 }
コード例 #14
0
/**
 * @return always returns 0.
 */
UINT LastCommonRouteFinder::RunInternal() {
	Pinger pinger;
	bool hasSucceededAtLeastOnce = false;

	while(doRun) {
		// wait for updated prefs
		prefsEvent->Lock();

		bool enabled = m_enabled;

		// retry loop. enabled will be set to false in end of this loop, if to many failures (tries too large)
		while(doRun && enabled) {
			bool foundLastCommonHost = false;
			uint32 lastCommonHost = 0;
			uint32 lastCommonTTL = 0;
			uint32 hostToPing = 0;
			bool useUdp = false;

			hostsToTraceRoute.RemoveAll();

			pingDelays.RemoveAll();
			pingDelaysTotal = 0;

			pingLocker.Lock();
			m_pingAverage = 0;
			m_lowestPing = 0;
			m_state = GetResString(IDS_USS_STATE_PREPARING);
			pingLocker.Unlock();

			// Calculate a good starting value for the upload control. If the user has entered a max upload value, we use that. Otherwise 10 KBytes/s
			int startUpload = (maxUpload != _UI32_MAX)?maxUpload:10*1024;

			bool atLeastOnePingSucceded = false;
			while(doRun && enabled && foundLastCommonHost == false) {
				uint32 traceRouteTries = 0;
				while(doRun && enabled && foundLastCommonHost == false && (traceRouteTries < 5 || hasSucceededAtLeastOnce && traceRouteTries < _UI32_MAX) && (hostsToTraceRoute.GetCount() < 10 || hasSucceededAtLeastOnce)) {
					traceRouteTries++;

					lastCommonHost = 0;

					CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Try #%i. Collecting hosts..."), traceRouteTries);

					addHostLocker.Lock();
					needMoreHosts = true;
					addHostLocker.Unlock();

					// wait for hosts to traceroute
					newTraceRouteHostEvent->Lock();

					CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Got enough hosts. Listing the hosts that will be tracerouted:"));

					POSITION pos = hostsToTraceRoute.GetStartPosition();
					int counter = 0;
					while(pos != NULL) {
						counter++;
						uint32 hostToTraceRoute, dummy;
                        hostsToTraceRoute.GetNextAssoc(pos, hostToTraceRoute, dummy);
						IN_ADDR stDestAddr;
						stDestAddr.s_addr = hostToTraceRoute;

						CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Host #%i: %s"), counter, ipstr(stDestAddr));
					}

					// find the last common host, using traceroute
					CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Starting traceroutes to find last common host."));

					// for the tracerouting phase (preparing...) we need to disable uploads so we get a faster traceroute and better ping values.
					SetUpload(2*1024);
					Sleep(SEC2MS(1));

					if(m_enabled == false) {
						enabled = false;
                    }

					bool failed = false;

					uint32 curHost = 0;
					for(uint32 ttl = 1; doRun && enabled && (curHost != 0 && ttl <= 64 || curHost == 0 && ttl < 5) && foundLastCommonHost == false && failed == false; ttl++) {
						CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Pinging for TTL %i..."), ttl);

						useUdp = false; // PENDING: Get default value from prefs?

						curHost = 0;
						if(m_enabled == false) {
							enabled = false;
                        }

						uint32 lastSuccedingPingAddress = 0;
                        uint32 lastDestinationAddress = 0;
                        uint32 hostsToTraceRouteCounter = 0;
                        bool failedThisTtl = false;
						POSITION pos = hostsToTraceRoute.GetStartPosition();
                        while(doRun && enabled && failed == false && failedThisTtl == false && pos != NULL &&
                              ( lastDestinationAddress == 0 || lastDestinationAddress == curHost)) // || pingStatus.success == false && pingStatus.error == IP_REQ_TIMED_OUT ))
						{
    						PingStatus pingStatus = {0};

                            hostsToTraceRouteCounter++;

							// this is the current address we send ping to, in loop below.
							// PENDING: Don't confuse this with curHost, which is unfortunately almost
							// the same name. Will rename one of these variables as soon as possible, to
							// get more different names.
							uint32 curAddress, dummy;
                            hostsToTraceRoute.GetNextAssoc(pos, curAddress, dummy);

							pingStatus.success = false;
							for(int counter = 0; doRun && enabled && counter < 2 && (pingStatus.success == false || pingStatus.success == true && pingStatus.status != IP_SUCCESS && pingStatus.status != IP_TTL_EXPIRED_TRANSIT); counter++) {
								pingStatus = pinger.Ping(curAddress, ttl, true, useUdp);
								if(doRun && enabled &&
                                   (
                                    pingStatus.success == false ||
                                    pingStatus.success == true &&
                                    pingStatus.status != IP_SUCCESS &&
                                    pingStatus.status != IP_TTL_EXPIRED_TRANSIT
                                   ) &&
                                   counter < 3-1)
                                {
									IN_ADDR stDestAddr;
									stDestAddr.s_addr = curAddress;
                                    CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Failure #%i to ping host! (TTL: %i IP: %s error: %i). Sleeping 1 sec before retry. Error info follows."), counter+1, ttl, ipstr(stDestAddr), (pingStatus.success)?pingStatus.status:pingStatus.error);
									pinger.PIcmpErr((pingStatus.success)?pingStatus.status:pingStatus.error);

									Sleep(1000);

									if(m_enabled == false)
										enabled = false;

									// trying other ping method
									useUdp = !useUdp;
								}
							}

							if(pingStatus.success == true && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) {
								if(curHost == 0)
									curHost = pingStatus.destinationAddress;
								atLeastOnePingSucceded = true;
								lastSuccedingPingAddress = curAddress;
                                lastDestinationAddress = pingStatus.destinationAddress;
							} else {
								// failed to ping this host for some reason.
								// Or we reached the actual host we are pinging. We don't want that, since it is too close.
								// Remove it.
								IN_ADDR stDestAddr;
								stDestAddr.s_addr = curAddress;
								if(pingStatus.success == true && pingStatus.status == IP_SUCCESS) {
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Host was too close! Removing this host. (TTL: %i IP: %s status: %i). Removing this host and restarting host collection."), ttl, ipstr(stDestAddr), pingStatus.status);

									hostsToTraceRoute.RemoveKey(curAddress);
								} else if(pingStatus.success == true && pingStatus.status == IP_DEST_HOST_UNREACHABLE) {
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Host unreacheable! (TTL: %i IP: %s status: %i). Removing this host. Status info follows."), ttl, ipstr(stDestAddr), pingStatus.status);
									pinger.PIcmpErr(pingStatus.status);

									hostsToTraceRoute.RemoveKey(curAddress);
                                } else if(pingStatus.success == true) {
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Unknown ping status! (TTL: %i IP: %s status: %i). Reason follows. Changing ping method to see if it helps."), ttl, ipstr(stDestAddr), pingStatus.status);
									pinger.PIcmpErr(pingStatus.status);
									useUdp = !useUdp;
								} else {
									if(pingStatus.error == IP_REQ_TIMED_OUT) {
										CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Timeout when pinging a host! (TTL: %i IP: %s Error: %i). Keeping host. Error info follows."), ttl, ipstr(stDestAddr), pingStatus.error);
										pinger.PIcmpErr(pingStatus.error);

                                        if(hostsToTraceRouteCounter > 2 && lastSuccedingPingAddress == 0) {
                                            // several pings have timed out on this ttl. Probably we can't ping on this ttl at all
                                            failedThisTtl = true;
                                        }
                                    } else {
									    CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Unknown pinging error! (TTL: %i IP: %s status: %i). Reason follows. Changing ping method to see if it helps."), ttl, ipstr(stDestAddr), pingStatus.error);
										pinger.PIcmpErr(pingStatus.error);
    									useUdp = !useUdp;
									}
								}

                                if(hostsToTraceRoute.GetSize() <= 8) {
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: To few hosts to traceroute left. Restarting host colletion."));
                                    failed = true;
                                }
							}
						}

						if(failed == false) {
							if(curHost != 0 && lastDestinationAddress != 0) {
								if(lastDestinationAddress == curHost) {
									IN_ADDR stDestAddr;
									stDestAddr.s_addr = curHost;
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Host at TTL %i: %s"), ttl, ipstr(stDestAddr));

									lastCommonHost = curHost;
									lastCommonTTL = ttl;
								} else /*if(lastSuccedingPingAddress != 0)*/ {
									foundLastCommonHost = true;
									hostToPing = lastSuccedingPingAddress;

									CString hostToPingString = ipstr(hostToPing);

									if(lastCommonHost != 0) {
										CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Found differing host at TTL %i: %s. This will be the host to ping."), ttl, hostToPingString);
									} else {
										CString lastCommonHostString = ipstr(lastDestinationAddress);

										lastCommonHost = lastDestinationAddress;
										lastCommonTTL = ttl;
										CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Found differing host at TTL %i, but last ttl couldn't be pinged so we don't know last common host. Taking a chance and using first differing ip as last commonhost. Host to ping: %s. Faked LastCommonHost: %s"), ttl, hostToPingString, lastCommonHostString);
									}
								}
							} else {
								if(ttl < 4) {
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Could perform no ping at all at TTL %i. Trying next ttl."), ttl);
								} else {
									CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Could perform no ping at all at TTL %i. Giving up."), ttl);
                                }
								lastCommonHost = 0;
							}
						}
					}

					if(foundLastCommonHost == false && traceRouteTries >= 3) {
						CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Tracerouting failed several times. Waiting a few minutes before trying again."));

                        SetUpload(maxUpload);

						pingLocker.Lock();
						m_state = GetResString(IDS_USS_STATE_WAITING);
						pingLocker.Unlock();

						prefsEvent->Lock(3*60*1000);

                        pingLocker.Lock();
						m_state = GetResString(IDS_USS_STATE_PREPARING);
                        pingLocker.Unlock();
					}

			        if(m_enabled == false) {
				        enabled = false;
                    }
				}

                if(enabled) {
				    CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Done tracerouting. Evaluating results."));

				    if(foundLastCommonHost == true) {
					    IN_ADDR stLastCommonHostAddr;
					    stLastCommonHostAddr.s_addr = lastCommonHost;

					    // log result
					    CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Found last common host. LastCommonHost: %s @ TTL: %i"), ipstr(stLastCommonHostAddr), lastCommonTTL);

					    IN_ADDR stHostToPingAddr;
					    stHostToPingAddr.s_addr = hostToPing;
					    CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Found last common host. HostToPing: %s"), ipstr(stHostToPingAddr));
				    } else {
					    CGlobalVariable::QueueDebugLogLine(false,GetResString(IDS_USS_TRACEROUTEOFTENFAILED));
						CGlobalVariable::QueueLogLine(true, GetResString(IDS_USS_TRACEROUTEOFTENFAILED));
					    enabled = false;

					    pingLocker.Lock();
						m_state = GetResString(IDS_USS_STATE_ERROR);
					    pingLocker.Unlock();

					    // PENDING: this may not be thread safe
					    thePrefs.SetDynUpEnabled(false);
				    }
                }
			}

			if(m_enabled == false) {
				enabled = false;
            }

			if(doRun && enabled) {
				CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Finding a start value for lowest ping..."));
            }

			// PENDING:
			prefsLocker.Lock();
			uint64 lowestInitialPingAllowed = m_LowestInitialPingAllowed;
			prefsLocker.Unlock();

			uint32 initial_ping = _I32_MAX;

			bool foundWorkingPingMethod = false;
			// finding lowest ping
			for(int initialPingCounter = 0; doRun && enabled && initialPingCounter < 10; initialPingCounter++) {
				Sleep(200);

				PingStatus pingStatus = pinger.Ping(hostToPing, lastCommonTTL, true, useUdp);

				if (pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) {
					foundWorkingPingMethod = true;

					if(pingStatus.delay > 0 && pingStatus.delay < initial_ping) {
						initial_ping = (UINT)max(pingStatus.delay, lowestInitialPingAllowed);
                    }
				} else {
					CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: %s-Ping #%i failed. Reason follows"), useUdp?_T("UDP"):_T("ICMP"), initialPingCounter);
					pinger.PIcmpErr(pingStatus.error);

					// trying other ping method
					if(!pingStatus.success && !foundWorkingPingMethod) {
						useUdp = !useUdp;
                    }
				}

				if(m_enabled == false) {
					enabled = false;
                }
			}

			// Set the upload to a good starting point
			SetUpload(startUpload);
			Sleep(SEC2MS(1));
			DWORD initTime = ::GetTickCount();

			// if all pings returned 0, initial_ping will not have been changed from default value.
			// then set initial_ping to lowestInitialPingAllowed
			if(initial_ping == _I32_MAX)
                initial_ping = (UINT)lowestInitialPingAllowed;

			uint32 upload = 0;

			hasSucceededAtLeastOnce = true;

			if(doRun && enabled) {
				if(initial_ping > lowestInitialPingAllowed) {
					CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Lowest ping: %i ms"), initial_ping);
				} else {
					CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Lowest ping: %i ms. (Filtered lower values. Lowest ping is never allowed to go under %i ms)"), initial_ping, lowestInitialPingAllowed);
                }
				prefsLocker.Lock();
				upload = m_CurUpload;

				if(upload < minUpload) {
					upload = minUpload;
                }
				if(upload > maxUpload) {
					upload = maxUpload;
                }
				prefsLocker.Unlock();
			}

			if(m_enabled == false) {
				enabled = false;
            }

			if(doRun && enabled) {
				CGlobalVariable::QueueDebugLogLine(false, GetResString(IDS_USS_STARTING));
				CGlobalVariable::QueueLogLine(true, GetResString(IDS_USS_STARTING)  );
            }

			pingLocker.Lock();
			m_state = _T("");
			pingLocker.Unlock();

			// There may be several reasons to start over with tracerouting again.
			// Currently we only restart if we get an unexpected ip back from the
			// ping at the set TTL.
			bool restart = false;

			DWORD lastLoopTick = ::GetTickCount();
			DWORD lastUploadReset = 0;

			while(doRun && enabled && restart == false) {
				DWORD ticksBetweenPings = 1000;
				if(upload > 0) {
					// ping packages being 64 bytes, this should use 1% of bandwidth (one hundredth of bw).
					ticksBetweenPings = (64*100*1000)/upload;

					if(ticksBetweenPings < 125) {
					    // never ping more than 8 packages a second
						ticksBetweenPings = 125;
					} else if(ticksBetweenPings > 1000) {
						ticksBetweenPings = 1000;
                    }
				}

				DWORD curTick = ::GetTickCount();

				DWORD timeSinceLastLoop = curTick-lastLoopTick;
				if(timeSinceLastLoop < ticksBetweenPings) {
					//CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Sleeping %i ms, timeSinceLastLoop %i ms ticksBetweenPings %i ms"), ticksBetweenPings-timeSinceLastLoop, timeSinceLastLoop, ticksBetweenPings);
					Sleep(ticksBetweenPings-timeSinceLastLoop);
				}

				lastLoopTick = curTick;

				prefsLocker.Lock();
				double pingTolerance = m_pingTolerance;
				uint32 pingToleranceMilliseconds = m_iPingToleranceMilliseconds;
				bool useMillisecondPingTolerance = m_bUseMillisecondPingTolerance;
				uint32 goingUpDivider = m_goingUpDivider;
				uint32 goingDownDivider = m_goingDownDivider;
				uint32 numberOfPingsForAverage = m_iNumberOfPingsForAverage;
				lowestInitialPingAllowed = m_LowestInitialPingAllowed; // PENDING
                uint32 curUpload = m_CurUpload;

                bool initiateFastReactionPeriod = m_initiateFastReactionPeriod;
                m_initiateFastReactionPeriod = false;
				prefsLocker.Unlock();

                if(initiateFastReactionPeriod) {
                    CGlobalVariable::QueueDebugLogLine(false, GetResString(IDS_USS_MANUALUPLOADLIMITDETECTED));
					CGlobalVariable::QueueLogLine(true, GetResString(IDS_USS_MANUALUPLOADLIMITDETECTED) );

                    // the first 60 seconds will use hardcoded up/down slowness that is faster
                    initTime = ::GetTickCount();
                }

				DWORD tempTick = ::GetTickCount();

				if(tempTick - initTime < SEC2MS(20)) {
					goingUpDivider = 1;
					goingDownDivider = 1;
                } else if(tempTick - initTime < SEC2MS(30)) {
                    goingUpDivider = (UINT)(goingUpDivider * 0.25);
                    goingDownDivider = (UINT)(goingDownDivider * 0.25);
                } else if(tempTick - initTime < SEC2MS(40)) {
                    goingUpDivider = (UINT)(goingUpDivider * 0.5);
                    goingDownDivider = (UINT)(goingDownDivider * 0.5);
                } else if(tempTick - initTime < SEC2MS(60)) {
                    goingUpDivider = (UINT)(goingUpDivider * 0.75);
                    goingDownDivider = (UINT)(goingDownDivider * 0.75);
				} else if(tempTick - initTime < SEC2MS(61)) {
					lastUploadReset = tempTick;
					prefsLocker.Lock();
					upload = m_CurUpload;
					prefsLocker.Unlock();
				}

                goingDownDivider = max(goingDownDivider, 1);
                goingUpDivider = max(goingUpDivider, 1);

				uint32 soll_ping = (UINT)(initial_ping*pingTolerance);
				if (useMillisecondPingTolerance) {
					soll_ping = pingToleranceMilliseconds; 
				} else {
					soll_ping = (UINT)(initial_ping*pingTolerance);
                }

				uint32 raw_ping = soll_ping; // this value will cause the upload speed not to change at all.

				bool pingFailure = false;        
				for(uint64 pingTries = 0; doRun && enabled && (pingTries == 0 || pingFailure) && pingTries < 60; pingTries++) {
                    if(m_enabled == false) {
                        enabled = false;
                    }

					// ping the host to ping
					PingStatus pingStatus = pinger.Ping(hostToPing, lastCommonTTL, false, useUdp);

					if(pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) {
						if(pingStatus.destinationAddress != lastCommonHost) {
							// something has changed about the topology! We got another ip back from this ttl than expected.
							// Do the tracerouting again to figure out new topology
							CString lastCommonHostAddressString = ipstr(lastCommonHost);
							CString destinationAddressString = ipstr(pingStatus.destinationAddress);

							CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Network topology has changed. TTL: %i Expected ip: %s Got ip: %s Will do a new traceroute."), lastCommonTTL, lastCommonHostAddressString, destinationAddressString);
							restart = true;
						}

						raw_ping = (uint32)pingStatus.delay;

						if(pingFailure) {
							// only several pings in row should fails, the total doesn't count, so reset for each successful ping
							pingFailure = false;

							//CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Ping #%i successful. Continuing."), pingTries);
						}
					} else {
						raw_ping = soll_ping*3+initial_ping*3; // this value will cause the upload speed be lowered.

						pingFailure = true;

                        if(m_enabled == false) {
				            enabled = false;
                        } else if(pingTries > 3) {
							prefsEvent->Lock(1000);
                        }

						//CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: %s-Ping #%i failed. Reason follows"), useUdp?_T("UDP"):_T("ICMP"), pingTries);
						//pinger.PIcmpErr(pingStatus.error);
					}

                    if(m_enabled == false) {
				        enabled = false;
                    }
				}

				if(pingFailure) {
                    if(enabled) {
					    CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: No response to pings for a long time. Restarting..."));
                    }
					restart = true;
				}

				if(restart == false) {
					if(raw_ping > 0 && raw_ping < initial_ping && initial_ping > lowestInitialPingAllowed) {
						CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: New lowest ping: %i ms. Old: %i ms"), max(raw_ping,lowestInitialPingAllowed), initial_ping);
						initial_ping = (UINT)max(raw_ping, lowestInitialPingAllowed);
					}

					pingDelaysTotal += raw_ping;
					pingDelays.AddTail(raw_ping);
					while(!pingDelays.IsEmpty() && (uint32)pingDelays.GetCount() > numberOfPingsForAverage) {
						uint32 pingDelay = pingDelays.RemoveHead();
						pingDelaysTotal -= pingDelay;
					}

                    uint32 pingAverage = Median(pingDelays); //(pingDelaysTotal/pingDelays.GetCount());
					int normalized_ping = pingAverage - initial_ping;

                    //{
                    //    prefsLocker.Lock();
                    //    uint32 tempCurUpload = m_CurUpload;
                    //    prefsLocker.Unlock();

                    //    CGlobalVariable::QueueDebugLogLine(false, _T("USS-Debug: %i %i %i"), raw_ping, upload, tempCurUpload);
                    //}

					pingLocker.Lock();
					m_pingAverage = (UINT)pingAverage;
					m_lowestPing = initial_ping;
					pingLocker.Unlock();

					// Calculate Waiting Time
					sint64 hping = ((int)soll_ping) - normalized_ping;

					// Calculate change of upload speed
					if(hping < 0) {
						//Ping too high
						acceptNewClient = false;

						// lower the speed
						sint64 ulDiff = hping*1024*10 / (sint64)(goingDownDivider*initial_ping);

						//CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Down! Ping cur %i ms. Ave %I64i ms %i values. New Upload %i + %I64i = %I64i"), raw_ping, pingDelaysTotal/pingDelays.GetCount(), pingDelays.GetCount(), upload, ulDiff, upload+ulDiff);
						// prevent underflow
						if(upload > -ulDiff) {
							upload = (UINT)(upload + ulDiff);
						} else {
							upload = 0;
						}
					} else if(hping > 0) {
						//Ping lower than max allowed
						acceptNewClient = true;

						if(curUpload+30*1024 > upload) {
						    // raise the speed
						    uint64 ulDiff = hping*1024*10 / (uint64)(goingUpDivider*initial_ping);
    
						    //CGlobalVariable::QueueDebugLogLine(false,_T("UploadSpeedSense: Up! Ping cur %i ms. Ave %I64i ms %i values. New Upload %i + %I64i = %I64i"), raw_ping, pingDelaysTotal/pingDelays.GetCount(), pingDelays.GetCount(), upload, ulDiff, upload+ulDiff);
						    // prevent overflow
						    if(_I32_MAX-upload > ulDiff) {
							    upload = (UINT)(upload + ulDiff);
						    } else {
							    upload = _I32_MAX;
                            }
						}
					}
					prefsLocker.Lock();
					if (upload < minUpload) {
						upload = minUpload;
						acceptNewClient = true;
					}
					if (upload > maxUpload) {
						upload = maxUpload;
                    }
					prefsLocker.Unlock();
					SetUpload(upload);
                    if(m_enabled == false) {
						enabled = false;
                    }
				}
			}
		}
	}

	// Signal that we have ended.
	threadEndedEvent->SetEvent();

	return 0;
}