/// <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); }