예제 #1
0
        /// <summary>
        /// Computes a confusion matrix using the soft values from the distributions in <paramref name="inferredLabels"/> based upon the ground truth
        /// pixel labels in <paramref name="groundTruth"/>, and adds them to <paramref name="matrix"/>.
        /// </summary>
        /// <param name="matrix">Matrix to add the confusion values of this image to</param>
        /// <param name="groundTruth">The ground truth labels of the image</param>
        /// <param name="inferredLabels">The inferred labels of the image</param>
        public static unsafe void ComputeConfusionMatrix(ConfusionMatrix matrix, LabelImage groundTruth, DistributionImage inferredLabels)
        {
            int rows     = groundTruth.Rows;
            int columns  = groundTruth.Columns;
            int channels = inferredLabels.Channels;

            fixed(short *labelsSrc = groundTruth.RawArray)
            {
                fixed(float *distSrc = inferredLabels.RawArray)
                {
                    short *labelsPtr = labelsSrc;
                    float *distPtr   = distSrc;

                    for (int r = 0; r < rows; r++)
                    {
                        for (int c = 0; c < columns; c++, labelsPtr++)
                        {
                            short trueLabel = *labelsPtr;
                            for (short i = 0; i < channels; i++, distPtr++)
                            {
                                matrix.Add(trueLabel, i, *distPtr);
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <summary>
        /// Computes a confusion matrix using the soft values from the distributions in <paramref name="inferredLabels"/> based upon the ground truth
        /// pixel labels in <paramref name="groundTruth"/>.
        /// </summary>
        /// <param name="groundTruth">The ground truth labels of the image</param>
        /// <param name="inferredLabels">The inferred labels of the image</param>
        /// <returns>A confusion matrix</returns>
        public static ConfusionMatrix ComputeConfusionMatrix(LabelImage groundTruth, DistributionImage inferredLabels)
        {
            ConfusionMatrix matrix = new ConfusionMatrix(inferredLabels.Channels);

            ComputeConfusionMatrix(matrix, groundTruth, inferredLabels);
            return(matrix);
        }
예제 #4
0
        /// <summary>
        /// Computes a confusion matrix from <paramref name="inferredLabels"/> using <paramref name="trueLabels"/> as a reference.
        /// </summary>
        /// <param name="numLabels">The number of possible labels</param>
        /// <param name="trueLabels">The true labels of an image</param>
        /// <param name="inferredLabels">The inferred labels of an image</param>
        /// <returns>A confusion matrix</returns>
        public static unsafe ConfusionMatrix ComputeConfusionMatrix(int numLabels, LabelImage trueLabels, LabelImage inferredLabels)
        {
            ConfusionMatrix matrix = new ConfusionMatrix(numLabels);

            ComputeConfusionMatrix(matrix, trueLabels, inferredLabels);
            return(matrix);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <summary>
        /// Computes a confusion matrix from <paramref name="inferredLabels"/> using <paramref name="trueLabels"/> as a reference, and adds
        /// the information into <paramref name="matrix"/>.
        /// </summary>
        /// <param name="matrix">The matrix that will hold the results</param>
        /// <param name="trueLabels">The true labels of an image</param>
        /// <param name="inferredLabels">The inferred labels of an image</param>
        public static unsafe void ComputeConfusionMatrix(ConfusionMatrix matrix, LabelImage trueLabels, LabelImage inferredLabels)
        {
            fixed(short *trueLabelsSrc = trueLabels.RawArray, inferredLabelsSrc = inferredLabels.RawArray)
            {
                short *trueLabelsPtr     = trueLabelsSrc;
                short *inferredLabelsPtr = inferredLabelsSrc;

                int count = trueLabels.Rows * trueLabels.Columns;

                while (count-- > 0)
                {
                    short row    = *trueLabelsPtr++;
                    short column = *inferredLabelsPtr++;
                    if (row == BackgroundLabel)
                    {
                        continue;
                    }
                    matrix.Add(row, column);
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Converts to a label image using the maximum likelihood labels of this image's pixels.
        /// </summary>
        /// <returns>A label image</returns>
        public unsafe LabelImage ToLabelImage()
        {
            LabelImage labels = new LabelImage(Rows, Columns);

            fixed(short *labelsSrc = labels.RawArray)
            {
                fixed(float *dataSrc = RawArray)
                {
                    float *dataPtr   = dataSrc;
                    short *labelsPtr = labelsSrc;
                    int    rows      = Rows;
                    int    columns   = Columns;
                    int    channels  = Channels;

                    for (int r = 0; r < rows; r++)
                    {
                        for (int c = 0; c < columns; c++)
                        {
                            short max      = -1;
                            float maxValue = float.MinValue;
                            for (short i = 0; i < channels; i++)
                            {
                                float test = *dataPtr++;
                                if (test > maxValue)
                                {
                                    maxValue = test;
                                    max      = i;
                                }
                            }
                            *labelsPtr++ = max;
                        }
                    }
                }
            }

            return(labels);
        }
예제 #9
0
        /// <summary>
        /// Adds a label image to the distribution.  Each time the label in <paramref name="labels"/> matches <paramref name="label"/>, the value at that pixel
        /// is incremented by 1.
        /// </summary>
        /// <param name="labels">Label image to add</param>
        /// <param name="label">The label to extract</param>
        public unsafe void Add(LabelImage labels, short label)
        {
            int   rows     = labels.Rows;
            int   columns  = labels.Columns;
            int   nRows    = Rows;
            int   nColumns = Columns;
            float scaleR   = (float)nRows / rows;
            float scaleC   = (float)nColumns / columns;

            float[,] counts = new float[nRows, nColumns];
            fixed(short *labelSrc = labels.RawArray)
            {
                short *labelPtr = labelSrc;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < columns; c++)
                    {
                        short test = *labelPtr++;
                        if (test == label)
                        {
                            float rr = r * scaleR;
                            float cc = c * scaleC;
                            int   i0 = (int)rr;
                            int   j0 = (int)cc;
                            float di = rr - i0 - .5f;
                            float dj = cc - j0 - .5f;
                            if (di < 0)
                            {
                                i0--;
                                di += 1;
                            }
                            if (dj < 0)
                            {
                                j0--;
                                dj += 1;
                            }
                            int i1 = i0 + 1;
                            int j1 = j0 + 1;
                            if (i0 < 0)
                            {
                                i0++;
                            }
                            if (i1 == nRows)
                            {
                                i1--;
                            }
                            if (j0 < 0)
                            {
                                j0++;
                            }
                            if (j1 == nColumns)
                            {
                                j1--;
                            }
                            float a = 1 - di;
                            float b = 1 - dj;
                            counts[i0, j0] += a * b;
                            counts[i0, j1] += a * dj;
                            counts[i1, j0] += di * b;
                            counts[i1, j1] += di * dj;

                            _sum            += 1;
                            _rowSums[i0]    += a;
                            _rowSums[i1]    += di;
                            _columnSums[j0] += b;
                            _columnSums[j1] += dj;
                        }
                    }
                }
            }

            fixed(float *dataSrc = RawArray, countsSrc = counts)
            {
                float *dataPtr   = dataSrc;
                float *countsPtr = countsSrc;
                int    total     = Rows * Columns;

                while (total-- > 0)
                {
                    *dataPtr = *dataPtr + *countsPtr;
                    dataPtr++;
                    countsPtr++;
                }
            }
        }
예제 #10
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="image">The source image</param>
 /// <param name="labels">The ground truth labels</param>
 public LabeledImage(IMultichannelImage <T> image, LabelImage labels)
 {
     Image  = image;
     Labels = labels;
     initValid();
 }
예제 #11
0
        /// <summary>
        /// Scales this image to another size using exact scaling (no interpolation).
        /// </summary>
        /// <param name="subsample">The sampling rate</param>
        /// <returns>The scaled image</returns>
        public unsafe LabelImage Subsample(int subsample)
        {
            if (_labelCounts == null)
            {
                updateLabelCounts();
            }
            int rows      = Rows;
            int columns   = Columns;
            int stride    = columns;
            int nRows     = rows / subsample;
            int nColumns  = columns / subsample;
            int numLabels = -1;

            foreach (short key in _labelCounts.Keys)
            {
                numLabels = Math.Max(numLabels, key);
            }
            numLabels++;
            short[, ,] dst = new short[nRows, nColumns, 1];
            fixed(short *srcBuf = RawArray, dstBuf = dst)
            {
                short *srcPtr = srcBuf;
                short *dstPtr = dstBuf;

                for (int r = 0; r < nRows; r++)
                {
                    short *srcScan = srcPtr;
                    for (int c = 0; c < nColumns; c++)
                    {
                        int[]  counts   = new int[numLabels];
                        short *srcScan2 = srcScan;
                        for (int srcR = 0; srcR < subsample; srcR++)
                        {
                            short *srcScan3 = srcScan2;
                            for (int srcC = 0; srcC < subsample; srcC++)
                            {
                                counts[*srcScan3++]++;
                            }
                            srcScan2 += stride;
                        }
                        int   maxValue = -1;
                        short max      = -1;
                        for (short i = 0; i < numLabels; i++)
                        {
                            if (counts[i] > maxValue)
                            {
                                maxValue = counts[i];
                                max      = i;
                            }
                        }
                        *dstPtr++ = max;
                        srcScan  += subsample;
                    }
                    srcPtr += stride * subsample;
                }
            }

            LabelImage labels = new LabelImage();

            labels.SetData(dst);
            return(labels);
        }