public virtual ImageDescription filter(ImageDescription inputImage) { inputImage.computeGrayscale(); int imageSizeX = inputImage.sizeX; int imageSizeY = inputImage.sizeY; byte[,] inputGray = inputImage.gray; byte[,] outputGray = new byte[imageSizeY, imageSizeX]; // 1. Gauss float[,] gaussConvolutionMatrix = FilterBankUtil.generateNormalizedGaussConvolutionMatrix(sigma, 5); float[,] gaussResult = ImageDescriptionUtil.mirroredMarginConvolution(inputGray, gaussConvolutionMatrix); // 2. Gradient float[,] dx = ImageDescriptionUtil.mirroredMarginConvolution(gaussResult, FilterBankUtil.normalizedSobelX); float[,] dy = ImageDescriptionUtil.mirroredMarginConvolution(gaussResult, FilterBankUtil.normalizedSobelY); // 3. Gradient Amplitude float[,] amplitudeResult = new float[imageSizeY, imageSizeX]; for (int i = 0; i < imageSizeY; i++) { for (int j = 0; j < imageSizeX; j++) { amplitudeResult[i, j] = (float)Math.Sqrt(dx[i, j] * dx[i, j] + dy[i, j] * dy[i, j]); } } for (var i = 0; i < imageSizeY; i++) { for (var j = 0; j < imageSizeX; j++) { if (amplitudeResult[i, j] < 255) { outputGray[i, j] = (byte)(amplitudeResult[i, j] + 0.5f); } else { outputGray[i, j] = 255; } } } ImageDescription outputImage = new ImageDescription(); outputImage.sizeX = imageSizeX; outputImage.sizeY = imageSizeY; foreach (ColorChannelEnum colorChannel in Enum.GetValues(typeof(ColorChannelEnum))) { outputImage.setColorChannel(colorChannel, inputImage.getColorChannel(colorChannel)); } outputImage.setColorChannel(ColorChannelEnum.Sobel, outputGray); return(outputImage); }
public ImageDescription filter(ImageDescription inputImage) { ImageDescription outputImage = new ImageDescription(); outputImage.sizeX = newSizeX; outputImage.sizeY = newSizeY; foreach (ColorChannelEnum colorChannel in colorChannelsToFilter) { byte[,] channel = inputImage.getColorChannel(colorChannel); ImageDescription temp = new ImageDescription(); temp.sizeX = inputImage.sizeX; temp.sizeY = inputImage.sizeY; temp.grayscale = true; temp.setColorChannel(ColorChannelEnum.Gray, channel); Bitmap tempBitmap = ImageDescriptionUtil.convertToBitmap(temp); Bitmap output = ImageDescriptionUtil.resizeImage(tempBitmap, newSizeX, newSizeY); temp = ImageDescriptionUtil.fromBitmap(output); temp.computeGrayscale(); outputImage.setColorChannel(colorChannel, temp.gray); } if (colorChannelsToFilter.Count == 1 && colorChannelsToFilter.Contains(ColorChannelEnum.Gray)) { outputImage.grayscale = true; } return(outputImage); }
public void trainWithBaseAlgorithm(EdgeDetectionAlgorithm algorithm, EdgeDetectionAlgorithm baseAlgorithm, int resizeFactor) { DateTime trainingStart = DateTime.Now; float totalLoss = 0; List <String> fileList = new List <string>(benchmark.getTrainingFilesPathList()); int totalNumberOfFiles = numberOfTrainingSetPasses * fileList.Count; int totalIndex = 0; for (int pass = 0; pass < numberOfTrainingSetPasses; pass++) { ListUtils.Shuffle(fileList); int index = 1; float totalPassLoss = 0; DateTime trainingPassStart = DateTime.Now; foreach (string trainingFileName in fileList) { DateTime start = DateTime.Now; Console.WriteLine("Pass: "******"/" + numberOfTrainingSetPasses + ", " + index + "/" + fileList.Count + " Training file: " + Path.GetFileName(trainingFileName)); ImageDescription inputImage = ImageFileHandler.loadFromPath(trainingFileName); ImageDescription computedImage = baseAlgorithm.test(inputImage); ResizeFilter resizeColor = new ResizeFilter(inputImage.sizeX / resizeFactor, inputImage.sizeY / resizeFactor, ImageDescriptionUtil.colorChannels); ImageDescription newInputImage = resizeColor.filter(inputImage); ImageDescription inputImageGroundTruth = ImageFileHandler.loadFromPath(benchmark.getTrainingFileGroundTruth(trainingFileName)); inputImageGroundTruth.computeGrayscale(); ResizeFilter resizeGrayscale = new ResizeFilter(inputImage.sizeX / resizeFactor, inputImage.sizeY / resizeFactor, ImageDescriptionUtil.grayscaleChannel); ImageDescription newInputImageGroundTruth = resizeGrayscale.filter(inputImageGroundTruth); ImageDescription resizedComputed = resizeGrayscale.filter(computedImage); newInputImage.setColorChannel(ColorChannelEnum.Layer, resizedComputed.gray); float loss = algorithm.train(newInputImage, newInputImageGroundTruth); totalLoss += loss; totalPassLoss += loss; index++; totalIndex++; double timeElapsed = (DateTime.Now - start).TotalSeconds; double timeElapsedSoFar = (DateTime.Now - trainingStart).TotalSeconds; double estimatedTime = (timeElapsedSoFar / totalIndex) * (totalNumberOfFiles - totalIndex); Console.WriteLine("Loss: " + loss.ToString("0.00") + " Time: " + timeElapsed.ToString("0.00") + "s Time elapsed: " + timeElapsedSoFar.ToString("0.00") + "s ETA: " + estimatedTime.ToString("0.00") + "s"); } double tariningPassTimeElapsed = (DateTime.Now - trainingPassStart).TotalSeconds; Console.WriteLine("Pass took " + tariningPassTimeElapsed.ToString("0.00") + " sec. Pass loss: " + totalPassLoss.ToString("0.00") + " Avg loss: " + (totalPassLoss / (fileList.Count)).ToString("0.00")); } double totalTimeElapsed = (DateTime.Now - trainingStart).TotalSeconds; Console.WriteLine("Training took " + totalTimeElapsed.ToString("0.00") + " sec. Total loss: " + totalLoss.ToString("0.00") + " Avg loss: " + (totalLoss / (totalNumberOfFiles)).ToString("0.00")); }
public ImageDescription filter(ImageDescription inputImage) { ImageDescription outputImage = new ImageDescription(); outputImage.sizeX = inputImage.sizeX; outputImage.sizeY = inputImage.sizeY; if (colorChannelsToFilter.Count == 1 && colorChannelsToFilter.Contains(ColorChannelEnum.Gray)) { outputImage.grayscale = true; } foreach (ColorChannelEnum channelEnum in colorChannelsToFilter) { byte[,] inputChannel = inputImage.getColorChannel(channelEnum); byte[,] outputChannel = new byte[outputImage.sizeY, outputImage.sizeX]; outputImage.setColorChannel(channelEnum, outputChannel); for (int y = 0; y < inputImage.sizeY; y++) { for (int x = 0; x < inputImage.sizeX; x++) { int index = 0; for (int i = -halfSize; i <= halfSize; i++) { for (int j = -halfSize; j <= halfSize; j++) { medianValueArray[index++] = inputChannel[ImageDescriptionUtil.outsideMirroredPosition(y + i, inputImage.sizeY), ImageDescriptionUtil.outsideMirroredPosition(x + j, inputImage.sizeX)]; } } Array.Sort(medianValueArray); outputChannel[y, x] = medianValueArray[medianPosition]; } } } return(outputImage); }
public void trainNestedAlgorithm(ContextualMemoryNestedAlgorithm nestedAlgorithm) { BlackAndWhiteConverter blackAndWhiteConverter = new BlackAndWhiteConverter(1); //BlackAndWhiteConverter blackAndWhiteConverter = new BlackAndWhiteConverter(63); List <String> fileList = new List <string>(benchmark.getTrainingFilesPathList()); List <ContextualMemoryNestedAlgorithmLayer> layers = nestedAlgorithm.getLayers(); for (int layerIndex = 0; layerIndex < layers.Count; layerIndex++) { ContextualMemoryNestedAlgorithmLayer layer = layers[layerIndex]; layer.initialize(); Console.WriteLine("Layer: " + (layerIndex + 1) + "/" + layers.Count); EdgeDetectionAlgorithm algorithm = layer.algorithm; DateTime trainingStart = DateTime.Now; float totalLoss = 0; int totalNumberOfFiles = numberOfTrainingSetPasses * fileList.Count; int totalIndex = 0; for (int pass = 0; pass < numberOfTrainingSetPasses; pass++) { ListUtils.Shuffle(fileList); int index = 1; float totalPassLoss = 0; DateTime trainingPassStart = DateTime.Now; foreach (string trainingFileName in fileList) { DateTime start = DateTime.Now; Console.WriteLine("Pass: "******"/" + numberOfTrainingSetPasses + ", " + index + "/" + fileList.Count + " Training file: " + Path.GetFileName(trainingFileName)); ImageDescription inputImage = ImageFileHandler.loadFromPath(trainingFileName); int layerResizeFactor = layer.resizeFactor; ImageDescription computedImage = null; if (layerIndex > 0) { List <ImageDescription> computedImages = nestedAlgorithm.computeImageForLayers(inputImage, layerIndex); computedImage = computedImages[layerIndex - 1]; } ImageDescription inputImageGroundTruth = ImageFileHandler.loadFromPath(benchmark.getTrainingFileGroundTruth(trainingFileName)); inputImageGroundTruth = blackAndWhiteConverter.filter(inputImageGroundTruth); ImageDescription newInputImage = null; ImageDescription newInputImageGroundTruth = null; ResizeFilter resizeGrayscale = new ResizeFilter(inputImage.sizeX / layerResizeFactor, inputImage.sizeY / layerResizeFactor, ImageDescriptionUtil.grayscaleChannel); ResizeFilter resizeColor = new ResizeFilter(inputImage.sizeX / layerResizeFactor, inputImage.sizeY / layerResizeFactor, ImageDescriptionUtil.colorChannels); if (layerResizeFactor == 1) { newInputImage = inputImage; newInputImageGroundTruth = inputImageGroundTruth; } else { newInputImage = resizeColor.filter(inputImage); newInputImageGroundTruth = resizeGrayscale.filter(inputImageGroundTruth); } if (layerIndex > 0) { ImageDescription resizedComputed = resizeGrayscale.filter(computedImage); newInputImage.setColorChannel(ColorChannelEnum.Layer, resizedComputed.gray); } float loss = algorithm.train(newInputImage, newInputImageGroundTruth); totalLoss += loss; totalPassLoss += loss; index++; totalIndex++; double timeElapsed = (DateTime.Now - start).TotalSeconds; double timeElapsedSoFar = (DateTime.Now - trainingStart).TotalSeconds; double estimatedTime = (timeElapsedSoFar / totalIndex) * (totalNumberOfFiles - totalIndex); Console.WriteLine("Loss: " + loss.ToString("0.00") + " Time: " + timeElapsed.ToString("0.00") + "s Time elapsed: " + timeElapsedSoFar.ToString("0.00") + "s ETA: " + estimatedTime.ToString("0.00") + "s"); } double tariningPassTimeElapsed = (DateTime.Now - trainingPassStart).TotalSeconds; Console.WriteLine("Pass took " + tariningPassTimeElapsed.ToString("0.00") + " sec. Pass loss: " + totalPassLoss.ToString("0.00") + " Avg loss: " + (totalPassLoss / (fileList.Count)).ToString("0.00")); } double totalTimeElapsed = (DateTime.Now - trainingStart).TotalSeconds; Console.WriteLine("Training took " + totalTimeElapsed.ToString("0.00") + " sec. Total loss: " + totalLoss.ToString("0.00") + " Avg loss: " + (totalLoss / (totalNumberOfFiles)).ToString("0.00")); } Console.WriteLine("Training blender"); DateTime blenderTrainingStart = DateTime.Now; float blenderTotalLoss = 0; int blenderTotalNumberOfFiles = /* numberOfTrainingSetPasses * */ fileList.Count; int blenderTotalIndex = 0; ImageBlender blender = nestedAlgorithm.getImageBlender(); //for (int pass = 0; pass < numberOfTrainingSetPasses; pass++) { ListUtils.Shuffle(fileList); int index = 1; float totalPassLoss = 0; DateTime trainingPassStart = DateTime.Now; foreach (string trainingFileName in fileList) { DateTime start = DateTime.Now; //Console.Write("Pass: "******"/" + numberOfTrainingSetPasses + ", "); Console.WriteLine(index + "/" + fileList.Count + " Training file: " + Path.GetFileName(trainingFileName)); ImageDescription inputImage = ImageFileHandler.loadFromPath(trainingFileName); List <ImageDescription> computedImages = nestedAlgorithm.computeImageForLayers(inputImage, layers.Count); ImageDescription inputImageGroundTruth = ImageFileHandler.loadFromPath(benchmark.getTrainingFileGroundTruth(trainingFileName)); inputImageGroundTruth = blackAndWhiteConverter.filter(inputImageGroundTruth); float blenderLoss = blender.train(computedImages, inputImageGroundTruth); blenderTotalLoss += blenderLoss; totalPassLoss += blenderLoss; index++; blenderTotalIndex++; double timeElapsed = (DateTime.Now - start).TotalSeconds; double timeElapsedSoFar = (DateTime.Now - blenderTrainingStart).TotalSeconds; double estimatedTime = (timeElapsedSoFar / blenderTotalIndex) * (blenderTotalNumberOfFiles - blenderTotalIndex); Console.WriteLine("Loss: " + blenderLoss.ToString("0.00") + " Time: " + timeElapsed.ToString("0.00") + "s Time elapsed: " + timeElapsedSoFar.ToString("0.00") + "s ETA: " + estimatedTime.ToString("0.00") + "s"); } //double tariningPassTimeElapsed = (DateTime.Now - trainingPassStart).TotalSeconds; //Console.WriteLine("Pass took " + tariningPassTimeElapsed.ToString("0.00") + " sec. Pass loss: " + totalPassLoss.ToString("0.00") //+ " Avg loss: " + (totalPassLoss / (fileList.Count)).ToString("0.00")); } double blenderTotalTimeElapsed = (DateTime.Now - blenderTrainingStart).TotalSeconds; Console.WriteLine("Training took " + blenderTotalTimeElapsed.ToString("0.00") + " sec. Total loss: " + blenderTotalLoss.ToString("0.00") + " Avg loss: " + (blenderTotalLoss / (blenderTotalNumberOfFiles)).ToString("0.00")); }
public virtual ImageDescription filter(ImageDescription inputImage) { inputImage.computeGrayscale(); int imageSizeX = inputImage.sizeX; int imageSizeY = inputImage.sizeY; byte[,] inputGray = inputImage.gray; byte[,] outputGray = new byte[imageSizeY, imageSizeX]; float[,] gaussConvolutionMatrix = FilterBankUtil.generateNormalizedGaussConvolutionMatrix(sigma, 7); float[,] gaussResult = ImageDescriptionUtil.mirroredMarginConvolution(inputGray, gaussConvolutionMatrix); List <float[, ]> templates = FilterBankUtil.normalizedKirschTemplates; List <float[, ]> results = new List <float[, ]>(templates.Count); foreach (float[,] template in templates) { results.Add(ImageDescriptionUtil.mirroredMarginConvolution(gaussResult, template)); } float[,] amplitudeResult = new float[imageSizeY, imageSizeX]; int[,] anglesResult = new int[imageSizeY, imageSizeX]; for (int i = 0; i < imageSizeY; i++) { for (int j = 0; j < imageSizeX; j++) { int direction = 0; float maxValue = 0; for (int templateIndex = 0; templateIndex < templates.Count; templateIndex++) { float value = results[templateIndex][i, j]; if (value > maxValue) { maxValue = value; direction = templateIndex; } } amplitudeResult[i, j] = maxValue; anglesResult[i, j] = direction; } } if (!applyNms) { for (var i = 0; i < imageSizeY; i++) { for (var j = 0; j < imageSizeX; j++) { if (amplitudeResult[i, j] < 255) { outputGray[i, j] = (byte)(amplitudeResult[i, j] + 0.5f); } else { outputGray[i, j] = 255; } } } } else { float[,] nmsResult = new float[imageSizeY, imageSizeX]; for (int i = 0; i < imageSizeY; i++) { for (int j = 0; j < imageSizeX; j++) { int angle = anglesResult[i, j]; if (angle == 2 || angle == 6) { if ((i == 0 || amplitudeResult[i, j] >= amplitudeResult[i - 1, j]) && (i == imageSizeY - 1 || amplitudeResult[i, j] > amplitudeResult[i + 1, j])) { nmsResult[i, j] = amplitudeResult[i, j]; } } else { if (angle == 1 || angle == 5) { if ((i == 0 || j == imageSizeX - 1 || amplitudeResult[i, j] >= amplitudeResult[i - 1, j + 1]) && (i == imageSizeY - 1 || j == 0 || amplitudeResult[i, j] > amplitudeResult[i + 1, j - 1])) { nmsResult[i, j] = amplitudeResult[i, j]; } } else { if (angle == 3 || angle == 7) { if ((i == 0 || j == 0 || amplitudeResult[i, j] >= amplitudeResult[i - 1, j - 1]) && (i == imageSizeY - 1 || j == imageSizeX - 1 || amplitudeResult[i, j] > amplitudeResult[i + 1, j + 1])) { nmsResult[i, j] = amplitudeResult[i, j]; } } else { if ((j == 0 || amplitudeResult[i, j] >= amplitudeResult[i, j - 1]) && (j == imageSizeX - 1 || amplitudeResult[i, j] > amplitudeResult[i, j + 1])) { nmsResult[i, j] = amplitudeResult[i, j]; } } } } } } float[,] hysteresisResult = new float[imageSizeY, imageSizeX]; bool[,] retainedPositions = applyHysteresisThreshold(nmsResult, imageSizeX, imageSizeY); for (var i = 0; i < imageSizeY; i++) { for (var j = 0; j < imageSizeX; j++) { if (retainedPositions[i, j]) { hysteresisResult[i, j] = nmsResult[i, j]; } } } for (var i = 0; i < imageSizeY; i++) { for (var j = 0; j < imageSizeX; j++) { if (hysteresisResult[i, j] < 255) { outputGray[i, j] = (byte)(hysteresisResult[i, j] + 0.5f); } else { outputGray[i, j] = 255; } } } } ImageDescription outputImage = new ImageDescription(); outputImage.sizeX = imageSizeX; outputImage.sizeY = imageSizeY; foreach (ColorChannelEnum colorChannel in Enum.GetValues(typeof(ColorChannelEnum))) { outputImage.setColorChannel(colorChannel, inputImage.getColorChannel(colorChannel)); } outputImage.setColorChannel(ColorChannelEnum.Kirsch, outputGray); return(outputImage); }
public virtual ImageDescription filter(ImageDescription inputImage) { inputImage.computeGrayscale(); int imageSizeX = inputImage.sizeX; int imageSizeY = inputImage.sizeY; byte[,] inputGray = inputImage.gray; byte[,] outputGray = new byte[imageSizeY, imageSizeX]; // 1. Gauss float[,] gaussConvolutionMatrix = FilterBankUtil.generateNormalizedGaussConvolutionMatrix(sigma, 5); float[,] gaussResult = ImageDescriptionUtil.mirroredMarginConvolution(inputGray, gaussConvolutionMatrix); // 2. Gradient float[,] dx = ImageDescriptionUtil.mirroredMarginConvolution(gaussResult, FilterBankUtil.normalizedSobelX); float[,] dy = ImageDescriptionUtil.mirroredMarginConvolution(gaussResult, FilterBankUtil.normalizedSobelY); // 3. Gradient Amplitude float[,] amplitudeResult = new float[imageSizeY, imageSizeX]; for (int i = 0; i < imageSizeY; i++) { for (int j = 0; j < imageSizeX; j++) { amplitudeResult[i, j] = (float)Math.Sqrt(dx[i, j] * dx[i, j] + dy[i, j] * dy[i, j]); } } // 4. Angle of gradient float[,] anglesResult = new float[imageSizeY, imageSizeX]; for (int i = 0; i < imageSizeY; i++) { for (int j = 0; j < imageSizeX; j++) { anglesResult[i, j] = (float)Math.Atan2(dx[i, j], dy[i, j]); } } // 5. Non maximal suppresion float[,] nmsResult = new float[imageSizeY, imageSizeX]; for (int i = 1; i < imageSizeY - 1; i++) { for (int j = 1; j < imageSizeX - 1; j++) { float angle = anglesResult[i, j]; if ((angle <= (5 * Math.PI) / 8 && angle > (3 * Math.PI) / 8) || (angle > -(5 * Math.PI) / 8 && angle <= -(3 * Math.PI) / 8)) { if (amplitudeResult[i, j] > amplitudeResult[i - 1, j] && amplitudeResult[i, j] > amplitudeResult[i + 1, j]) { nmsResult[i, j] = amplitudeResult[i, j]; } } else { if (angle <= (3 * Math.PI) / 8 && angle > Math.PI / 8 || angle > -(7 * Math.PI) / 8 && angle <= -(5 * Math.PI) / 8) { if (amplitudeResult[i, j] > amplitudeResult[i - 1, j + 1] && amplitudeResult[i, j] > amplitudeResult[i + 1, j - 1]) { nmsResult[i, j] = amplitudeResult[i, j]; } } else { if (angle <= (7 * Math.PI / 8) && angle > (5 * Math.PI / 8) || angle > -(3 * Math.PI) / 8 && angle < -(Math.PI / 8)) { if (amplitudeResult[i, j] > amplitudeResult[i - 1, j - 1] && amplitudeResult[i, j] > amplitudeResult[i + 1, j + 1]) { nmsResult[i, j] = amplitudeResult[i, j]; } } else { if (amplitudeResult[i, j] > amplitudeResult[i, j - 1] && amplitudeResult[i, j] > amplitudeResult[i, j + 1]) { nmsResult[i, j] = amplitudeResult[i, j]; } } } } } } // 6. Hysteresis thresolding float[,] hysteresisResult = new float[imageSizeY, imageSizeX]; bool[,] retainedPositions = applyHysteresisThreshold(nmsResult, imageSizeX, imageSizeY); for (var i = 0; i < imageSizeY; i++) { for (var j = 0; j < imageSizeX; j++) { if (retainedPositions[i, j]) { hysteresisResult[i, j] = nmsResult[i, j]; } } } for (var i = 0; i < imageSizeY; i++) { for (var j = 0; j < imageSizeX; j++) { if (hysteresisResult[i, j] < 255) { outputGray[i, j] = (byte)(hysteresisResult[i, j] + 0.5f); } else { outputGray[i, j] = 255; } } } ImageDescription outputImage = new ImageDescription(); outputImage.sizeX = imageSizeX; outputImage.sizeY = imageSizeY; foreach (ColorChannelEnum colorChannel in Enum.GetValues(typeof(ColorChannelEnum))) { outputImage.setColorChannel(colorChannel, inputImage.getColorChannel(colorChannel)); } outputImage.setColorChannel(ColorChannelEnum.Canny, outputGray); return(outputImage); }