001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.image; 018 019import java.awt.*; 020import java.awt.image.*; 021 022/** 023 * An edge-detection filter. 024 */ 025public class EdgeFilter extends WholeImageFilter { 026 027 public final static float R2 = (float)Math.sqrt(2); 028 029 public final static float[] ROBERTS_V = { 030 0, 0, -1, 031 0, 1, 0, 032 0, 0, 0, 033 }; 034 public final static float[] ROBERTS_H = { 035 -1, 0, 0, 036 0, 1, 0, 037 0, 0, 0, 038 }; 039 public final static float[] PREWITT_V = { 040 -1, 0, 1, 041 -1, 0, 1, 042 -1, 0, 1, 043 }; 044 public final static float[] PREWITT_H = { 045 -1, -1, -1, 046 0, 0, 0, 047 1, 1, 1, 048 }; 049 public final static float[] SOBEL_V = { 050 -1, 0, 1, 051 -2, 0, 2, 052 -1, 0, 1, 053 }; 054 public static float[] SOBEL_H = { 055 -1, -2, -1, 056 0, 0, 0, 057 1, 2, 1, 058 }; 059 public final static float[] FREI_CHEN_V = { 060 -1, 0, 1, 061 -R2, 0, R2, 062 -1, 0, 1, 063 }; 064 public static float[] FREI_CHEN_H = { 065 -1, -R2, -1, 066 0, 0, 0, 067 1, R2, 1, 068 }; 069 070 protected float[] vEdgeMatrix = SOBEL_V; 071 protected float[] hEdgeMatrix = SOBEL_H; 072 073 public EdgeFilter() { 074 } 075 076 public void setVEdgeMatrix(float[] vEdgeMatrix) { 077 this.vEdgeMatrix = vEdgeMatrix; 078 } 079 080 public float[] getVEdgeMatrix() { 081 return vEdgeMatrix; 082 } 083 084 public void setHEdgeMatrix(float[] hEdgeMatrix) { 085 this.hEdgeMatrix = hEdgeMatrix; 086 } 087 088 public float[] getHEdgeMatrix() { 089 return hEdgeMatrix; 090 } 091 092 protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { 093 int index = 0; 094 int[] outPixels = new int[width * height]; 095 096 for (int y = 0; y < height; y++) { 097 for (int x = 0; x < width; x++) { 098 int r = 0, g = 0, b = 0; 099 int rh = 0, gh = 0, bh = 0; 100 int rv = 0, gv = 0, bv = 0; 101 int a = inPixels[y*width+x] & 0xff000000; 102 103 for (int row = -1; row <= 1; row++) { 104 int iy = y+row; 105 int ioffset; 106 if (0 <= iy && iy < height) 107 ioffset = iy*width; 108 else 109 ioffset = y*width; 110 int moffset = 3*(row+1)+1; 111 for (int col = -1; col <= 1; col++) { 112 int ix = x+col; 113 if (!(0 <= ix && ix < width)) 114 ix = x; 115 int rgb = inPixels[ioffset+ix]; 116 float h = hEdgeMatrix[moffset+col]; 117 float v = vEdgeMatrix[moffset+col]; 118 119 r = (rgb & 0xff0000) >> 16; 120 g = (rgb & 0x00ff00) >> 8; 121 b = rgb & 0x0000ff; 122 rh += (int)(h * r); 123 gh += (int)(h * g); 124 bh += (int)(h * b); 125 rv += (int)(v * r); 126 gv += (int)(v * g); 127 bv += (int)(v * b); 128 } 129 } 130 r = (int)(Math.sqrt(rh*rh + rv*rv) / 1.8); 131 g = (int)(Math.sqrt(gh*gh + gv*gv) / 1.8); 132 b = (int)(Math.sqrt(bh*bh + bv*bv) / 1.8); 133 r = PixelUtils.clamp(r); 134 g = PixelUtils.clamp(g); 135 b = PixelUtils.clamp(b); 136 outPixels[index++] = a | (r << 16) | (g << 8) | b; 137 } 138 139 } 140 return outPixels; 141 } 142 143 public String toString() { 144 return "Edges/Detect Edges"; 145 } 146}