/// <summary> /// Creates a label image by sampling from the distribution. Labels chosen are constricted to belong to <paramref name="set"/>, thus using it /// as a hard prior over labels. /// </summary> /// <param name="set">Set used to constrict the sampling</param> /// <returns>A label image</returns> public unsafe LabelImage GenerateLabels(LabelSet set) { int rows = Rows; int columns = Columns; int numLabels = Channels; int setSize = set.Count; LabelImage result = new LabelImage(Rows, Columns); int count = rows * columns; GibbsImage[] gibbs = new GibbsImage[set.Count]; short[] labels = set.OrderBy(o => o).ToArray(); float[] prior = new float[set.Count]; for (int i = 0; i < labels.Length; i++) { gibbs[i] = new GibbsImage(rows, columns); gibbs[i].Add(this, labels[i]); prior[i] = 1f / set.Count; } int samples = rows * columns; int row, column; row = column = 0; for (int i = 0; i < samples; i++) { int index = (short)prior.Sample(); gibbs[index].Sample(ref row, ref column); result[row, column] = labels[index]; } return(result); }
/// <summary> /// Extracts all segments within the image. Each "segment" is a list of all points with a common label. /// </summary> /// <returns>The segments of the image, indexed by segment label</returns> public unsafe Dictionary <short, List <ImageDataPoint <short> > > ExtractSegments() { LabelSet labels = Labels; List <ImageDataPoint <short> >[] segments = new List <ImageDataPoint <short> > [labels.Max() + 1]; foreach (short label in labels) { segments[label] = new List <ImageDataPoint <short> >(); } int rows = Rows; int columns = Columns; fixed(short *src = RawArray) { short *ptr = src; for (short r = 0; r < rows; r++) { for (short c = 0; c < columns; c++) { short label = *ptr++; segments[label].Add(new ImageDataPoint <short>(this, r, c, label)); } } } return((from label in labels select new { Label = label, Points = segments[label] }).ToDictionary(o => o.Label, o => o.Points)); }
/// <summary> /// Creates several splits of the dataset. /// </summary> /// <param name="sampleFrequency">How often to sample pixels within the training images.</param> /// <param name="boxRows">Vertical trim around the edges of images to avoid feature tests beyond the boundary of the image</param> /// <param name="boxColumns">Vertical trim around the edges of images to avoid feature tests beyond the boundary of the image</param> /// <param name="numSplits">Number of splits to create</param> /// <returns>Splits of the data</returns> public List <ImageDataPoint <T> >[] CreateDataPoints(int sampleFrequency, int boxRows, int boxColumns, int numSplits) { List <ImageDataPoint <T> > points = new List <ImageDataPoint <T> >(); foreach (LabeledImage <T> labelledImage in _images) { IMultichannelImage <T> image = labelledImage.Image; LabelImage labels = labelledImage.Labels; LabelSet set = labels.Labels; string id = labelledImage.ID; bool[,] valid = labelledImage.Valid; int maxRows = image.Rows - boxRows; int maxColumns = image.Columns - boxColumns; for (int r = boxRows; r < maxRows; r += sampleFrequency) { for (int c = boxColumns; c < maxColumns; c += sampleFrequency) { short label = getLabel(labels[r, c], set); bool sample = valid[r, c]; if (sample && label == LabelImage.BackgroundLabel) { switch (_backgroundSampleMode) { case BackgroundSampleMode.Ignore: sample = false; break; case BackgroundSampleMode.Half: sample = ThreadsafeRandom.Test(.5); break; } } if (sample) { points.Add(new ImageDataPoint <T>(image, (short)r, (short)c, label)); } } } } List <ImageDataPoint <T> >[] splits = new List <ImageDataPoint <T> > [numSplits]; for (int i = 0; i < numSplits; i++) { if (_byImage) { splits[i] = sampleByImage(points); } else { splits[i] = sample(points); } } return(splits); }
/// <summary> /// Computes the inverse label frequency array for the image. This is an array in which each index holds a value equal /// to the total number of image labels divided by the total number of that particular label. /// </summary> /// <param name="numLabels">Total number of labels</param> /// <returns>Inverse label frequency</returns> public unsafe float[] ComputeInverseLabelFrequency(int numLabels) { int[] counts = new int[numLabels]; foreach (LabeledImage <T> image in _images) { LabelImage labels = image.Labels; LabelSet set = labels.Labels; fixed(short *labelsSrc = labels.RawArray) { int count = labels.Rows * labels.Columns; short *labelsPtr = labelsSrc; while (count-- > 0) { short index = getLabel(*labelsPtr++, set); bool sample = true; if (index == LabelImage.BackgroundLabel) { switch (_backgroundSampleMode) { case BackgroundSampleMode.Ignore: sample = false; break; case BackgroundSampleMode.Half: sample = ThreadsafeRandom.Test(.5); break; } } if (!sample) { continue; } counts[index]++; } } } float[] frequency = new float[numLabels]; float sum = 0; for (short i = 0; i < frequency.Length; i++) { frequency[i] = 1 + counts[i]; sum += frequency[i]; } for (int i = 0; i < frequency.Length; i++) { frequency[i] = sum / frequency[i]; } return(frequency); }
private short getLabel(short label, LabelSet labels) { switch (_supervisionMode) { case SupervisionMode.Full: return(label); case SupervisionMode.Part: return(labels.SelectRandom()); case SupervisionMode.None: return((short)ThreadsafeRandom.Next(20)); } return(0); }
private unsafe List <ImageDataPoint <T> > createAllDataPointsLabels(BackgroundSampleMode mode) { List <ImageDataPoint <T> > points = new List <ImageDataPoint <T> >(); int rows = _image.Rows; int columns = _image.Columns; LabelSet set = _labels.Labels; fixed(short *labelsSrc = _labels.RawArray) { fixed(bool *validSrc = _valid) { short *labelsPtr = labelsSrc; bool * validPtr = validSrc; for (short r = 0; r < rows; r++) { for (short c = 0; c < columns; c++) { short label = getLabel(*labelsPtr++, set); bool sample = *validPtr++; if (sample && label == LabelImage.BackgroundLabel) { switch (mode) { case BackgroundSampleMode.Ignore: sample = false; break; case BackgroundSampleMode.Half: sample = ThreadsafeRandom.Test(.5); break; } } if (sample) { points.Add(new ImageDataPoint <T>(_image, r, c, label)); } } } } } return(points); }
/// <summary> /// Compares this set to <paramref name="other"/>. /// </summary> /// <param name="other">Set to compare to.</param> /// <returns>Whether this set is "less" or "more" than <paramref name="other"/></returns> public int CompareTo(LabelSet other) { if (other.Count == Count) { List <short> otherLabels = other._labels; for (int i = 0; i < _labels.Count; i++) { if (_labels[i] != otherLabels[i]) { return(_labels[i].CompareTo(otherLabels[i])); } } return(0); } else { return(Count.CompareTo(other.Count)); } }