private void LoadGroundTrack() { gMapControl1.MapProvider = GMap.NET.MapProviders.GoogleSatelliteMapProvider.Instance; GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerOnly; GMapOverlay markersOverlay = new GMapOverlay("markers"); GMapOverlay linesOverlay = new GMapOverlay("lines"); //GMapOverlay polyOverlay = new GMapOverlay("polygons"); //List<PointLatLng> points = new List<PointLatLng>(); // Test for coordinates TrackMethods _trackMethods = new TrackMethods(); List <PointLatLng> pointList = new List <PointLatLng>(); foreach (TLE_Sat sat in _tle_sat_list) { List <double> longitude = new List <double>(); List <double> latitude = new List <double>(); double sat_period = 86164 / sat.Sat_MeanMotion; _trackMethods.GetTrackCoordinates(sat.Sat_Inclination, sat.Sat_ArgumentPerigee, sat.Sat_SemiAxis, sat.Sat_Eccentricity, sat_period, sat.Sat_RightAscension, sat.Sat_MeanMotion, 1000, out longitude, out latitude); //_trackMethods.GetTrackCoordinates(20, 270, 42164, 0.3, 86160, 60, 0, 360, out longitude, out latitude); for (int i = 1; i < longitude.Count; i++) { //points.Add(new PointLatLng(latitude[i - 1], longitude[i - 1])); //points.Add(new PointLatLng(latitude[i - 1] + 10, longitude[i - 1] + 10)); //points.Add(new PointLatLng(latitude[i] + 10, longitude[i] + 10)); //points.Add(new PointLatLng(latitude[i], longitude[i])); GMarkerCross marker = new GMarkerCross(new PointLatLng(latitude[i], longitude[i])); pointList.Add(new PointLatLng(latitude[i], longitude[i])); marker.Pen = new Pen(Color.Yellow); markersOverlay.Markers.Add(marker); marker.IsVisible = true; //gMapControl1.Update(); } } // TODO: Checkear cuando por el cambio de longitud de >180 a <180 se genera una línea que no debería ser pintada GMapRoute route = new GMapRoute(pointList, "trackLine"); route.Stroke = new Pen(Color.Yellow); route.Stroke.Width = 2; route.Stroke.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; route.Stroke.StartCap = System.Drawing.Drawing2D.LineCap.NoAnchor; route.Stroke.EndCap = System.Drawing.Drawing2D.LineCap.NoAnchor; route.Stroke.LineJoin = System.Drawing.Drawing2D.LineJoin.Round; linesOverlay.Routes.Add(route); gMapControl1.Overlays.Add(linesOverlay); //gMapControl1.Overlays.Add(markersOverlay); //GMapPolygon polygon = new GMapPolygon(points, "mypolygon"); //polygon.Fill = new SolidBrush(Color.FromArgb(50, Color.Red)); //polygon.Stroke = new Pen(Color.Red, 1); //polyOverlay.Polygons.Add(polygon); //gMapControl1.Overlays.Add(polyOverlay); }
/// <summary> /// Constructs a new multi-well tracker /// </summary> /// <param name="imageWidth">The total width of the image we want to track</param> /// <param name="imageHeight">The total height of the image we want to track</param> /// <param name="plate_index">This index is appended to the ROI file name to load file for proper plate</param> /// <param name="parallelChunks">The number of parallel chunks to track</param> public TrackerMultiWell(int imageWidth, int imageHeight, int plate_index, int parallelChunks = 2) : base(imageWidth, imageHeight) { _typicalFishLength = 30; _trackMethod = TrackMethods.PerWell;//default to per-well tracking method //Load ROIs - the following way to assess how many lines we have and hence how many //ROIs we are dealing with is ugly but what the heck its quick to think up _wellnumber = 0; var assembly = Assembly.GetExecutingAssembly(); StreamReader roiStream = null; string fileToOpen = string.Format("SleepTracker.ROI_defs_{0}.txt", plate_index); //open for prescanning var s = assembly.GetManifestResourceStream(fileToOpen); roiStream = new StreamReader(s); while (!roiStream.EndOfStream) { string line = roiStream.ReadLine(); string[] values = line.Split('\t'); if (values.Length == 4) { _wellnumber++; } } roiStream.Dispose(); //reopen to load wells s = assembly.GetManifestResourceStream(fileToOpen); roiStream = new StreamReader(s); _wells = new IppiROI[_wellnumber]; //we use the following hash-table to keep track of wells belonging //to each row. This will give us the number of rows and their boundaries //for later parallel chunk boundary determination as well as which wells //should be tracked in which chunk Dictionary <int, List <IppiROI> > wellsPerRow = new Dictionary <int, List <IppiROI> >(); Dictionary <int, int> columnStarts = new Dictionary <int, int>(); for (int i = 0; i < _wellnumber; i++) { System.Diagnostics.Debug.Assert(!roiStream.EndOfStream, "Unexpectedly reached end of ROI file"); string line = roiStream.ReadLine(); string[] values = line.Split('\t'); System.Diagnostics.Debug.Assert(values.Length == 4, "Found line in ROI file that does not contain 4 tab-separated strings"); int[] numValues = new int[4]; for (int j = 0; j < 4; j++) { numValues[j] = int.Parse(values[j]); } _wells[i] = new IppiROI(numValues[1], numValues[0], numValues[2], numValues[3]); if (wellsPerRow.ContainsKey(_wells[i].Y)) { wellsPerRow[_wells[i].Y].Add(_wells[i]); } else { //create a new list for this row and append our first well wellsPerRow[_wells[i].Y] = new List <IppiROI>(); wellsPerRow[_wells[i].Y].Add(_wells[i]); } if (columnStarts.ContainsKey(_wells[i].X)) { columnStarts[_wells[i].X]++; } else { columnStarts[_wells[i].X] = 1; } } roiStream.Dispose(); //can't have more parallel regions than we have rows of wells if (parallelChunks > wellsPerRow.Count) { parallelChunks = wellsPerRow.Count; } _allFish = new BlobWithMoments[_wellnumber]; //initialize our histogram bin boundaries (=histogram levels) //the following assignment will allow us to study marker values from 0 to 254 //since: h[k] = countof(pLevels[k] <= pixels(x,y) < pLevels[k+1]) _histogramLevels = (int *)Marshal.AllocHGlobal(sizeof(int) * 256); for (int i = 0; i < 256; i++) { _histogramLevels[i] = i; } _hist = (int *)Marshal.AllocHGlobal(sizeof(int) * 255); //assume all wells have the same size _wellCompare = new Image8(_wells[1].Size.width, _wells[1].Size.height); _parallelChunks = parallelChunks; //Initialize result array for parallel tracking _parallelTrackResults = new BlobWithMoments[_wellnumber]; //Set up image regions for parallel tracking _parallelImageRegions = new IppiROI[_parallelChunks]; //populate image regions and parallel buffers if _parallelChunks is larger 1 if (_parallelChunks > 1) { _parallelMarkerBuffers = new byte *[_parallelChunks]; _parallelMomentStates = new IppiMomentState_64s *[_parallelChunks]; //determine the number of rows in each chunk - integer division and last chunk get's the remainder tucked on int nPerChunk = wellsPerRow.Count / _parallelChunks; int nLastChunk = wellsPerRow.Count - (_parallelChunks - 1) * nPerChunk; //obtain all our row-starting coordinates and sort ascending var rowCoordinates = wellsPerRow.Keys.ToArray(); Array.Sort(rowCoordinates); //do the same for column starting coordinates var colCoordinates = columnStarts.Keys.ToArray(); Array.Sort(colCoordinates); //Inititalize our parallel-well list array _parallelChunkWells = new List <IppiROI> [_parallelChunks]; for (int i = 0; i < _parallelChunks; i++) { //for each chunk initialize it's well-list _parallelChunkWells[i] = new List <IppiROI>(); int startRowInChunk = i * nPerChunk; int endRowInChunk; //are we dealing with the last chunk - this one potentially has a different number of rows! if (i == _parallelChunks - 1) { endRowInChunk = startRowInChunk + nLastChunk - 1; } else { endRowInChunk = startRowInChunk + nPerChunk - 1; } //add all wells of this chunk to the list by looping over rows //finding their start coordinate and using that to index into //our dictionary. Then loop over the list in the dictionary for (int j = startRowInChunk; j <= endRowInChunk; j++) { foreach (IppiROI wr in wellsPerRow[rowCoordinates[j]]) { _parallelChunkWells[i].Add(wr); } } //determine top-left corner as well as width and height of this chunk int y_top = wellsPerRow[rowCoordinates[0]][0].Y; int y_bottom = wellsPerRow[rowCoordinates[endRowInChunk]][0].Y + wellsPerRow[rowCoordinates[endRowInChunk]][0].Height - 1; int height = y_bottom - y_top + 1; System.Diagnostics.Debug.Assert(height > 1); int x_left = colCoordinates[0]; int x_right = colCoordinates[colCoordinates.Length - 1] + wellsPerRow[rowCoordinates[0]][0].Width - 1; int width = x_right - x_left + 1; System.Diagnostics.Debug.Assert(width > 1); _parallelImageRegions[i] = new IppiROI(x_left, y_top, width, height); //Initialize marker buffer for this chunk int bufferSize = 0; IppHelper.IppCheckCall(cv.ippiLabelMarkersGetBufferSize_8u_C1R(_parallelImageRegions[i].Size, &bufferSize)); _parallelMarkerBuffers[i] = (byte *)Marshal.AllocHGlobal(bufferSize); //initialize moment state for this chunk fixed(IppiMomentState_64s **ppState = &_parallelMomentStates[i]) { //let ipp decide whether to give accurate or fast results IppHelper.IppCheckCall(ip.ippiMomentInitAlloc_64s(ppState, IppHintAlgorithm.ippAlgHintNone)); } } //determine each chunks start index in the fish output array based on the number of wells //in lower chunks _parallelCumWellCount = new int[_parallelChunks]; for (int i = 1; i < _parallelChunks; i++) { _parallelCumWellCount[i] = _parallelCumWellCount[i - 1] + _parallelChunkWells[i - 1].Count; } } }