KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > instruments > PTTwoDBarycentreCross


1 package JSci.instruments;
2
3 import java.awt.*;
4 import java.awt.geom.*;
5 import java.util.*;
6
7 public class PTTwoDBarycentreCross {
8
9     /** threshold for defininf the light and dark regions; 0<ALPHA<1 (ALPHA approx 0.3) */
10     public static double ALPHA = 0.3;
11     /** the weight of the light region vs. the dark region (%) */
12     public static int WEIGHT_LIGHT_PART = 50;
13     /** the speed of movement of the region; 0 = the region doesn't move; 1 = the region follows the bead */
14     public static double REGION_SPEED = 0.2;
15     /** the meaning of fields in interlaced images; 1 for odd/even, 0 for odd-only fields */
16     public static int ODD_EVEN = 1;
17     
18     private Rectangle region;
19     private double x;
20     private double y;
21     private double x2;
22     private double y2;
23     private double ox; // original position with respect to the upper left corner of the region
24
private double oy;
25     private double cx; // floating point position of the upper left corner of the region
26
private double cy;
27     private boolean firstTime = true;
28
29     private static int currNum = 0;
30     private int num;
31
32     /** @param r the initial region where to look for the bead */
33     public PTTwoDBarycentreCross(Rectangle r) {
34     region = (Rectangle)r.clone();
35     cx=region.x;
36     cy=region.y;
37     num=currNum++;
38     }
39     
40
41
42
43
44
45     /////////////////////////////////////////////////////////////////////////////////
46
// TRACKING EX-NATIVO
47

48     private int fromImg(byte c) { if (c>=0) return (int)c; else return (int)(256+c); }
49
50     private void contiguous(Hashtable h,Point p) {
51     HashSet candidati=new HashSet(),effettivi=new HashSet();
52     candidati.add(p);
53     while (!candidati.isEmpty()) {
54         p=(Point)candidati.iterator().next();
55         candidati.remove(p);
56         if (h.containsKey(p) && ! effettivi.contains(p)) {
57         effettivi.add(p);
58         candidati.add(new Point(p.x+1,p.y));
59         candidati.add(new Point(p.x-1,p.y));
60         candidati.add(new Point(p.x,p.y+1));
61         candidati.add(new Point(p.x,p.y-1));
62         }
63     }
64     for (Enumeration e=h.keys();e.hasMoreElements();) {
65         p=(Point)e.nextElement();
66         if (!effettivi.contains(p)) h.remove(p);
67     }
68     }
69
70     /*
71       Parameters:
72       im : the image
73       start : the index of the first pixel of the ROI
74       width : the width of the ROI
75       height : the height of the ROI
76       linestride : the line width of the whole image
77       alpha : the factor for defining the tresholds
78       weight : the weight of the light region vs. the dark region (%)
79       x[0],x[1] : the resulting position
80     */

81
82     private void PTTwoDBarycentreFindNative(
83          byte []im,
84          int start,int width,int height,int linestride,
85          double alpha,
86          int weight,
87          double []x
88          ) {
89     /* posizione e valore degli estremi */
90     int maxj,maxk,minj,mink;
91     int maxv,minv;
92     /* tagli superiore e inferiore */
93     int inf,sup;
94     /* coordinate */
95     int j,k,p,q;
96     /* somme */
97     long s,sx,sy;
98     /* valori finali x,y ligth/dark */
99     double xl,yl,xd,yd;
100     /* utili */
101     int abv;
102     /* elenco pixel interessati */
103     Hashtable dark = new Hashtable(),light = new Hashtable();
104
105     /* minimo, massimo, media */
106         maxj=minj=maxk=mink=0;
107     maxv=minv=fromImg(im[start]);s=0;
108     abv=linestride-width;
109     for (k=0,p=start;k<height;k++,p+=abv) for (j=0;j<width;j++,p++) {
110         if (fromImg(im[p])>maxv) {maxv=fromImg(im[p]);maxj=j;maxk=k;}
111         if (fromImg(im[p])<minv) {minv=fromImg(im[p]);minj=j;mink=k;}
112         s+=fromImg(im[p]);
113     }
114     s/=width*height;
115     
116     /* superiore e inferiore per tagliare l'immagine */
117     sup=(int)((1.0-alpha)*s+alpha*maxv);
118     inf=(int)((1.0-alpha)*s+alpha*minv);
119
120     /* zone di interesse */
121     for (k=0,p=start;k<height;k++,p+=abv) for (j=0;j<width;j++,p++) {
122         if (fromImg(im[p])>sup) light.put(new Point(j,k),new Integer JavaDoc(fromImg(im[p])));
123         if (fromImg(im[p])<inf) dark.put(new Point(j,k),new Integer JavaDoc(fromImg(im[p])));
124     }
125     
126     /* cerca zone contigue */
127     contiguous(light,new Point(maxj,maxk));
128     contiguous(dark,new Point(minj,mink));
129
130     /* media nella parte superiore */
131     if (weight!=0) {
132         sx=sy=s=0;
133         Point pt;int v;
134         for (Enumeration e = light.keys();e.hasMoreElements();) {
135         pt=(Point)e.nextElement();
136         v=((Integer JavaDoc)(light.get(pt))).intValue();
137         sx+=(v-sup)*pt.x;
138         sy+=(v-sup)*pt.y;
139         s+=v-sup;
140         }
141         xl=(double)sx/s;
142         yl=(double)sy/s;
143     }
144     else { xl=yl=0.0; }
145
146     /* media nella parte inferiore */
147     if (weight!=100) {
148         sx=sy=s=0;
149         Point pt;int v;
150         for (Enumeration e = dark.keys();e.hasMoreElements();) {
151         pt=(Point)e.nextElement();
152         v=((Integer JavaDoc)(dark.get(pt))).intValue();
153         sx+=(inf-v)*pt.x;
154         sy+=(inf-v)*pt.y;
155         s+=inf-v;
156         }
157         xd=(double)sx/s;
158         yd=(double)sy/s;
159     }
160     else { xd=yd=0.0; }
161     
162     /* risultati */
163     x[0]=(xl*weight+xd*(100-weight))/100;
164     x[1]=(yl*weight+yd*(100-weight))/100;
165
166     }
167
168
169     // FINE TRACKING EX-NATIVO
170
////////////////////////////////////////////////////////////////////////////////
171

172
173
174     /** ask the cross to find the bead. For non-interlaced images. */
175     public void find(Image i) {
176     // find the bead
177
double[] rp = new double[2];
178     PTTwoDBarycentreFindNative(
179                 i.getData(),
180                 region.x+region.y*i.getScansize()+i.getOffset(),region.width,region.height,i.getScansize(),
181                 ALPHA,
182                 WEIGHT_LIGHT_PART,
183                 rp);
184     double dx = rp[0];
185     double dy = rp[1];
186     if (Double.isNaN(dx) || Double.isNaN(dy)) return;
187     x = region.x+dx;
188     y = region.y+dy;
189     // move the region
190
if (firstTime) {
191         ox=dx;
192         oy=dy;
193         cx=region.x;
194         cy=region.y;
195         firstTime=false;
196     }
197     cx+=(dx-ox)*REGION_SPEED;
198     cy+=(dy-oy)*REGION_SPEED;
199     if (cx<0) cx=0;
200     if (cx+region.width>=i.getWidth()) cx=i.getWidth()-1;
201     if (cy<0) cy=0;
202     if (cy+region.height>=i.getHeight()) cy=i.getHeight()-1;
203     region.setLocation((int)cx,(int)cy);
204     // add overlays
205
i.addOverlay(new Overlay() {
206         public void paint(Graphics g) {
207             Graphics2D g2 = (Graphics2D)g;
208             g2.setColor(Color.RED);
209             g2.draw(new Line2D.Double(x,y-3,x,y+3));
210             g2.draw(new Line2D.Double(x-3,y,x+3,y));
211             g2.setColor(Color.MAGENTA);
212             g2.draw(region);
213             g2.drawString(PTTwoDBarycentreCross.this.toString(),region.x,region.y+region.height+12);
214         }
215         });
216     }
217
218
219     /** ask the cross to find the bead. For interlaced images; generates also x2 and y2 coords. */
220     public void findInterlaced(Image i) {
221     // find the bead - first field
222
double[] rp = new double[2];
223     PTTwoDBarycentreFindNative(
224                 i.getData(),
225                 region.x+region.y*i.getScansize()+i.getOffset(),region.width,region.height/2,i.getScansize()*2,
226                 ALPHA,
227                 WEIGHT_LIGHT_PART,
228                 rp);
229     double dx = rp[0];
230     double dy = rp[1]*2;
231     if (Double.isNaN(dx) || Double.isNaN(dy)) return;
232     x = region.x+dx;
233     y = region.y+dy;
234     // find the bead - second field
235
PTTwoDBarycentreFindNative(
236                 i.getData(),
237                 region.x+(region.y+1)*i.getScansize()+i.getOffset(),region.width,region.height/2,i.getScansize()*2,
238                 ALPHA,
239                 WEIGHT_LIGHT_PART,
240                 rp);
241     double dx2 = rp[0];
242     double dy2 = rp[1]*2+ODD_EVEN;
243     if (Double.isNaN(dx2) || Double.isNaN(dy2)) return;
244     x2 = region.x+dx2;
245     y2 = region.y+dy2;
246     // move the region
247
dx=(dx+dx2)/2;
248     dy=(dy+dy2)/2;
249     if (firstTime) {
250         ox=dx;
251         oy=dy;
252         cx=region.x;
253         cy=region.y;
254         firstTime=false;
255     }
256     cx+=(dx-ox)*REGION_SPEED;
257     cy+=(dy-oy)*REGION_SPEED;
258     if (cx<0) cx=0;
259     if (cx+region.width>=i.getWidth()) cx=i.getWidth()-1;
260     if (cy<0) cy=0;
261     if (cy+region.height>=i.getHeight()) cy=i.getHeight()-1;
262     region.setLocation((int)cx,(int)cy);
263     // add overlays
264
i.addOverlay(new Overlay() {
265         public void paint(Graphics g) {
266             Graphics2D g2 = (Graphics2D)g;
267             g2.setColor(Color.RED);
268             g2.draw(new Line2D.Double(x,y-3,x,y+3));
269             g2.draw(new Line2D.Double(x-3,y,x+3,y));
270             g2.setColor(Color.MAGENTA);
271             g2.draw(region);
272             g2.drawString(PTTwoDBarycentreCross.this.toString(),region.x,region.y+region.height+12);
273         }
274         });
275     }
276
277     /** @return the number of the cross; increases for each instance is created */
278     public String JavaDoc toString() { return ""+num; }
279
280     /** @return the number of the bead */
281     public int getN() { return num; }
282     /** @return the x position of the bead */
283     public double getX() { return x; }
284     /** @return the y position of the bead */
285     public double getY() { return y; }
286     /** @return the x position of the bead, in the second field, only for interlaced images */
287     public double getX2() { return x2; }
288     /** @return the y position of the bead, in the second field, only for interlaced images */
289     public double getY2() { return y2; }
290
291 }
292
Popular Tags