3/29/2012 Thresholding for Image Segmentation Review • Pixels below a cutoff value are set to black • Images – an array of colors • Pixels above a cutoff value are set to white • Color – RGBA • Loading, modifying, updating pixels • pixels[] as a 2D array • Animating with arrays of images + transformations • PImage class, fields and methods • get() method and crumble • tint() function – color and alpha filtering • Creative image processing – Pointillism • Video Library • Recording animated sketches as movie files threshold.pde Obamicon // obamicon void setup() { // Posterize image loadPixels(); // Load image PImage img = loadImage("head.jpg"); for (int i = 0; i < pixels.length; i++) { // Get pixel color // Define colors color c = pixels[i]; color darkBlue = color(0, 51, 76); color reddish = color(217, 26, 33); // Total color components color lightBlue = color(112, 150, 158); float total = red(c)+green(c)+blue(c); color yellow = color(252, 227, 166); // Remap to new color // Size sketch window if (total < 182) { size(img.width, img.height); pixels[i] = darkBlue; } // Draw picture on sketch else if (total < 364) { image(img, 0, 0); pixels[i] = reddish; } else if (total < 546) { pixels[i] = lightBlue; } else { pixels[i] = yellow; } } updatePixels(); } obamicon.pde Histogram Equalization Shift to the right implies brighter reds • Increase the global contrast of images • So that intensities are better distributed • Reveal more details in photos that are over or under exposed • Better views of bone structure in X-rays histogram.pde 1
3/29/2012 Histogram Equalization • Calculate color frequencies - count the number of times each pixel color appear in the image • Calculate the cumulative distribution function (cdf) for each pixel color – the number of times all smaller color values appear in the image • Normalize over (0, 255) Spatial Filtering (aka Area-Based Filters) Spatial Filtering (aka Area-Based Filters) Input Image Output Image w 1 w 2 w 3 A B C w 4 w 5 w 6 D E F E' w 7 w 8 w 7 G H I Spatial Filter Kernel Sharpen Edge Gaussian Detection Blur E' = w 1 A+w 2 B+w 3 C+w 4 D+w 5 E+w 6 F+w 7 G+w 8 H+w 7 I spatial.pde Spatial Kernel Filters - Identity Average – smooth • No change • Set pixel to the average of all colors in the neighborhood 0 0 0 • Smoothes out areas of sharp changes. 0 1 0 1/9 1/9 1/9 0 0 0 1/9 1/9 1/9 1/9 1/9 1/9 2
3/29/2012 Blur – Low Pass Filter Sharpen – High Pass Filter • Softens significant color changes in image • Enhances the difference between neighboring pixels • Creates intermediate colors • The greater the difference, the more change in the current pixel 1/16 2/16 1/16 -1 -1 -1 0 -2/3 0 2/16 4/16 2/16 -1 9 -1 -2/3 11/3 -2/3 1/16 2/16 4/16 -1 -1 -1 0 -2/3 0 // Spatial Filtering void draw() { // Perform spatial filtering on one pixel location PImage img; // Draw the image on the background color spatialFilter(int x, int y, float[][] matrix, Dilation - Morphology PImage filt; image(img,0,0); int msize, PImage img) { int w = 100; float rtotal = 0.0; int msize = 3; // Get current filter rectangle location float gtotal = 0.0; int xstart = float btotal = 0.0; // Sharpen • Set pixel to the maximum color value within a constrain(mouseX-w/2,0,img.width); int offset = msize/2; float[][] matrix = {{ -1., -1., -1.}, int ystart = { -1., 9., -1.}, constrain(mouseY-w/2,0,img.height); // Loop through filter matrix 3x3 window around the pixel { -1., -1., -1.}}; for (int i=0; i<msize; i++) { // Filter rectangle for (int j=0; j<msize; j++) { // Laplacian Edge Detection loadPixels(); • Causes objects to grow in size. //float[][] matrix = {{ 0., 1., 0. }, filt.loadPixels(); // What pixel are we testing // { 1., -4., 1. }, int xloc = x+i-offset; // { 0., 1., 0. }}; for (int i=0; i<w; i++ ) { int yloc = y+j-offset; • Brightens and fills in small holes for (int j=0; j<w; j++) { int loc = xloc + img.width*yloc; // Average int x = xstart + i; //float[][] matrix = {{ 1./9., 1./9., 1./9.}, int y = ystart + j; // Make sure we haven't walked off // { 1./9., 1./9., 1./9.}, color c = // the edge of the pixel array // { 1./9., 1./9., 1./9.}}; spatialFilter(x, y, matrix, msize, img); loc = constrain(loc,0,img.pixels.length-1); int loc = i+j*w; // Gaussian Blur filt.pixels[loc] = c; // Calculate the filter //float[][] matrix = {{ 1./16., 2./16., 1./16. }, } rtotal += (red(img.pixels[loc]) * matrix[i][j]); // { 2./16., 4./16., 2./16. }, } gtotal += (green(img.pixels[loc]) * matrix[i][j]); // { 1./16., 2./16., 1./16. }}; btotal+= (blue(img.pixels[loc]) * matrix[i][j]); filt.updatePixels(); } void setup() { updatePixels(); } //img = loadImage("bmc3.jpg"); // Make sure RGB is within range img = loadImage("moon.jpg"); // Add rectangle around convolved region rtotal = constrain(rtotal,0,255); size( img.width, img.height ); stroke(0); gtotal= constrain(gtotal,0,255); filt = createImage(w, w, RGB); noFill(); btotal= constrain(btotal,0,255); } image(filt, xstart, ystart); rect(xstart, ystart, w, w); // return resulting color } return color(rtotal, gtotal, btotal); } Erode + Dilate to Despeckle Erosion - Morphology • Set pixel to the minimum color value within a 3x3 window around the pixel • Causes objects to shrink. • Darkens and removes small objects Erode Dilate erodedilate.pde 3
3/29/2012 Feature Extraction Image Processing in Processing - Region detection – morphology manipulation - Dilate and Erode tint() modulate individual color components blend() combine the pixels of two images in a given manner filter() apply an image processing algorithm to an image - Open - Erode � Dilate - Small objects are removed - Close - Dilate � Erode - Holes are closed - Skeleton and perimeter Kun Huang, Ohio State / Digital Image Processing using Matlab, By R.C.Gonzalez, R.E.Woods, and S.L.Eddins blend() filter() Draw an image and img = loadImage("colony.jpg"); then blend with Draw an image and mask = loadImage("mask.png"); PImage b; another image then apply a filter b = loadImage("myImage.jpg"); image(img, 0, 0); blend(mask, 0, 0, mask.width, mask.height, image(b, 0, 0); filter(THRESHOLD, 0.5); 0, 0, img.width, img.height, SUBTRACT); THRESHOLD converts the image to black and white pixels depending if they are above or below the BLEND linear interpolation of colours: C = A*factor + B threshold defined by the level parameter. The level must be between 0.0 (black) and ADD additive blending with white clip: C = min(A*factor + B, 255) 1.0 (white). If no level is specified, 0.5 is used. SUBTRACT subtractive blending with black clip: C = max(B - A*factor, 0) GRAY converts any colors in the image to grayscale equivalents DARKEST only the darkest colour succeeds: C = min(A*factor, B) LIGHTEST only the lightest colour succeeds: C = max(A*factor, B) INVERT sets each pixel to its inverse value DIFFERENCE subtract colors from underlying image. POSTERIZE limits each channel of the image to the number of colors specified as the level EXCLUSION similar to DIFFERENCE, but less extreme. parameter MULTIPLY Multiply the colors, result will always be darker. BLUR executes a Gaussian blur with the level parameter specifying the extent of the blurring. SCREEN Opposite multiply, uses inverse values of the colors. If no level parameter is used, the blur is equivalent to Gaussian blur of radius 1. OVERLAY A mix of MULTIPLY and SCREEN. Multiplies dark values, and screens light values. OPAQUE sets the alpha channel to entirely opaque. HARD_LIGHT SCREEN when greater than 50% gray, MULTIPLY when lower. ERODE reduces the light areas with the amount defined by the level parameter. SOFT_LIGHT Mix of DARKEST and LIGHTEST. Works like OVERLAY, but not as harsh. DODGE Lightens light tones and increases contrast, ignores darks. DILATE increases the light areas with the amount defined by the level parameter. BURN Darker areas are applied, increasing contrast, ignores lights. // Posterize // Threshold PImage img; PImage img; void setup() { void setup() { img = loadImage("andy-warhol2.jpg"); img = loadImage("kodim01.png"); size(img.width, img.height); size(img.width, img.height); image(img, 0, 0); image(img, 0, 0); } } void draw() {} void draw() {} void drawImg(float val { void drawImg(float thresh) { image(img, 0, 0); image(img, 0, 0); filter(POSTERIZE, val); filter(THRESHOLD, thresh); } } void mouseDragged() { void mouseDragged() { float val = int(map(mouseY, 0, height, 2, 10)); float thresh = map(mouseY, 0, height, 0.0, 1.0); val = constrain(val, 2, 10); println(thresh); println(val); drawImg(thresh); drawImg(val); } } threshold.pde posterize.pde 4
Recommend
More recommend