public ProcessingImage filter(ProcessingImage inputImage) { ProcessingImage outputImage = new ProcessingImage(); outputImage.copyAttributesAndAlpha(inputImage); outputImage.addWatermark(String.Format("sobel watermark")); const int dim = 3; float[,] convMatrixGx = new float[dim, dim] { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, -1 } }; float[,] convMatrixGy = new float[dim, dim] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } }; byte[,] inputLuminance = inputImage.getLuminance(); byte[,] outputGray = new byte[inputImage.getSizeY() - (dim - 1), inputImage.getSizeX() - (dim - 1)]; for (int y = dim / 2; y < inputImage.getSizeY() - dim / 2; y++) { for (int x = dim / 2; x < inputImage.getSizeX() - dim / 2; x++) { float resx = applyConv(x, y, inputLuminance, convMatrixGx); float resy = applyConv(x, y, inputLuminance, convMatrixGy); double r = Math.Sqrt((resx * resx) + (resy * resy)); if (r < 0) { r = 0; } if (r > 255) { r = 255; } outputGray[y - dim / 2, x - dim / 2] = (byte)r; } } outputImage.setSizeX(inputImage.getSizeX() - (dim - 1)); outputImage.setSizeY(inputImage.getSizeY() - (dim - 1)); outputImage.setGray(outputGray); return(outputImage); }
public ProcessingImage filter(ProcessingImage inputImage) { ProcessingImage outputImage = new ProcessingImage(); outputImage.copyAttributesAndAlpha(inputImage); outputImage.addWatermark(String.Format("canny watermark")); float[,] gaussianMatrix = generateGaussianMatrix(); byte[,] inputLuminance = inputImage.getLuminance(); float[,] outputImageGauss = new float[inputImage.getSizeY() - (gaussDim - 1), inputImage.getSizeX() - (gaussDim - 1)]; /////////////////////////////////// input image -> GAUSS -> output image Gauss for (int y = gaussDim / 2; y < inputImage.getSizeY() - gaussDim / 2; y++) { for (int x = gaussDim / 2; x < inputImage.getSizeX() - gaussDim / 2; x++) { float r = applyConv(x, y, inputLuminance, gaussianMatrix); /*if (r < 0) r = 0; * if (r > 255) r = 255;*/ outputImageGauss[y - gaussDim / 2, x - gaussDim / 2] = r; } } /////////////////////////////////// output image Gauss -> SOBEL -> output image Sobel const int sobelDim = 3; float[,] convMatrixGx = new float[sobelDim, sobelDim] { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, -1 } }; float[,] convMatrixGy = new float[sobelDim, sobelDim] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } }; float[,] outputImageSobel = new float[outputImageGauss.GetLength(0) - (sobelDim - 1), outputImageGauss.GetLength(1) - (sobelDim - 1)]; DIRECTION[,] outputImageDirection = new DIRECTION[outputImageGauss.GetLength(0) - (sobelDim - 1), outputImageGauss.GetLength(1) - (sobelDim - 1)]; for (int y = sobelDim / 2; y < outputImageGauss.GetLength(0) - sobelDim / 2; y++) { for (int x = sobelDim / 2; x < outputImageGauss.GetLength(1) - sobelDim / 2; x++) { float resx = applyConv(x, y, outputImageGauss, convMatrixGx); float resy = applyConv(x, y, outputImageGauss, convMatrixGy); double r = Math.Sqrt((resx * resx) + (resy * resy)); /*if (r < 0) r = 0; * if (r > 255) r = 255;*/ outputImageSobel[y - sobelDim / 2, x - sobelDim / 2] = (float)r; outputImageDirection[y - sobelDim / 2, x - sobelDim / 2] = radiansToDirection(Math.Atan2(resy, resx)); } } /////////////////////////////////// output image Sobel & direction -> non maximum suppression -> outputImageNMS float float[,] floatOutputImageNms = new float[outputImageSobel.GetLength(0), outputImageSobel.GetLength(1)]; for (int y = 0; y < outputImageSobel.GetLength(0); y++) { for (int x = 0; x < outputImageSobel.GetLength(1); x++) { switch (outputImageDirection[y, x]) { case DIRECTION.HORIZONTAL: if (x >= 1 && x < outputImageSobel.GetLength(1) - 1 && outputImageSobel[y, x] > outputImageSobel[y, x - 1] && outputImageSobel[y, x] >= outputImageSobel[y, x + 1]) { floatOutputImageNms[y, x] = outputImageSobel[y, x]; } break; case DIRECTION.LEFT45: //case DIRECTION.RIGHT45: if (x >= 1 && x < outputImageSobel.GetLength(1) - 1 && y >= 1 && y < outputImageSobel.GetLength(0) - 1 && outputImageSobel[y, x] >= outputImageSobel[y - 1, x + 1] && outputImageSobel[y, x] > outputImageSobel[y + 1, x - 1]) { floatOutputImageNms[y, x] = outputImageSobel[y, x]; } break; case DIRECTION.VERTICAL: if (y >= 1 && y < outputImageSobel.GetLength(0) - 1 && outputImageSobel[y, x] > outputImageSobel[y - 1, x] && outputImageSobel[y, x] >= outputImageSobel[y + 1, x]) { floatOutputImageNms[y, x] = outputImageSobel[y, x]; } break; //case DIRECTION.LEFT45: case DIRECTION.RIGHT45: if (x >= 1 && x < outputImageSobel.GetLength(1) - 1 && y >= 1 && y < outputImageSobel.GetLength(0) - 1 && outputImageSobel[y, x] > outputImageSobel[y - 1, x - 1] && outputImageSobel[y, x] >= outputImageSobel[y + 1, x + 1]) { floatOutputImageNms[y, x] = outputImageSobel[y, x]; } break; } } } /////////////////////////////////// output image non maximum suppression float -> acceptance matrix & byte outputNms bool[,] acceptanceMatrix = new bool[floatOutputImageNms.GetLength(0), floatOutputImageNms.GetLength(1)]; byte[,] outputImageNms = new byte[floatOutputImageNms.GetLength(0), floatOutputImageNms.GetLength(1)]; for (int y = 0; y < floatOutputImageNms.GetLength(0); y++) { for (int x = 0; x < floatOutputImageNms.GetLength(1); x++) { float r = floatOutputImageNms[y, x]; if (r > 255) { r = 255; } if (r < 0) { r = 0; } outputImageNms[y, x] = (byte)r; acceptanceMatrix[y, x] = outputImageNms[y, x] >= highThreshold; } } Queue <KeyValuePair <int, int> > neighbors = new Queue <KeyValuePair <int, int> >(); for (int y = 0; y < outputImageNms.GetLength(0); y++) { for (int x = 0; x < outputImageNms.GetLength(1); x++) { if (acceptanceMatrix[y, x]) { if (y >= 1 && outputImageNms[y - 1, x] >= lowThreshold && outputImageNms[y - 1, x] < highThreshold) // up { neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x)); } if (y < outputImageNms.GetLength(0) - 1 && outputImageNms[y + 1, x] >= lowThreshold && outputImageNms[y + 1, x] < highThreshold) // down { neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x)); } if (x < outputImageNms.GetLength(1) - 1 && outputImageNms[y, x + 1] >= lowThreshold && outputImageNms[y, x + 1] < highThreshold) // right { neighbors.Enqueue(new KeyValuePair <int, int>(y, x + 1)); } if (x >= 1 && outputImageNms[y, x - 1] >= lowThreshold && outputImageNms[y, x - 1] < highThreshold) // left { neighbors.Enqueue(new KeyValuePair <int, int>(y, x - 1)); } if (y >= 1 && x < outputImageNms.GetLength(1) - 1 && outputImageNms[y - 1, x + 1] >= lowThreshold && outputImageNms[y - 1, x + 1] < highThreshold) //right-up { neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x + 1)); } if (x >= 1 && y >= 1 && outputImageNms[y - 1, x - 1] >= lowThreshold && outputImageNms[y - 1, x - 1] < highThreshold) // left-up { neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x - 1)); } if (y < outputImageNms.GetLength(0) - 1 && x >= 1 && outputImageNms[y + 1, x - 1] >= lowThreshold && outputImageNms[y + 1, x - 1] < highThreshold) // left-down { neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x - 1)); } if (x < outputImageNms.GetLength(1) - 1 && y < outputImageNms.GetLength(0) - 1 && outputImageNms[y + 1, x + 1] >= lowThreshold && outputImageNms[y + 1, x + 1] < highThreshold) // right-down { neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x + 1)); } } } } while (neighbors.Count > 0) { KeyValuePair <int, int> xy = neighbors.Dequeue(); int y = xy.Key; int x = xy.Value; if (!acceptanceMatrix[y, x]) { acceptanceMatrix[y, x] = true; if (y >= 1 && outputImageNms[y - 1, x] >= lowThreshold && outputImageNms[y - 1, x] < highThreshold) // up { neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x)); } if (y < outputImageNms.GetLength(0) - 1 && outputImageNms[y + 1, x] >= lowThreshold && outputImageNms[y + 1, x] < highThreshold) // down { neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x)); } if (x < outputImageNms.GetLength(1) - 1 && outputImageNms[y, x + 1] >= lowThreshold && outputImageNms[y, x + 1] < highThreshold) // right { neighbors.Enqueue(new KeyValuePair <int, int>(y, x + 1)); } if (x >= 1 && outputImageNms[y, x - 1] >= lowThreshold && outputImageNms[y, x - 1] < highThreshold) // left { neighbors.Enqueue(new KeyValuePair <int, int>(y, x - 1)); } if (y >= 1 && x < outputImageNms.GetLength(1) - 1 && outputImageNms[y - 1, x + 1] >= lowThreshold && outputImageNms[y - 1, x + 1] < highThreshold) //right-up { neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x + 1)); } if (x >= 1 && y >= 1 && outputImageNms[y - 1, x - 1] >= lowThreshold && outputImageNms[y - 1, x - 1] < highThreshold) // left-up { neighbors.Enqueue(new KeyValuePair <int, int>(y - 1, x - 1)); } if (y < outputImageNms.GetLength(0) - 1 && x >= 1 && outputImageNms[y + 1, x - 1] >= lowThreshold && outputImageNms[y + 1, x - 1] < highThreshold) // left-down { neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x - 1)); } if (x < outputImageNms.GetLength(1) - 1 && y < outputImageNms.GetLength(0) - 1 && outputImageNms[y + 1, x + 1] >= lowThreshold && outputImageNms[y + 1, x + 1] < highThreshold) // right-down { neighbors.Enqueue(new KeyValuePair <int, int>(y + 1, x + 1)); } } } /////////////////////////////////// output image non maximum suppression -> histeresis threshold-> outputImageHisteresis float[,] outputImageHist = new float[outputImageNms.GetLength(0), outputImageNms.GetLength(1)]; for (int y = 0; y < outputImageNms.GetLength(0); y++) { for (int x = 0; x < outputImageNms.GetLength(1); x++) { if (acceptanceMatrix[y, x]) { outputImageHist[y, x] = outputImageNms[y, x]; } } } ////////////////////////////////// to byte byte[,] outputGray = new byte[outputImageHist.GetLength(0), outputImageHist.GetLength(1)]; for (int y = 0; y < outputGray.GetLength(0); y++) { for (int x = 0; x < outputGray.GetLength(1); x++) { float r = outputImageHist[y, x]; if (r < 0) { r = 0; } if (r > 255) { r = 255; } outputGray[y, x] = (byte)r; } } outputImage.setSizeX(outputGray.GetLength(1)); outputImage.setSizeY(outputGray.GetLength(0)); outputImage.setGray(outputGray); return(outputImage); }
public ProcessingImage filter(ProcessingImage inputImage) { ProcessingImage outputImage = new ProcessingImage(); outputImage.copyAttributesAndAlpha(inputImage); outputImage.addWatermark(String.Format("LoG watermark")); // intout -> laplacian of gaussian -> output LOG const int logDim = 5; float[,] laplacianOfGaussian = new float[logDim, logDim] { { 0, 0, -1, 0, 0 }, { 0, -1, -2, -1, 0 }, { -1, -2, 16, -2, -1 }, { 0, -1, -2, -1, 0 }, { 0, 0, -1, 0, 0 }, }; byte[,] inputLuminance = inputImage.getLuminance(); int[,] outputImageLoG = new int[inputImage.getSizeY() - (logDim - 1), inputImage.getSizeX() - (logDim - 1)]; for (int y = logDim / 2; y < inputImage.getSizeY() - logDim / 2; y++) //getlength0 { for (int x = logDim / 2; x < inputImage.getSizeX() - logDim / 2; x++) //getlength1 { float r = applyConv(x, y, inputLuminance, laplacianOfGaussian); outputImageLoG[y - logDim / 2, x - logDim / 2] = (int)r; } } // LOG -> zero crossing -> output byte[,] outputImageZC = new byte[outputImageLoG.GetLength(0), outputImageLoG.GetLength(1)]; for (int y = 0; y < outputImageLoG.GetLength(0); y++) { for (int x = 0; x < outputImageLoG.GetLength(1); x++) { bool zeroCrossing = false; //left if (x >= 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y, x - 1])) { zeroCrossing = true; } //upper left else if (x >= 1 && y >= 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y - 1, x - 1])) { zeroCrossing = true; } //up else if (y >= 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y - 1, x])) { zeroCrossing = true; } //upper right else if (y >= 1 && x < outputImageLoG.GetLength(1) - 1 && Math.Sign(outputImageLoG[y, x]) != Math.Sign(outputImageLoG[y - 1, x + 1])) { zeroCrossing = true; } if (zeroCrossing) { outputImageZC[y, x] = 255; } } } ////////////////////////////////// to byte byte[,] outputGray = new byte[outputImageZC.GetLength(0), outputImageZC.GetLength(1)]; for (int y = 0; y < outputGray.GetLength(0); y++) { for (int x = 0; x < outputGray.GetLength(1); x++) { float r = outputImageZC[y, x]; if (r < 0) { r = 0; } if (r > 255) { r = 255; } outputGray[y, x] = (byte)r; } } outputImage.setSizeX(outputGray.GetLength(1)); outputImage.setSizeY(outputGray.GetLength(0)); outputImage.setGray(outputGray); return(outputImage); }
public ProcessingImage filter(ProcessingImage inputImage) { ProcessingImage outputImage = new ProcessingImage(); outputImage.copyAttributesAndAlpha(inputImage); outputImage.addWatermark(String.Format("Active contour filter watermark")); double k = 0.001; int radius = 25; byte[,] inputLuminance = inputImage.getLuminance(); int centerX = inputImage.getSizeX() / 2; int centerY = inputImage.getSizeY() / 2; int[,] outputImageResult = new int[inputImage.getSizeY(), inputImage.getSizeX()]; outputImageResult[centerY, centerX] = 255; Point[] points = new Point[numPoints]; int n = 0; for (double i = 0; i < 2 * Math.PI && n < numPoints; i += (2 * Math.PI) / numPoints) { double sinRes = Math.Sin(i); double cosRes = Math.Cos(i); points[n] = new Point(); points[n].x = centerY + (radius * sinRes); points[n].y = centerX + (radius * cosRes); n++; } for (int i = 0; i < numPoints; i++) { outputImageResult[(int)points[i].y, (int)points[i].x] = 255; } for (int s = 0; s < numSteps; s++) { for (int i = 0; i < numPoints; i++) { int up_i = i + 1; int down_i = i - 1; if (up_i >= numPoints - 1) { up_i = 0; } if (down_i < 0) { down_i = numPoints - 1; } double dx1 = points[down_i].x - points[i].x; double dx2 = points[up_i].x - points[i].x; double dy1 = points[down_i].y - points[i].y; double dy2 = points[up_i].y - points[i].y; points[i].accelX = k * dx1 + k * dx2; //elastic force, we approximate F=ma with a mass of 1 points[i].accelY = k * dy1 + k * dy2; // sum of forces that act on the object on both axes points[i].speedY = points[i].speedY + points[i].accelY; points[i].speedX = points[i].speedX + points[i].accelX; if (points[i].speedY > 2) { points[i].speedY = 2; } if (points[i].speedY < -2) { points[i].speedY = -2; } if (points[i].speedX > 2) { points[i].speedX = 2; } if (points[i].speedX < -2) { points[i].speedX = -2; } points[i].y = (points[i].y + points[i].speedY); points[i].x = (points[i].x + points[i].speedX); } } for (int i = 0; i < numPoints; i++) { if ((int)points[i].y >= 0 && (int)points[i].x >= 0 && (int)points[i].x < outputImage.getSizeX() && (int)points[i].y < outputImage.getSizeY()) { outputImageResult[(int)points[i].y, (int)points[i].x] = 100; } } ////////////////////////////////// to byte byte[,] outputGray = new byte[outputImageResult.GetLength(0), outputImageResult.GetLength(1)]; for (int y = 0; y < outputGray.GetLength(0); y++) { for (int x = 0; x < outputGray.GetLength(1); x++) { float r = outputImageResult[y, x]; if (r < 0) { r = 0; } if (r > 255) { r = 255; } outputGray[y, x] = (byte)r; } } outputImage.setSizeX(outputGray.GetLength(1)); outputImage.setSizeY(outputGray.GetLength(0)); outputImage.setGray(outputGray); return(outputImage); }