//generate training set for given viewport (training purposes) private ArrayList generateTrainingSet(BaseTypes.viewport vprt, Bitmap bmp) { int smallShift; int largeShift; int CoordX,CoordY, Radius = 0,Width,Height; Point TL = new Point(0,0); double[] temporaryDoubleVector; //training set element ByteVector temporaryByteVector; //reqd to obtain double vector ArrayList trainingSet=new ArrayList(); Rectangle crop; switch (vprt) { case BaseTypes.viewport.XY: { smallShift=xyRadius+(int)(0.5*xyRadius); largeShift=xyRadius*2;//+(int)(0.5*xyRadius); CoordX=xyCoordX; CoordY=xyCoordY; Radius=xyRadius; break; } case BaseTypes.viewport.XZ: { smallShift=xzRadius+(int)(0.5*xzRadius); largeShift=xzRadius*2;//+(int)(0.5*xzRadius); CoordX=xzCoordX; CoordY=xzCoordZ; Radius=xzRadius; break; } case BaseTypes.viewport.YZ: { smallShift=yzRadius+(int)(0.5*yzRadius); largeShift=yzRadius*2;//+(int)(0.5*yzRadius); CoordX=yzCoordY; CoordY=yzCoordZ; Radius=yzRadius; break; } default : { smallShift=xyRadius+(int)(0.5*xyRadius); largeShift=xyRadius*2;//+(int)(0.5*xyRadius); CoordX=xyCoordX; CoordY=xyCoordY; Radius=xyRadius; break; } } smallShift=Radius; largeShift=Radius+(int)(0.5*xyRadius); Width=Height=Radius*2; //add sixteen wrong answers (image shifted by 50% and 75%) for (int x=-1; x<2; x++) for (int y=-1; y<2; y++) { if (!((x==0) && (y==0))) //To bylaby poprawna dana { int a = (int)x*(int)smallShift; TL.X=(CoordX-Radius)+a; a =(int)y*(int)smallShift; TL.Y=(CoordY-Radius)+a; crop = new Rectangle(TL.X,TL.Y,Width,Height); temporaryByteVector=new ByteVector(BitmapFilters.CropBitmap(bmp, crop)); temporaryDoubleVector=temporaryByteVector.GetDoubleVector(); trainingSet.Add(temporaryDoubleVector); a = (int)x*(int)largeShift; TL.X=(CoordX-Radius)+a; a =(int)y*(int)largeShift; TL.Y=(CoordY-Radius)+a; crop = new Rectangle(TL.X,TL.Y,Width,Height); temporaryByteVector=new ByteVector(BitmapFilters.CropBitmap(bmp, crop)); temporaryDoubleVector=temporaryByteVector.GetDoubleVector(); trainingSet.Add(temporaryDoubleVector); } } //the following code caused not really good results during precise tracking, but still helps //add eight correct answers (genuine image shifted by 1) for (int x=-1; x<2; x++) for (int y=-1; y<2; y++) { if (!((x==0) && (y==0))) //To bylaby poprawna dana { int a = (int)x*(int)1; TL.X=(CoordX-Radius)+a; a =(int)y*(int)1; TL.Y=(CoordY-Radius)+a; crop = new Rectangle(TL.X,TL.Y,Width,Height); temporaryByteVector=new ByteVector(BitmapFilters.CropBitmap(bmp, crop)); temporaryDoubleVector=temporaryByteVector.GetDoubleVector(); trainingSet.Add(temporaryDoubleVector); } } //add eight answer vectors from genuine image for (int x=0; x<8; x++) { crop = new Rectangle((CoordX-Radius),(CoordY-Radius),Width,Height); temporaryByteVector=new ByteVector(BitmapFilters.CropBitmap(bmp, crop)); temporaryDoubleVector=temporaryByteVector.GetDoubleVector(); trainingSet.Add(temporaryDoubleVector); } return trainingSet; }
// The thread procedure performs the task public void ThreadProc() { ArrayList pointsFound = new ArrayList(); Point TL = new Point(0,0); Point BR = new Point(0,0); Rectangle crop; double[] answer=new double[4]; double[] answerYes=new double[4]{1,1,1,1}; double threshold=acceptanceThreshold; threshold/=100; int xAvg=0,yAvg=0; for (int i=scanArea.Left; i<scanArea.Width-(Radius*2); i++) { for (int j=scanArea.Top;j<scanArea.Height-(Radius*2); j++) { TL.X=scanArea.Left+((i+1)-scanArea.Left); TL.Y=scanArea.Top+((j+1)-scanArea.Top); BR.X=Radius*2; BR.Y=Radius*2; crop=new Rectangle(TL.X,TL.Y,BR.X,BR.Y); ByteVector tempByteVector= new ByteVector(BitmapFilters.CropBitmap(bmp,crop)); answer=Ann.Calculate(tempByteVector.GetDoubleVector()); if ( (answer[0]>answerYes[0]*threshold) && (answer[1]>answerYes[1]*threshold) && (answer[2]>answerYes[2]*threshold) && (answer[3]>answerYes[3]*threshold) ) { pointsFound.Add(new Point(crop.X+Radius, crop.Y+Radius)); break; } } } bool tracked=true; if (pointsFound.Count>0) { foreach (Point pt in pointsFound) { xAvg+=pt.X; yAvg+=pt.Y; } xAvg=(int)(xAvg/pointsFound.Count); yAvg=(int)(yAvg/pointsFound.Count); } else { MessageBox.Show("Alert! Point not found!!! Viewport: " + Convert.ToString(this.vprt),"Point tracking failed!",MessageBoxButtons.OK,MessageBoxIcon.Warning); xAvg=(int)(scanArea.Left); yAvg=(int)(scanArea.Top); tracked=false; } if (callback != null) callback(xAvg, yAvg,vprt,tracked); }
//train neural networks with given tracking point images public void initAndTrainANN(int trainingIterationsCount, double trainingRate, int outputVectorSize, int hiddenLayersCount, int hiddenLayersSize, int minimumWeight, int maximumWeight, Bitmap xy1stFrame, Bitmap xz1stFrame, Bitmap yz1stFrame) { //define and initialize activationFunction for Ann's iActivationFunction activationFunction = new LogisticCurve(); //generate ByteVectors for each viewport xyVector=new ByteVector(xyTrackPointImage); xzVector=new ByteVector(xzTrackPointImage); yzVector=new ByteVector(yzTrackPointImage); //train points in each viewport (to be threaded ;)) trainPoint(BaseTypes.viewport.XY,xy1stFrame,ref xyAnn, hiddenLayersSize, outputVectorSize, hiddenLayersCount, activationFunction, trainingRate, trainingIterationsCount, minimumWeight, maximumWeight); trainPoint(BaseTypes.viewport.XZ,xy1stFrame,ref xzAnn, hiddenLayersSize, outputVectorSize, hiddenLayersCount, activationFunction, trainingRate, trainingIterationsCount, minimumWeight, maximumWeight); trainPoint(BaseTypes.viewport.YZ,xy1stFrame,ref yzAnn, hiddenLayersSize, outputVectorSize, hiddenLayersCount, activationFunction, trainingRate, trainingIterationsCount, minimumWeight, maximumWeight); Trained=true; }