root / trunk / libraries / libCq_CMS_praster / src / org / cresques / filter / convolution / ConvolutionShortFilter.java @ 8026
History | View | Annotate | Download (7.53 KB)
1 | 8026 | nacho | /* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
---|---|---|---|
2 | *
|
||
3 | * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
||
4 | *
|
||
5 | * This program is free software; you can redistribute it and/or
|
||
6 | * modify it under the terms of the GNU General Public License
|
||
7 | * as published by the Free Software Foundation; either version 2
|
||
8 | * of the License, or (at your option) any later version.
|
||
9 | *
|
||
10 | * This program is distributed in the hope that it will be useful,
|
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
13 | * GNU General Public License for more details.
|
||
14 | *
|
||
15 | * You should have received a copy of the GNU General Public License
|
||
16 | * along with this program; if not, write to the Free Software
|
||
17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
18 | */
|
||
19 | |||
20 | package org.cresques.filter.convolution; |
||
21 | |||
22 | import org.cresques.filter.RasterFilter; |
||
23 | import org.cresques.io.data.RasterBuf; |
||
24 | |||
25 | /**
|
||
26 | * Filtro de Convoluci?n que se aplica a un RasterBuf de tipo Short.
|
||
27 | * Toma como entrada la imagen, el kernel en que se base la convoluci?n
|
||
28 | * y el umbral (cero para no umbralizar).
|
||
29 | *
|
||
30 | * @author Diego Guerrero Sevilla <diego.guerrero@uclm.es>
|
||
31 | *
|
||
32 | */
|
||
33 | public class ConvolutionShortFilter extends ConvolutionFilter { |
||
34 | |||
35 | /**
|
||
36 | * Constructor sin par?metros. Este es usado principalmente desde controlTypes
|
||
37 | * ya que se instancia con newInstance y sin par?metros. Poseriormente le aplica
|
||
38 | * el nombre al filtro con la funci?n setFilterName de RasterFilter.
|
||
39 | */
|
||
40 | public ConvolutionShortFilter() {}
|
||
41 | |||
42 | /**
|
||
43 | * Constructor para la asignaci?n del identificador del filtro
|
||
44 | * @param fName Cadena que representa el identificador del filtro
|
||
45 | */
|
||
46 | public ConvolutionShortFilter(String fName) { |
||
47 | super(fName);
|
||
48 | } |
||
49 | |||
50 | public int getInRasterDataType() { |
||
51 | return RasterBuf.TYPE_SHORT;
|
||
52 | } |
||
53 | |||
54 | public int getOutRasterDataType() { |
||
55 | return RasterBuf.TYPE_SHORT;
|
||
56 | } |
||
57 | |||
58 | public Object getResult(String name) { |
||
59 | if (name.equals("raster")) { |
||
60 | return (Object) this.rasterResult; |
||
61 | } else {
|
||
62 | return null; |
||
63 | } |
||
64 | } |
||
65 | |||
66 | public void pre() { |
||
67 | exec = true;
|
||
68 | this.raster = (RasterBuf)params.get("raster"); |
||
69 | height = raster.getHeight(); |
||
70 | width = raster.getWidth(); |
||
71 | rasterResult = new RasterBuf(raster.getDataType(),width,height,raster.getBandCount(),true); |
||
72 | |||
73 | super.pre();
|
||
74 | } |
||
75 | |||
76 | public void process(int col, int line) { |
||
77 | short[] pxOut = new short[4]; |
||
78 | short[] px = new short[4]; |
||
79 | int ladoVentana = kernel.getLado();
|
||
80 | int semiLado = (ladoVentana-1)>>1; |
||
81 | |||
82 | double ventanaR[][]=new double[ladoVentana][ladoVentana]; |
||
83 | double ventanaG[][]=new double[ladoVentana][ladoVentana]; |
||
84 | double ventanaB[][]=new double[ladoVentana][ladoVentana]; |
||
85 | |||
86 | Kernel kernelRGB[]=new Kernel[3]; |
||
87 | |||
88 | raster.getElemShort(line, col, px); |
||
89 | |||
90 | if((col-semiLado >= 0) && (line-semiLado >= 0) &&(col+semiLado < width)&&(line+semiLado < height)) |
||
91 | { |
||
92 | // Obtener el vector con la ventanas de muestras (una por componente RGB)
|
||
93 | for (int i=-semiLado;i<=semiLado;i++) |
||
94 | for(int j=-semiLado;j<=semiLado;j++) |
||
95 | { |
||
96 | raster.getElemShort(line+j, col+i,px); |
||
97 | ventanaR[i+semiLado][j+semiLado] =px[0];
|
||
98 | ventanaG[i+semiLado][j+semiLado] =px[1];
|
||
99 | ventanaB[i+semiLado][j+semiLado] =px[2];
|
||
100 | } |
||
101 | kernelRGB[0]=new Kernel(ventanaR); |
||
102 | kernelRGB[1]=new Kernel(ventanaG); |
||
103 | kernelRGB[2]=new Kernel(ventanaB); |
||
104 | |||
105 | pxOut[0]= (short)kernel.convolution(kernelRGB[0]); |
||
106 | pxOut[1]= (short)kernel.convolution(kernelRGB[1]); |
||
107 | pxOut[2]= (short)kernel.convolution(kernelRGB[2]); |
||
108 | |||
109 | if (umbral>0){ |
||
110 | if(pxOut[0]>=umbral)pxOut[0]=255; |
||
111 | else pxOut[0]=0; |
||
112 | if(pxOut[1]>=umbral)pxOut[1]=255; |
||
113 | else pxOut[1]=0; |
||
114 | if(pxOut[2]>=umbral)pxOut[2]=255; |
||
115 | else pxOut[2]=0; |
||
116 | } |
||
117 | else{
|
||
118 | if (pxOut[0]<0) pxOut[0]=0; |
||
119 | else if (pxOut[0]>255) pxOut[0]=255; |
||
120 | if (pxOut[1]<0) pxOut[1]=0; |
||
121 | else if (pxOut[1]>255) pxOut[1]=255; |
||
122 | if (pxOut[2]<0) pxOut[2]=0; |
||
123 | else if (pxOut[2]>255) pxOut[2]=255; |
||
124 | } |
||
125 | |||
126 | rasterResult.setElemShort(line, col,pxOut); |
||
127 | } |
||
128 | else rasterResult.setElemShort(line, col,pxOut);
|
||
129 | |||
130 | } |
||
131 | |||
132 | |||
133 | public void processSuperSampling(int col, int line) { |
||
134 | short[] px = new short[4]; |
||
135 | short[] pxOut = new short[4]; |
||
136 | int ladoVentana = kernel.getLado();
|
||
137 | RasterFilter.Kernel kernelRGB[];
|
||
138 | |||
139 | raster.getElemShort(line, col,px); |
||
140 | |||
141 | // Obtener el vector con la ventanas de muestras (una por componente RGB)
|
||
142 | kernelRGB=extractSubRaster(ladoVentana,col,line); |
||
143 | if(kernelRGB!=null) |
||
144 | { |
||
145 | pxOut[0]= (short)kernel.convolution(kernelRGB[0]); |
||
146 | pxOut[1]= (short)kernel.convolution(kernelRGB[1]); |
||
147 | pxOut[2]= (short)kernel.convolution(kernelRGB[2]); |
||
148 | |||
149 | if (umbral>0){ |
||
150 | if(pxOut[0]>=umbral)pxOut[0]=255; |
||
151 | else pxOut[0]=0; |
||
152 | if(pxOut[1]>=umbral)pxOut[1]=255; |
||
153 | else pxOut[1]=0; |
||
154 | if(pxOut[2]>=umbral)pxOut[2]=255; |
||
155 | else pxOut[2]=0; |
||
156 | } |
||
157 | else{
|
||
158 | if (pxOut[0]<0) pxOut[0]=0; |
||
159 | else if (pxOut[0]>255) pxOut[0]=255; |
||
160 | if (pxOut[1]<0) pxOut[1]=0; |
||
161 | else if (pxOut[1]>255) pxOut[1]=255; |
||
162 | if (pxOut[2]<0) pxOut[2]=0; |
||
163 | else if (pxOut[2]>255) pxOut[2]=255; |
||
164 | } |
||
165 | |||
166 | for(int i = col; i < width && i < (col + stepX[contX + 1]); i++) |
||
167 | for(int j = line; j < height && j < (line + stepY[contY + 1]); j++) |
||
168 | rasterResult.setElemShort(j, i,pxOut); |
||
169 | } |
||
170 | else
|
||
171 | for(int i = col; i < rasterResult.getWidth() && i < (col + stepX[contX + 1]); i++) |
||
172 | for(int j = line; j < rasterResult.getHeight() && j < (line + stepY[contY + 1]); j++) |
||
173 | rasterResult.setElemShort(j, i,px); |
||
174 | } |
||
175 | |||
176 | public void processLine(int y) { |
||
177 | // TODO Auto-generated method stub
|
||
178 | |||
179 | } |
||
180 | |||
181 | /**
|
||
182 | * @param ladoVentana Lado del subraster a extraer
|
||
183 | * @param x Coordenada x del pixel central
|
||
184 | * @param y Coordenada y del pixel central
|
||
185 | * @return
|
||
186 | */
|
||
187 | public Kernel[] extractSubRaster(int ladoVentana,int x,int y){ |
||
188 | |||
189 | int k,indiceX,indiceY,origenX,origenY;
|
||
190 | short[] px = new short[4]; |
||
191 | int semiLado = (ladoVentana-1)>>1; |
||
192 | int offsetX=0; |
||
193 | int offsetY=0; |
||
194 | |||
195 | Kernel kernelRGB[] = null; |
||
196 | |||
197 | // Obtener el vector con las ventanas de muestras (una por componente RGB) **************************
|
||
198 | // Me situo en la esquina superior izquierda del "kernel"
|
||
199 | if ((contX+1-semiLado>=0) && (contY+1-semiLado>=0)&& (contX+1+semiLado<stepX.length) && (contY+1+semiLado<stepY.length)){ |
||
200 | |||
201 | // Calcular el alcance del kernel cuyo centro es (x,y)
|
||
202 | for (int i=0;i<semiLado;i++){ |
||
203 | offsetX=offsetX+stepX[contX+i+1];
|
||
204 | offsetY=offsetY+stepY[contY+i+1];
|
||
205 | } |
||
206 | if((x+offsetX<width)&&(y+offsetY<height)){
|
||
207 | |||
208 | double ventanaR[][] = new double[ladoVentana][ladoVentana]; |
||
209 | double ventanaG[][] = new double[ladoVentana][ladoVentana]; |
||
210 | double ventanaB[][] = new double[ladoVentana][ladoVentana]; |
||
211 | kernelRGB = new Kernel[3]; |
||
212 | |||
213 | origenX=x; |
||
214 | origenY=y; |
||
215 | for (int i=0;i<semiLado;i++){ |
||
216 | origenX=origenX-stepX[contX-i]; |
||
217 | origenY=origenY-stepY[contY-i]; |
||
218 | } |
||
219 | //Recorro el kernel seg?n los step
|
||
220 | k=0;
|
||
221 | indiceX=origenX; |
||
222 | for (int i=-semiLado;i<=semiLado;i++){ |
||
223 | indiceY=origenY; |
||
224 | for(int j=-semiLado;j<=semiLado;j++){ |
||
225 | raster.getElemShort(indiceY,indiceX,px); |
||
226 | ventanaR[i+semiLado][j+semiLado] =px[0];
|
||
227 | ventanaG[i+semiLado][j+semiLado] =px[1];
|
||
228 | ventanaB[i+semiLado][j+semiLado] =px[2];
|
||
229 | indiceY=indiceY+stepY[contY+j+1];
|
||
230 | k++; |
||
231 | } |
||
232 | indiceX=indiceX+stepX[contX+i+1];
|
||
233 | } |
||
234 | //**************************************************************************************************
|
||
235 | kernelRGB[0]= new Kernel(ventanaR); |
||
236 | kernelRGB[1]= new Kernel(ventanaG); |
||
237 | kernelRGB[2]= new Kernel(ventanaB); |
||
238 | } |
||
239 | } |
||
240 | return kernelRGB;
|
||
241 | } |
||
242 | } |