123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751 |
- //"rendering" in terms of "render to disk", not to screen. that is given in draw()
-
- PImage sobelEdgeImg;
- PImage sobelEdgeImg2;
- PImage cannyEdgeImg;
- PImage cannyEdgeImg2;
- PGraphics renderFiltered;
-
- PImage[] masksRender;
- int masksRenderAmount = 3; //for airis
- int masksSize = 1024;
-
- //PImage roundMaskImage; //for obs-studio greenscreenremoval // have the source be in a circle
-
-
- void render() {
- if (airisRendering) {
- //render grayscale image
- renderFiltered = createGraphics((renderer.width < renderer.height) ? int(map(renderer.width, 0, renderer.height, 0, masksSize)) : masksSize, (renderer.width < renderer.height) ? masksSize : int(map(renderer.height, 0, renderer.width, 0, masksSize)));
- renderFiltered.beginDraw();
- renderFiltered.image(renderer, 0, 0, renderFiltered.width, renderFiltered.height);
- renderFiltered.endDraw();
- //sobelEdgeImg = sobelEdge(renderFiltered);
- //sobelEdgeImg = sobelEdge(sobelEdgeImg);
- //sobelEdgeImg.filter(INVERT); //<- best sobel results here
- //cannyEdgeImg = cannyEdge(renderFiltered); //better look bellow
- renderFiltered.beginDraw();
- renderFiltered.filter(GRAY);
- renderFiltered.filter(POSTERIZE, masksRenderAmount);
- //renderFiltered. giers PUT A CONTRAST CORRECTION HERE!
- renderFiltered.loadPixels();
- renderFiltered.endDraw();
- cannyEdgeImg2 = cannyEdge(renderFiltered); //<- best canny results here
- //sobelEdgeImg2 = sobelEdge(renderFiltered); //better look above
-
-
- //render mask layers
- PImage imgRenderFiltered = renderFiltered.get();
- imgRenderFiltered.loadPixels();
- color[] c = new color[masksRender.length];
- int cc = 0;
- for (int i = 0; i < renderFiltered.width*renderFiltered.height; i ++) {
- boolean exists = false;
- for (int j = 0; j < c.length; j++) {
- if (color(renderFiltered.pixels[i]) == c[j]) exists = true;
- }
- if (!exists) {
- c[cc] = color(renderFiltered.pixels[i]);
- cc++;
- }
- }
- for (int i = 0; i < masksRender.length; i ++) {
- masksRender[i] = createImage(renderFiltered.width, renderFiltered.height, ARGB);
- masksRender[i].loadPixels();
- for (int j = 0; j < masksRender[i].width*masksRender[i].height; j++) {
- if (c[i] == color(imgRenderFiltered.pixels[j])) {
- masksRender[i].pixels[j] = color(255);
- } else {
- masksRender[i].pixels[j] = color(0);
- }
- }
- }
-
- // render edge image
- /* old, processing edge detection example
- float[][] kernel = {{ -1, -1, -1},
- { -1, 9, -1},
- { -1, -1, -1}};
-
- edgeImg = createImage(renderFiltered.width, renderFiltered.height, RGB);
- for (int y = 1; y < renderFiltered.height-1; y++) {
- for (int x = 1; x < renderFiltered.width-1; x++) {
- float sum = 0;
- for (int ky = -1; ky <= 1; ky++) {
- for (int kx = -1; kx <= 1; kx++) {
- int pos = (y + ky)*renderFiltered.width + (x + kx);
- float val = red(renderFiltered.pixels[pos]);
- sum += kernel[ky+1][kx+1] * val;
- }
- }
- edgeImg.pixels[y*renderFiltered.width + x] = color(sum, sum, sum);
- }
- }
- edgeImg.updatePixels();
- */
- }
- }
-
-
- void airisRender(int size) {
- if (!airisRendering) {
- airisRendering = true;
- previousRenderSize = renderSize;
- previousRecordState = recording;
- renderSize = size;
- recording = true;
- }
- }
-
- boolean airisRendering;
- int previousRenderSize;
- boolean previousRecordState;
-
- void snapshot() {
- frameName = str(frameCount + int(uptime));
- if (airisRendering) {
- String renderPath = dataPath("")+"/snapshots/" + frameName + "_rendered/";
- renderer.save(renderPath + frameName + ".png");
- //edgeImg.save(renderPath + frameName + "_edges.bmp");
- //exec(dataPath("potrace"), "--svg", renderPath + frameName + "_edges.bmp", "-o", renderPath + frameName + "_edges.svg");
- //sobelEdgeImg.save(renderPath + frameName + "_edgeSobel.png");
- //cannyEdgeImg.save(renderPath + frameName + "_edgeCanny.png");
- //cannyEdgeImg2.save(renderPath + frameName + "_edgeCanny2.png");
- cannyEdgeImg2.save(renderPath + frameName + "_edge.png");
- //edgeImg2.save(renderPath + frameName + "_edges2.png");
- //renderFiltered.save(renderPath + frameName + "_filtered.png");
-
- //pack 3 masks into one image
- PImage packedMasks = createImage(masksRender[0].width, masksRender[0].height, RGB);
- packedMasks.loadPixels();
-
-
- for (int i = 0; i < masksRender.length; i ++) {
- masksRender[i].save(renderPath + frameName + "_mask_" + i + ".png");
- }
- for (int j = 0; j < masksRender[0].pixels.length; j++) {
- packedMasks.pixels[j] = color(red(masksRender[0].pixels[j]), green(masksRender[1].pixels[j]), blue(masksRender[2].pixels[j]));
- }
- packedMasks.updatePixels();
- packedMasks.save(renderPath + frameName + "_masks_packed.png");
-
- composiorServer.write("images " + renderer.width + " " + renderer.height + " " + renderPath);
- println("Rendered & Message sent");
- } else {
- renderer.save(dataPath("")+"/snapshots/" + frameName + ".png");
- }
- saveData[1] = "uptime = " + frameName;
- println("Rendered " + frameName + ".png at " + dataPath("")+"/snapshots/ with a resolution of " + renderer.width + " x " + renderer.height);
- saveStrings(dataPath("saves.sav"), saveData);
- }
-
-
-
-
- //the following two effects were not implemented as fx-shaders.
- //these are just for iris // vector tracing
-
- /*******************************************
- * CANNY EDGE DETECTOR FOR VECTOR TRACING
- *******************************************/
-
- import java.awt.image.BufferedImage;
- import java.util.Arrays;
-
-
- PImage cannyEdge(PImage img){
- CannyEdgeDetector detector = new CannyEdgeDetector();
- detector.setLowThreshold(0.5f);
- detector.setHighThreshold(1f);
- detector.setSourceImage((java.awt.image.BufferedImage)img.getImage());
- detector.process();
- BufferedImage edges = detector.getEdgesImage();
- PImage changed = new PImage(edges);
- return changed;
- }
-
- // The code below is taken from "http://www.tomgibara.com/computer-vision/CannyEdgeDetector.java"
- // I have stripped the comments for conciseness
-
- public class CannyEdgeDetector {
-
- // statics
-
- private final static float GAUSSIAN_CUT_OFF = 0.005f;
- private final static float MAGNITUDE_SCALE = 100F;
- private final static float MAGNITUDE_LIMIT = 1000F;
- private final static int MAGNITUDE_MAX = (int) (MAGNITUDE_SCALE * MAGNITUDE_LIMIT);
-
- // fields
-
- private int height;
- private int width;
- private int picsize;
- private int[] data;
- private int[] magnitude;
- private BufferedImage sourceImage;
- private BufferedImage edgesImage;
-
- private float gaussianKernelRadius;
- private float lowThreshold;
- private float highThreshold;
- private int gaussianKernelWidth;
- private boolean contrastNormalized;
-
- private float[] xConv;
- private float[] yConv;
- private float[] xGradient;
- private float[] yGradient;
-
- // constructors
-
- /**
- * Constructs a new detector with default parameters.
- */
-
- public CannyEdgeDetector() {
- lowThreshold = 2.5f;
- highThreshold = 7.5f;
- gaussianKernelRadius = 2f;
- gaussianKernelWidth = 16;
- contrastNormalized = false;
- }
-
-
-
- public BufferedImage getSourceImage() {
- return sourceImage;
- }
-
-
- public void setSourceImage(BufferedImage image) {
- sourceImage = image;
- }
-
-
- public BufferedImage getEdgesImage() {
- return edgesImage;
- }
-
-
- public void setEdgesImage(BufferedImage edgesImage) {
- this.edgesImage = edgesImage;
- }
-
-
- public float getLowThreshold() {
- return lowThreshold;
- }
-
-
- public void setLowThreshold(float threshold) {
- if (threshold < 0) throw new IllegalArgumentException();
- lowThreshold = threshold;
- }
-
- public float getHighThreshold() {
- return highThreshold;
- }
-
-
- public void setHighThreshold(float threshold) {
- if (threshold < 0) throw new IllegalArgumentException();
- highThreshold = threshold;
- }
-
- public int getGaussianKernelWidth() {
- return gaussianKernelWidth;
- }
-
- public void setGaussianKernelWidth(int gaussianKernelWidth) {
- if (gaussianKernelWidth < 2) throw new IllegalArgumentException();
- this.gaussianKernelWidth = gaussianKernelWidth;
- }
-
- public float getGaussianKernelRadius() {
- return gaussianKernelRadius;
- }
-
- public void setGaussianKernelRadius(float gaussianKernelRadius) {
- if (gaussianKernelRadius < 0.1f) throw new IllegalArgumentException();
- this.gaussianKernelRadius = gaussianKernelRadius;
- }
-
- public boolean isContrastNormalized() {
- return contrastNormalized;
- }
-
- public void setContrastNormalized(boolean contrastNormalized) {
- this.contrastNormalized = contrastNormalized;
- }
-
- // methods
-
- public void process() {
- width = sourceImage.getWidth();
- height = sourceImage.getHeight();
- picsize = width * height;
- initArrays();
- readLuminance();
- if (contrastNormalized) normalizeContrast();
- computeGradients(gaussianKernelRadius, gaussianKernelWidth);
- int low = Math.round(lowThreshold * MAGNITUDE_SCALE);
- int high = Math.round( highThreshold * MAGNITUDE_SCALE);
- performHysteresis(low, high);
- thresholdEdges();
- writeEdges(data);
- }
-
- // private utility methods
-
- private void initArrays() {
- if (data == null || picsize != data.length) {
- data = new int[picsize];
- magnitude = new int[picsize];
-
- xConv = new float[picsize];
- yConv = new float[picsize];
- xGradient = new float[picsize];
- yGradient = new float[picsize];
- }
- }
- private void computeGradients(float kernelRadius, int kernelWidth) {
-
- //generate the gaussian convolution masks
- float kernel[] = new float[kernelWidth];
- float diffKernel[] = new float[kernelWidth];
- int kwidth;
- for (kwidth = 0; kwidth < kernelWidth; kwidth++) {
- float g1 = gaussian(kwidth, kernelRadius);
- if (g1 <= GAUSSIAN_CUT_OFF && kwidth >= 2) break;
- float g2 = gaussian(kwidth - 0.5f, kernelRadius);
- float g3 = gaussian(kwidth + 0.5f, kernelRadius);
- kernel[kwidth] = (g1 + g2 + g3) / 3f / (2f * (float) Math.PI * kernelRadius * kernelRadius);
- diffKernel[kwidth] = g3 - g2;
- }
-
- int initX = kwidth - 1;
- int maxX = width - (kwidth - 1);
- int initY = width * (kwidth - 1);
- int maxY = width * (height - (kwidth - 1));
-
- //perform convolution in x and y directions
- for (int x = initX; x < maxX; x++) {
- for (int y = initY; y < maxY; y += width) {
- int index = x + y;
- float sumX = data[index] * kernel[0];
- float sumY = sumX;
- int xOffset = 1;
- int yOffset = width;
- for (; xOffset < kwidth; ) {
- sumY += kernel[xOffset] * (data[index - yOffset] + data[index + yOffset]);
- sumX += kernel[xOffset] * (data[index - xOffset] + data[index + xOffset]);
- yOffset += width;
- xOffset++;
- }
-
- yConv[index] = sumY;
- xConv[index] = sumX;
- }
- }
-
- for (int x = initX; x < maxX; x++) {
- for (int y = initY; y < maxY; y += width) {
- float sum = 0f;
- int index = x + y;
- for (int i = 1; i < kwidth; i++)
- sum += diffKernel[i] * (yConv[index - i] - yConv[index + i]);
-
- xGradient[index] = sum;
- }
- }
-
- for (int x = kwidth; x < width - kwidth; x++) {
- for (int y = initY; y < maxY; y += width) {
- float sum = 0.0f;
- int index = x + y;
- int yOffset = width;
- for (int i = 1; i < kwidth; i++) {
- sum += diffKernel[i] * (xConv[index - yOffset] - xConv[index + yOffset]);
- yOffset += width;
- }
-
- yGradient[index] = sum;
- }
- }
-
- initX = kwidth;
- maxX = width - kwidth;
- initY = width * kwidth;
- maxY = width * (height - kwidth);
- for (int x = initX; x < maxX; x++) {
- for (int y = initY; y < maxY; y += width) {
- int index = x + y;
- int indexN = index - width;
- int indexS = index + width;
- int indexW = index - 1;
- int indexE = index + 1;
- int indexNW = indexN - 1;
- int indexNE = indexN + 1;
- int indexSW = indexS - 1;
- int indexSE = indexS + 1;
-
- float xGrad = xGradient[index];
- float yGrad = yGradient[index];
- float gradMag = hypot(xGrad, yGrad);
-
- //perform non-maximal supression
- float nMag = hypot(xGradient[indexN], yGradient[indexN]);
- float sMag = hypot(xGradient[indexS], yGradient[indexS]);
- float wMag = hypot(xGradient[indexW], yGradient[indexW]);
- float eMag = hypot(xGradient[indexE], yGradient[indexE]);
- float neMag = hypot(xGradient[indexNE], yGradient[indexNE]);
- float seMag = hypot(xGradient[indexSE], yGradient[indexSE]);
- float swMag = hypot(xGradient[indexSW], yGradient[indexSW]);
- float nwMag = hypot(xGradient[indexNW], yGradient[indexNW]);
- float tmp;
-
- if (xGrad * yGrad <= (float) 0 /*(1)*/
- ? Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/
- ? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * neMag - (xGrad + yGrad) * eMag) /*(3)*/
- && tmp > Math.abs(yGrad * swMag - (xGrad + yGrad) * wMag) /*(4)*/
- : (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * neMag - (yGrad + xGrad) * nMag) /*(3)*/
- && tmp > Math.abs(xGrad * swMag - (yGrad + xGrad) * sMag) /*(4)*/
- : Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/
- ? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * seMag + (xGrad - yGrad) * eMag) /*(3)*/
- && tmp > Math.abs(yGrad * nwMag + (xGrad - yGrad) * wMag) /*(4)*/
- : (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * seMag + (yGrad - xGrad) * sMag) /*(3)*/
- && tmp > Math.abs(xGrad * nwMag + (yGrad - xGrad) * nMag) /*(4)*/
- ) {
- magnitude[index] = gradMag >= MAGNITUDE_LIMIT ? MAGNITUDE_MAX : (int) (MAGNITUDE_SCALE * gradMag);
- //NOTE: The orientation of the edge is not employed by this
- //implementation. It is a simple matter to compute it at
- //this point as: Math.atan2(yGrad, xGrad);
- } else {
- magnitude[index] = 0;
- }
- }
- }
- }
-
- private float hypot(float x, float y) {
- return (float) Math.hypot(x, y);
- }
-
- private float gaussian(float x, float sigma) {
- return (float) Math.exp(-(x * x) / (2f * sigma * sigma));
- }
-
- private void performHysteresis(int low, int high) {
-
- Arrays.fill(data, 0);
-
- int offset = 0;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- if (data[offset] == 0 && magnitude[offset] >= high) {
- follow(x, y, offset, low);
- }
- offset++;
- }
- }
- }
-
- private void follow(int x1, int y1, int i1, int threshold) {
- int x0 = x1 == 0 ? x1 : x1 - 1;
- int x2 = x1 == width - 1 ? x1 : x1 + 1;
- int y0 = y1 == 0 ? y1 : y1 - 1;
- int y2 = y1 == height -1 ? y1 : y1 + 1;
-
- data[i1] = magnitude[i1];
- for (int x = x0; x <= x2; x++) {
- for (int y = y0; y <= y2; y++) {
- int i2 = x + y * width;
- if ((y != y1 || x != x1)
- && data[i2] == 0
- && magnitude[i2] >= threshold) {
- follow(x, y, i2, threshold);
- return;
- }
- }
- }
- }
-
- private void thresholdEdges() {
- for (int i = 0; i < picsize; i++) {
- data[i] = data[i] > 0 ? -1 : 0xff000000;
- }
- }
-
- private int luminance(float r, float g, float b) {
- return Math.round(0.299f * r + 0.587f * g + 0.114f * b);
- }
-
- private void readLuminance() {
- int type = sourceImage.getType();
- if (type == BufferedImage.TYPE_INT_RGB || type == BufferedImage.TYPE_INT_ARGB) {
- int[] pixels = (int[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
- for (int i = 0; i < picsize; i++) {
- int p = pixels[i];
- int r = (p & 0xff0000) >> 16;
- int g = (p & 0xff00) >> 8;
- int b = p & 0xff;
- data[i] = luminance(r, g, b);
- }
- } else if (type == BufferedImage.TYPE_BYTE_GRAY) {
- byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
- for (int i = 0; i < picsize; i++) {
- data[i] = (pixels[i] & 0xff);
- }
- } else if (type == BufferedImage.TYPE_USHORT_GRAY) {
- short[] pixels = (short[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
- for (int i = 0; i < picsize; i++) {
- data[i] = (pixels[i] & 0xffff) / 256;
- }
- } else if (type == BufferedImage.TYPE_3BYTE_BGR) {
- byte[] pixels = (byte[]) sourceImage.getData().getDataElements(0, 0, width, height, null);
- int offset = 0;
- for (int i = 0; i < picsize; i++) {
- int b = pixels[offset++] & 0xff;
- int g = pixels[offset++] & 0xff;
- int r = pixels[offset++] & 0xff;
- data[i] = luminance(r, g, b);
- }
- } else {
- throw new IllegalArgumentException("Unsupported image type: " + type);
- }
- }
-
- private void normalizeContrast() {
- int[] histogram = new int[256];
- for (int i = 0; i < data.length; i++) {
- histogram[data[i]]++;
- }
- int[] remap = new int[256];
- int sum = 0;
- int j = 0;
- for (int i = 0; i < histogram.length; i++) {
- sum += histogram[i];
- int target = sum*255/picsize;
- for (int k = j+1; k <=target; k++) {
- remap[k] = i;
- }
- j = target;
- }
-
- for (int i = 0; i < data.length; i++) {
- data[i] = remap[data[i]];
- }
- }
-
- private void writeEdges(int pixels[]) {
- if (edgesImage == null) {
- edgesImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
- }
- edgesImage.getWritableTile(0, 0).setDataElements(0, 0, width, height, pixels);
- }
- }
-
-
- /***************************************
- * SOBELEDGE DETECTION FOR VECTOR TRACING
- ***************************************/
-
-
- SobelEdgeDetection sobel;
-
- PImage sobelEdge(PImage img) {
- PImage g_img = sobel.findEdgesAll(img, 90);
- g_img = sobel.noiseReduction(g_img, 1);
- return(g_img);
- }
-
-
- class SobelEdgeDetection
- {
-
- // Sobel Edge Detection strandard, this applies the edge detection algorithm across the entire image and returns the edge image
- public PImage findEdgesAll(PImage img, int tolerance)
- {
- PImage buf = createImage( img.width, img.height, ARGB );
-
- int GX[][] = new int[3][3];
- int GY[][] = new int[3][3];
- int sumRx = 0;
- int sumGx = 0;
- int sumBx = 0;
- int sumRy = 0;
- int sumGy = 0;
- int sumBy = 0;
- int finalSumR = 0;
- int finalSumG = 0;
- int finalSumB = 0;
-
- // 3x3 Sobel Mask for X
- GX[0][0] = -1;
- GX[0][1] = 0;
- GX[0][2] = 1;
- GX[1][0] = -2;
- GX[1][1] = 0;
- GX[1][2] = 2;
- GX[2][0] = -1;
- GX[2][1] = 0;
- GX[2][2] = 1;
-
- // 3x3 Sobel Mask for Y
- GY[0][0] = 1;
- GY[0][1] = 2;
- GY[0][2] = 1;
- GY[1][0] = 0;
- GY[1][1] = 0;
- GY[1][2] = 0;
- GY[2][0] = -1;
- GY[2][1] = -2;
- GY[2][2] = -1;
-
- buf.loadPixels();
-
- for(int y = 0; y < img.height; y++)
- {
- for(int x = 0; x < img.width; x++)
- {
- if(y==0 || y==img.height-1) {
- }
- else if( x==0 || x == img.width-1 ) {
- }
- else
- {
-
- // Convolve across the X axis and return gradiant aproximation
- for(int i = -1; i <= 1; i++)
- for(int j = -1; j <= 1; j++)
- {
- color col = img.get(x + i, y + j);
- float r = red(col);
- float g = green(col);
- float b = blue(col);
-
-
- sumRx += r * GX[ i + 1][ j + 1];
- sumGx += g * GX[ i + 1][ j + 1];
- sumBx += b * GX[ i + 1][ j + 1];
-
- }
-
- // Convolve across the Y axis and return gradiant aproximation
- for(int i = -1; i <= 1; i++)
- for(int j = -1; j <= 1; j++)
- {
- color col = img.get(x + i, y + j);
- float r = red(col);
- float g = green(col);
- float b = blue(col);
-
-
- sumRy += r * GY[ i + 1][ j + 1];
- sumGy += g * GY[ i + 1][ j + 1];
- sumBy += b * GY[ i + 1][ j + 1];
-
- }
-
- finalSumR = abs(sumRx) + abs(sumRy);
- finalSumG = abs(sumGx) + abs(sumGy);
- finalSumB = abs(sumBx) + abs(sumBy);
-
-
- // I only want to return a black or a white value, here I determine the greyscale value,
- // and if it is above a tolerance, then set the colour to white
-
- float gray = (finalSumR + finalSumG + finalSumB) / 3;
- if(gray > tolerance)
- {
- finalSumR = 0;
- finalSumG = 0;
- finalSumB = 0;
- }
- else
- {
- finalSumR = 255;
- finalSumG = 255;
- finalSumB = 255;
- }
-
-
-
- buf.pixels[ x + (y * img.width) ] = color(finalSumR, finalSumG, finalSumB);
-
- sumRx=0;
- sumGx=0;
- sumBx=0;
- sumRy=0;
- sumGy=0;
- sumBy=0;
-
- }
-
- }
-
- }
-
- buf.updatePixels();
-
- return buf;
- }
-
-
-
- public PImage noiseReduction(PImage img, int kernel)
- {
- PImage buf = createImage( img.width, img.height, ARGB );
-
-
- buf.loadPixels();
-
- for(int y = 0; y < img.height; y++)
- {
- for(int x = 0; x < img.width; x++)
- {
-
- int sumR = 0;
- int sumG = 0;
- int sumB = 0;
-
- // Convolute across the image, averages out the pixels to remove noise
- for(int i = -kernel; i <= kernel; i++)
- {
- for(int j = -kernel; j <= kernel; j++)
- {
- color col = img.get(x+i,y+j);
- float r = red(col);
- float g = green(col);
- float b = blue(col);
-
- if(r==255) sumR++;
- if(g==255) sumG++;
- if(b==255) sumB++;
- }
- }
-
- int halfKernel = (((kernel*2)+1) * ((kernel*2)+1)) / 2 ;
-
- if(sumR > halfKernel ) sumR=255;
- else sumR= 0;
- if(sumG > halfKernel ) sumG=255;
- else sumG= 0;
- if(sumB > halfKernel ) sumB=255;
- else sumB= 0;
-
-
- buf.pixels[ x + (y * img.width) ] = color(sumR, sumG, sumB);
-
- }
-
-
- }
- buf.updatePixels();
-
- return buf;
- }
-
-
- }
|