Exemplo n.º 1
0
        /// <summary>
        /// Calculate value for position in result matrix (made from multiplication of image and kernel)
        /// </summary>
        /// <param name="image">image</param>
        /// <param name="row">current result matrix row</param>
        /// <param name="column">current result matrix column</param>
        /// <param name="kernel">kernel</param>
        /// <param name="kernelSum">Optional. Sum of kernel matrix. If not specified every time it will calculate (bad for performance i guess)</param>
        /// <returns>calculated value for specified position</returns>
        private IMatrixData CalculateValueForPosition(int row, int column, IMatrix image, IMatrix kernel,
                                                      float kernelSum = -1)
        {
            IMatrixData endValue = ZeroRepresentationOfMatrixData;

            for (var i = 0; i < kernel.Height; i++)
            {
                IMatrixData innerCycleCalculationResult = ZeroRepresentationOfMatrixData;

                for (var j = 0; j < kernel.Width; j++)
                {
                    var imageColumn = column + j - 1;
                    var imageRow    = row + i - 1;

                    //allows bluring edges of the picture (a.k.a prevents from throwing exceptions when kernel is on the edge of the picture)
                    if (imageColumn < 0 || imageRow < 0 || imageColumn >= image.Width || imageRow >= image.Height)
                    {
                        continue;
                    }

                    var imageValue  = image.GetValue(imageColumn, imageRow);
                    var kernelValue = kernel.GetValue(j, i);
                    var imageValueMultipliedByKernelValue = this.arithmeticsController.Multiply(imageValue, kernelValue);
                    innerCycleCalculationResult = this.arithmeticsController.Add(innerCycleCalculationResult, imageValueMultipliedByKernelValue);
                }

                endValue = this.arithmeticsController.Add(endValue, innerCycleCalculationResult);
            }

            if (Math.Abs(kernelSum - (-1)) > 0.001f)
            {
                if (Math.Abs(kernelSum) < 0.001f)
                {
                    return(endValue.CompareTo(endValue.ZeroRepresentation) < 0 ? endValue.ZeroRepresentation : endValue);
                }

                return(this.arithmeticsController.Divide(endValue, new FloatNumberMatrixData(kernelSum)));
            }

            var sum      = kernel.Sum;
            var sumValue = Convert.ToDouble(sum.RawValue);

            if (Math.Abs(sumValue) > 0.001f)
            {
                return(this.arithmeticsController.Divide(endValue, new FloatNumberMatrixData((float)sumValue)));
            }

            return(endValue.CompareTo(endValue.ZeroRepresentation) < 0 ? endValue.ZeroRepresentation : endValue);
        }