예제 #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"/>.
        /// </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);
        }
예제 #2
0
        /// <summary>
        /// Multiplies each pixel's distribution in this image by each pixel's distribution in <paramref name="image"/>.
        /// </summary>
        /// <param name="image">Image to multiply by</param>
        public unsafe void Multiply(DistributionImage image)
        {
            int rows     = Rows;
            int columns  = Columns;
            int channels = Channels;

            if (rows != image.Rows || columns != image.Columns || channels != image.Channels)
                throw new ArgumentException("Argument must be of same dimensions as image");
            fixed(float *dataSrc = RawArray, argSrc = image.RawArray)
            {
                float *dataPtr = dataSrc;
                float *argPtr  = argSrc;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < columns; c++)
                    {
                        for (int i = 0; i < channels; i++, dataPtr++, argPtr++)
                        {
                            *dataPtr = *dataPtr * *argPtr;
                        }
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Subsamples this image.
        /// </summary>
        /// <param name="subsample">Value to subsample by</param>
        /// <returns>The subsampled distribution image</returns>
        public unsafe DistributionImage Subsample(int subsample)
        {
            int rows     = Rows;
            int columns  = Columns;
            int channels = Channels;
            int stride   = columns * channels;
            int nRows    = rows / subsample;
            int nColumns = columns / subsample;

            float[, ,] dst = new float[nRows, nColumns, channels];
            fixed(float *srcBuf = RawArray, dstBuf = dst)
            {
                float *srcPtr = srcBuf;
                float *dstPtr = dstBuf;

                for (int r = 0; r < nRows; r++)
                {
                    float *srcScan = srcPtr;
                    for (int c = 0; c < nColumns; c++)
                    {
                        float *srcScan2 = srcScan;
                        for (int srcR = 0; srcR < subsample; srcR++)
                        {
                            float *srcScan3 = srcScan2;
                            for (int srcC = 0; srcC < subsample; srcC++)
                            {
                                for (int i = 0; i < channels; i++)
                                {
                                    dstPtr[i] += *srcScan3++;
                                }
                            }
                            srcScan2 += stride;
                        }
                        dstPtr  += channels;
                        srcScan += subsample * channels;
                    }
                    srcPtr += subsample * stride;
                }
            }

            DistributionImage dist = new DistributionImage();

            dist.ID = ID;
            dist.SetData(dst);
            dist.Normalize();
            return(dist);
        }
예제 #4
0
        /// <summary>
        /// Creates a new distribution image by appending the distributions at each pixel.
        /// </summary>
        /// <param name="lhs">The first image</param>
        /// <param name="rhs">The second image</param>
        /// <returns>The appended distribution image</returns>
        public static unsafe DistributionImage Append(DistributionImage lhs, DistributionImage rhs)
        {
            int rows      = lhs.Rows;
            int columns   = lhs.Columns;
            int channels0 = lhs.Channels;
            int channels1 = rhs.Channels;

            if (rhs.Rows != rows || rhs.Columns != columns)
            {
                throw new ArgumentException("Arguments must be same dimension");
            }
            DistributionImage combo = new DistributionImage(rows, columns, channels0 + channels1);

            fixed(float *lhsSrc = lhs.RawArray, rhsSrc = rhs.RawArray, comboSrc = combo.RawArray)
            {
                float *lhsPtr   = lhsSrc;
                float *rhsPtr   = rhsSrc;
                float *comboPtr = comboSrc;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < columns; c++)
                    {
                        for (int i = 0; i < channels0; i++)
                        {
                            *comboPtr++ = *lhsPtr++;
                        }
                        for (int i = 0; i < channels1; i++)
                        {
                            *comboPtr++ = *rhsPtr++;
                        }
                    }
                }
            }

            return(combo);
        }
예제 #5
0
        /// <summary>
        /// Adds a distribution image to this image, using <paramref name="label"/> to index that image.
        /// </summary>
        /// <param name="dist">The distribution image to add</param>
        /// <param name="label">The label to extract from the image</param>
        public unsafe void Add(DistributionImage dist, short label)
        {
            int   numLabels = dist.Channels;
            int   rows      = dist.Rows;
            int   columns   = dist.Columns;
            int   nRows     = Rows;
            int   nColumns  = Columns;
            float scaleR    = (float)nRows / rows;
            float scaleC    = (float)nColumns / columns;

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

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < columns; c++)
                    {
                        float val = labelPtr[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 * val;
                        counts[i0, j1] += a * dj * val;
                        counts[i1, j0] += di * b * val;
                        counts[i1, j1] += di * dj * val;

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

                        labelPtr += numLabels;
                    }
                }
            }

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

                while (total-- > 0)
                {
                    *dataPtr = *dataPtr + *countsPtr;
                    dataPtr++;
                    countsPtr++;
                }
            }
        }
예제 #6
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);
                            }
                        }
                    }
                }
            }
        }