001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit http://imagingbook.com for additional details. 008 *******************************************************************************/ 009 010package imagingbook.lib.filters; 011 012import imagingbook.lib.image.ImageAccessor; 013 014 015/** 016 * Generic linear convolution filter implemented 017 * by extending the GenericFilter class. 018 */ 019public class LinearFilter extends GenericFilter { 020 021 private final float[][] kernel2d; 022 private final float[] rgb = { 0, 0, 0 }; 023 024 private final int kernelWidth, kernelHeight; // width/height of the kernel 025 private final int kernelCtrX, kernelCtrY; // center coordinates of the kernel 026 027 public LinearFilter(float[][] kernel2d) { 028 this.kernel2d = kernel2d; 029 this.kernelWidth = kernel2d.length; 030 this.kernelHeight = kernel2d[0].length; 031 this.kernelCtrX = kernelWidth / 2; 032 this.kernelCtrY = kernelHeight / 2; 033 } 034 035 // -------------------------------------------------------------- 036 037 038 public float filterPixel(ImageAccessor.Scalar ia, int u, int v) { 039 float sum = 0; 040 for (int j = 0; j < kernelHeight; j++) { 041 int vj = v + j - kernelCtrY; 042 for (int i = 0; i < kernelWidth; i++) { 043 int ui = u + i - kernelCtrX; 044 sum = sum + ia.getVal(ui, vj) * kernel2d[i][j]; 045 } 046 } 047 return sum; 048 } 049 050 public float[] filterPixel(ImageAccessor.Rgb ia, int u, int v) { 051 float sumR = 0; // sum of weighted red 052 float sumG = 0; // sum of weighted green 053 float sumB = 0; // sum of weighted blue 054 for (int j = 0; j < kernelHeight; j++) { 055 int vj = v + j - kernelCtrY; 056 for (int i = 0; i < kernelWidth; i++) { 057 int ui = u + i - kernelCtrX; 058 float[] val = ia.getPix(ui, vj); 059 float w = kernel2d[i][j]; 060 sumR = sumR + val[0] * w; 061 sumG = sumG + val[1] * w; 062 sumB = sumB + val[2] * w; 063 } 064 } 065 rgb[0] = sumR; 066 rgb[1] = sumG; 067 rgb[2] = sumB; 068 return rgb; 069 } 070 071 // -------------------------------------------------------------- 072 073// @Deprecated // return a string instead 074// public void listKernel() { 075// for (int j = 0; j < kernelHeight; j++) { 076// StringBuilder sb = new StringBuilder(); 077// Formatter fm = new Formatter(sb, Locale.US); 078// for (int i = 0; i < kernelWidth; i++) { 079// fm.format(" %.5f | ", kernel2d[i][j]); 080// } 081// fm.format("\n"); 082// IJ.log(fm.toString()); 083// fm.close(); 084// } 085// } 086}