Created
June 25, 2020 22:28
-
-
Save volfegan/1ab76e99883d82f05a0eac9661dd6cce to your computer and use it in GitHub Desktop.
Custom high-pass (Sharpening) filter for Processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//author Volfegan: https://twitter.com/VolfeganGeist | |
//resources: | |
//high-pass filter (Sharpening) https://processing.org/examples/edgedetection.html | |
import java.util.UUID; | |
PImage img; | |
PImage sortedPixels; //image processed | |
boolean save = false; | |
int width = 0; | |
int height = 0; | |
String filename; | |
//there is no file validation, so any non-img selected will crash the program | |
void fileSelected(File selection) { | |
if (selection == null) { | |
println("No image file selected."); | |
exit(); | |
} else { | |
String filepath = selection.getAbsolutePath(); | |
filename = selection.getName(); | |
int pos = filename.lastIndexOf("."); | |
if (pos != -1) filename = filename.substring(0, pos); | |
println("File selected " + filepath); | |
// load file here | |
img = loadImage(filepath); | |
} | |
} | |
void interrupt() { | |
while (img==null) delay(200); | |
} | |
void settings() { | |
selectInput("Select an image file to process:", "fileSelected"); | |
interrupt(); //interrupt process until img is selected | |
width = img.width; | |
height = img.height; | |
if (width > 1920) { | |
int resizer = width / 1200; | |
width = 1200; | |
height = height / resizer; | |
img.resize(width, height); | |
} | |
if (height > 1080) { | |
int resizer = height / 900; | |
height = 900; | |
width = width / resizer; | |
img.resize(width, height); | |
} | |
//the canvas window size will be according to the img size | |
size(width, height); | |
} | |
void setup() { | |
// Create an opaque image of the same size as the original | |
sortedPixels = createImage(img.width, img.height, RGB); | |
sortedPixels = img.get(); | |
//High Pass (Sharpening) | |
sortedPixels = highPassFilter(sortedPixels); | |
background(0); | |
image(sortedPixels, 0, 0); | |
if (save) { | |
//save the image with a random id | |
save("image_"+UUID.randomUUID().toString().replace("-", "")+".png"); | |
} | |
} | |
//return a sharp edge PImage | |
public PImage highPassFilter(PImage image) { | |
//high-pass matrix | |
float[][] kernel = { | |
{ -1, -1, -1}, | |
{ -1, 9, -1}, | |
{ -1, -1, -1}}; | |
image.loadPixels(); | |
// Create an opaque image of the same size as the original | |
PImage processedImg = createImage(image.width, image.height, RGB); | |
// Loop through every pixel in the image. | |
for (int y = 0; y < image.height-1; y++) { | |
for (int x = 0; x < image.width-1; x++) { | |
//Skip left and right, top and bottom edges to avoid aberations | |
if (x==0 || y==0 || x==image.width-1 || y==image.height-1) continue; | |
float sum = 0; // Kernel sum for this pixel | |
for (int ky = -1; ky <= 1; ky++) { | |
for (int kx = -1; kx <= 1; kx++) { | |
// Calculate the adjacent pixel for this kernel point | |
int pos = (y + ky)*image.width + (x + kx); | |
// Image is grayscale, red/green/blue are identical | |
float val = red(image.pixels[pos]); | |
// Multiply adjacent pixels based on the kernel values | |
sum += kernel[ky+1][kx+1] * val; | |
} | |
} | |
// For this pixel in the new image, set the gray value | |
// based on the sum from the kernel | |
processedImg.pixels[y*image.width + x] = color(sum, sum, sum); | |
} | |
} | |
// State that there are changes to processedImg.pixels[] | |
processedImg.updatePixels(); | |
return processedImg; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment