// Listing of client source code

/*
Author: Srikanta Patnaik and Team 
Machine Intelligence Laboratory, University College of Engineering, Burla, India
Date of Writing: April, 2003; Version: 1.0
Book: Robot Cognition and Navigation: An Experiment with Mobile Robots
Publisher: Springer
ISBN: 978-3-540-23446-3
URL: http://www.springer.com/3-540-23446-2
*/


This consists of three files: Predictor.java, ColCamera.jav, EdgeMap.jav 

(a) Predictor.jav
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.image.*;
import java.util.*;
import javax.imageio.*;
import java.awt.geom.*;

class MyLine
{
Point p1,p2;
double slope;
public MyLine(Point p1,Point p2)
{
this.p1 = p1;
this.p2 = p2;
}
public double getSlope()
{
slope = Math.toDegrees(Math.atan2((p2.getY()-p1.getY()),(p2.getX()-p1.getX())));
if(slope<0)slope = 360+slope;
return slope;
}
};

public class Predictor extends Frame implements Runnable
{
Image img;
Vector curve,list,nc,start,end;
Point sr,ds;
int pixles[],no;
Point arr[];
int width,height;
public Predictor(int w,int h,int pix[])
{
width = w;height = h;
arr = new Point[w*h];
no=0;
for(int i=0;i<w*h;i++)
{
if((pix[i]&255)>0)
{
arr[no] = new Point(i%w,i/w);
no++;
}
}
if(no>0)
curve = sortOut();
list = new Vector();
nc = new Vector();
sr = new Point();
ds = new Point();
start = new Vector();
end = new Vector();
setSize(2*w+20,h+55);
setTitle("Curve Recognition");
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
setVisible(false);
dispose();
}
});
img = createImage(new MemoryImageSource(w,h,pix,0,w));
setVisible(true);
 (new Thread(this)).start();
}

public Vector sortOut()
{
double dist=0,mindist=99999999999.9;
int minindex=0;
Point temp1 =new Point();
Point temp2 =new Point();

Vector pointarray = new Vector();
Vector sortedarray = new Vector();
		
for(int i = 0;i<no;i++)
{
pointarray.add(arr[i]);
}
int runs=0;
while(runs<2)
{
runs++;
temp1 = (Point)pointarray.firstElement();
if(runs==1)
{
sortedarray.add(temp1);
}
int k=0;
do
{
mindist=99999999999.9;
for(int i=1;i<no;i++)
{
temp2 = new Point((Point)pointarray.elementAt(i));
dist = temp1.distance(temp2);
if((dist<mindist)&&(sortedarray.indexOf(temp2)==-1))
{
mindist = dist;
minindex = i;
}
}
sortedarray.add(pointarray.get(minindex));
temp1 = (Point)pointarray.get(minindex);
}while(sortedarray.size()<no);
}
for(int i = 0;i<no;i++)
{
arr[i]= new Point((Point)sortedarray.get(i));
}
return sortedarray;

}
public void run()
{
int d;
double delta;
MyLine cur,prev=null;
int i=0;
if(!curve.isEmpty())
{
nc.add(curve.firstElement());
for(int j=0;j<curve.size();j++)
{
sr = (Point) curve.elementAt(i);
ds = (Point) curve.elementAt(j);
d= (int)sr.distance(ds);

if(d>=21&&d<=25)
{
cur = new MyLine(sr,ds);			
i = j;
if(prev!=null)
{		
delta = cur.getSlope() - prev.getSlope();
System.out.println("D:"+delta);
list.add(new Double(delta));
}
prev = cur;
nc.add(ds);
repaint();
}
}
predict(list);
}

}
public void update(Graphics g)
{
g.drawImage(img,0,35,this);
BufferedImage img1 = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2D gd = (Graphics2D)img1.getGraphics();
for(int i = 0;i<nc.size()-1;i++)
{
if(start.contains(new Integer(i)))
gd.setColor(Color.red);
if(end.contains(new Integer(i)))
gd.setColor(Color.blue);
gd.draw(new Line2D.Float((Point)nc.get(i),(Point)nc.get(i+1)));//check
try{Thread.sleep(5);}catch(Exception e){}
g.drawImage(img1,width+10,35,this);
}
}
public void paint(Graphics g)
{
update(g);
}
public void predict(Vector l)
{
double m = mean(l),val=0,prev=m,delta=0;
double tolerance = 5;
int hcount = 0,ncount = 0;
for(int i=0;i<l.size();i++)
{
val = ((Double)((l.get(i)))).doubleValue();
delta = Math.abs(val-prev);
if(delta<=tolerance)
	hcount++;
if(delta>tolerance)
	ncount++;
if(ncount>=1)
{
hcount=0;
if(!end.isEmpty())
end.remove(end.lastElement());
end.add(new Integer(i-ncount+1));
ncount=0;
}
if(hcount>=1)
{
System.out.println("Found Circular Portion");
if(start.contains(new Integer(i-hcount+1)))
{
}
else
start.add(new Integer(i-hcount+1));
}
prev = val;
System.out.println("start:-"+start);
System.out.println("end:-"+end);
}
}
public double mean(Vector l)
{
double sum=0,m=0;
for(int i=0;i<l.size();i++)
{
sum += ((Double)((l.get(i)))).doubleValue();
}
m = sum / l.size();
return m;
}
}

(b) FColCamera.java

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

class Img extends Canvas
{
public Image img;
int sx,sy,dx,dy,ex,ey;
int pixels[];
public Img(int w,int h)
{
//img = i;
sx=sy=dx=dy=ex=ey=0;
pixels = new int[w*h];
setSize(w,h);
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent me)
{
sx = me.getX();
sy = me.getY();
repaint();
System.out.println(sx+","+sy);
}
public void mouseReleased(MouseEvent me)
{
ex = me.getX();
ey = me.getY();
repaint();
System.out.println(ex+","+ey);
}
});
		
addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent me)
{
dx = me.getX();
dy = me.getY();
repaint();
}
});
			
}
public void predict()
{
try
{
int hp = Math.abs(ey-sy+1);
int wp = Math.abs(ex-sx+1);
PixelGrabber pg = new PixelGrabber(img,sx,sy,wp,hp,pixels,0,wp);
	pg.grabPixels();
}catch(Exception e){}
Predictor p = new Predictor(ex-sx+1,ey-sy+1,pixels);
}
public void update(Graphics g)
{
g.drawImage(img,0,0,null);
g.setColor(Color.red);
g.drawRect(sx,sy,dx-sx,dy-sy);
}
public void paint(Graphics g)
{
update(g);
}
};
public class FColCamera extends Frame implements Runnable,ActionListener
{
Image img;
Img cimg,eimg;
MemoryImageSource imsource;
int pixels[];
int h,w;
Socket client;
DataInputStream dis;
DataOutputStream dos;
String input;
StringTokenizer st;
int mx,my;
boolean hold;

public FColCamera()//int ht,int wt)
{
//h = ht; w = wt;
int n;mx=0;my=0;
hold = false;
try{client = new Socket("192.168.0.9",9904);
if(client == null)System.exit(0);
System.out.println("connected");
client.setTcpNoDelay(true);
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
w=320;
h=240;
System.out.println(w+" "+h);
dos.write((new String("recd")).getBytes());
dos.flush();
}catch(Exception e){}
pixels = new int[h*w];
imsource = new MemoryImageSource(w,h,pixels,0,w);
imsource.setAnimated(true);
cimg = new Img(w,h);
eimg = new Img(w,h);
cimg.img = createImage(imsource);
		
setLayout(null);
setSize(2*w+50,h+110);
setTitle("Edge Map Generator");
setVisible(true);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
		
cimg.setBounds(10,35,w,h);
eimg.setBounds(10+w+10,35,w,h);
add(cimg);
add(eimg);
Button bp = new Button("PREDICT");
Button bh = new Button("HOLD");
bp.setBounds(w-100,h+70,70,30);
bh.setBounds(w+30,h+70,70,30);
add(bp);
add(bh);
		
bp.addActionListener(this);
bh.addActionListener(this);

}
public void actionPerformed(ActionEvent e)
{
System.out.println("adfa");
if(e.getActionCommand().equals("PREDICT"))
{
eimg.predict();
System.out.println("desdf");
}
if(e.getActionCommand().equals("HOLD"))
{
if(!hold)hold = true;
else hold = false;
System.out.println("desdf");
}
}
public void run()
{
int n=0;
while(true)
{
int c = 0,r = 0,g = 0,b = 0,kount = 0,x = 0,y=0;
while (true)
{
try
{
r =dis.read();
g =dis.read();
b =dis.read();
c = dis.read();
}catch(Exception e){}
				
if((c==0)&&(r==0)&&(g==0)&&(b==0))
{
break;
}
else
{
{
if(x==(w*h))break;
pixels[x] = (255<<24)|(r<<16)|(g<<8)|b;
x++;
}
}
if((r==-1)||(g==-1)||(b==-1))
break;
}
updateImage();repaint();
}
}
public void updateImage()
{
imsource.newPixels(0,0,w,h);
}
public void update(Graphics g)
{
if(!hold)
{			
EdgeMap e = new EdgeMap(cimg.img);
eimg.img = createImage(e.getImage());
cimg.repaint();
eimg.repaint();
}
}
public void paint(Graphics g)
{
update(g);
}
public static void main(String[] args) 
{
System.out.println("Hello World!");
FColCamera a = new FColCamera();
try{Thread t  = new Thread(a);t.start();}catch(Exception e){}
}
}


(c) EdgeMap.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.image.*;
import java.util.*;

public class EdgeMap
{
Image im,em;
MemoryImageSource source;
Dimension d;
int w,h;
int no;
int pixels[],G[],hg[],vg[];
int matres[][],matim[][],op[][];
Point arr[];
public EdgeMap(Image img)
{
int hop[][] = {{-1,-2,-1},{0,0,0},{1,2,1}};
int vop[][] = {{-1,0,1},{-2,0,2},{-1,0,1}};
try{
im = img;
	
w = im.getWidth(null);
h = im.getHeight(null);
arr = new Point[w*h];

//System.out.println("I:"+h+" "+w);
pixels = new int[w*h];
G = new int[w*h];
hg = new int[w*h];
vg = new int[w*h];
matres = new int[h][w];
matim = new int[h][w];
op = new int[h][w];
		
PixelGrabber pg = new PixelGrabber(im,0,0,w,h,pixels,0,w);
pg.grabPixels();
}catch(InterruptedException ie){System.out.println(ie);}
catch( ArrayIndexOutOfBoundsException ae){System.out.println(ae);}
catch(Exception e){System.out.println("E:"+e);
e.printStackTrace();}
grayScale(pixels,w*h);
linToMat(pixels,matim,w*h,w,h);
operate(matres,matim,hop,w,h,3,3,1,1);
matToLin(matres,hg,w,h,w*h);
operate(matres,matim,vop,w,h,3,3,1,1);
matToLin(matres,vg,w,h,w*h);
vectorSum(G,hg,vg,w*h);
linToMat(G,op,w*h,w,h);
int ch=0;
do
{
ch=thinner(op,w,h);
}while(ch!=0);
matToLin(op,G,w,h,w*h);
procure(op,arr,w,h);
		
source = new MemoryImageSource(w,h,G,0,w);
}
int thinner(int mat[][],int w ,int h)
{
int ch=0;
int nb[] = new int[8];
int nz=0,z01=0,z02=0,z04=0,p1,p2;
for(int i=1;i<h-1;i++)
{
for (int j=1;j<w-1 ;j++ )
{
if(mat[i][j]==255)
{
nz=Nz(i,j,mat,w,h,nb);									
z01=Z0(i,j,mat,w,h);										
z02=Z0(i-1,j,mat,w,h);									
z04=Z0(i,j-1,mat,w,h); 
p1=nb[0]&nb[2]&nb[6];									
p2=nb[0]&nb[2]&nb[4];	
 		
if(nz>=2&&nz<=6&&z01==1&&((p1==0)||(z02!=1))&&((p2==0)||(z04!=1)))
{
mat[i][j]=0;ch++;
}
}
}
}
return ch;
}
int Z0(int m,int n,int mat[][],int w,int h)
{
int no = 0,k=0,l=0,x=0,y=0;
int nb[] = new int[8];
		
for (int i=0;i<8 ;i++ )
{
switch(i%8)
{
case 0:x=0;y=-1;break;
case 1:x=-1;y=-1;break;
case 2:x=-1;y=0;break;
case 3:x=-1;y=1;break;
case 4:x=0;y=1;break;
case 5:x=1;y=1;break;
case 6:x=1;y=0;break;
case 7:x=1;y=-1;break;
default:x=0;y=0;break;
}

k=m+y;l=n+x;
if(k<0||l<0||k>=h||l>=w)nb[i]=0;
else nb[i]=mat[k][l];
}
for (int i=0;i<8;i++ )
{
if((nb[i]!=nb[(i+1)%8])&&(nb[i]==0))no++;
}
return no;
}
	
int Nz(int m,int n,int mat[][],int w,int h,int nb[])
{
int no = 0,k=0,l=0,x,y;
for (int i=0;i<8 ;i++ )
{
switch(i%8)
{
case 0:x=0;y=-1;break;
case 1:x=-1;y=-1;break;
case 2:x=-1;y=0;break;
case 3:x=-1;y=1;break;
case 4:x=0;y=1;break;
case 5:x=1;y=1;break;
case 6:x=1;y=0;break;
case 7:x=1;y=-1;break;
default:x=0;y=0;break;
}
				
k=m+y;l=n+x;
if(k<0||l<0||k>=h||l>=w)nb[i]=0;
else nb[i]=mat[k][l];
if(nb[i]!=0)no++;
}
return no;
}

void vectorSum(int res[],int hor[],int ver[],int size)
{
//int r,h,v;
int y;
for(int i = 0;i < size; i++)
{
int h=hor[i]&255,v=ver[i]&255;
			
y=(int) Math.sqrt((double) (h*h) + (double)(v*v) );
if(y>50)
y=255;
else
y=0;
res[i]=255<<24|y<<16|y<<8|y;
}
}

void procure(int mat[][],Point arr[],int w,int h)
{
int k=0;
for (int i=0;i<h ;i++ )
{
for (int j=0;j<w ;j++ )
{
if((mat[i][j]==255)&&i!=0&&j!=0&&i!=h-1&&j!=w-1)
{
arr[k] = new Point(j,i);
k++;
}
}
}
no=k;
}
	
void sortOut()
{
double dist,mindist=99999999999.9;
int minindex=0;
Point temp1 =new Point();
Point temp2 =new Point();
Vector pointarray = new Vector(no);
Vector sortedarray = new Vector(no);
for(int i = 0;i<no;i++)
{
pointarray.add(arr[i]); //System.out.println(arr[i].toString());
}
temp1 = (Point)pointarray.firstElement();
sortedarray.add(temp1);
int k=0;
do
{
//System.out.println(temp1+" "+mindist+" "+minindex);try{Thread.sleep(500);}catch(Exception e){}
mindist=99999999999.9;
for(int i=1;i<no;i++)
{
temp2 =(Point)pointarray.get(i);
dist = temp1.distance(temp2);
if((dist<mindist)&&(sortedarray.indexOf(temp2)==-1))
{
mindist = dist;
minindex = i;
}
}
			
sortedarray.add(pointarray.get(minindex));
temp1 = (Point)pointarray.get(minindex);
}while(sortedarray.size()<no);
			
for(int i = 0;i<no;i++)
{
arr[i]= new Point((Point)sortedarray.get(i));
}
}

void operate(int res[][],int mat[][],int op[][],int w,int h,int ow,int oh,int x,int y)
{
for (int i=0;i<h ;i++ )
{
for (int j=0;j<w;j++ )
{
int m=0;
for(int k = 0; k<oh; k++)
{
for (int l=0;l<ow ;l++ )
{
int hcor = i - y + k,wcor = j - x + l;
int val;
if(hcor<0||wcor<0||hcor>=h||wcor>=w)
val=0;
else
val = mat[hcor][wcor]*op[k][l];
m += val;	
}
}
if(m<0)m=-m;
res[i][j]=m;
}
}
}

void linToMat(int lin[],int mat[][],int size,int w,int h)
{
int k = 0;
for (int i=0;i<h ;i++ )
{
for (int j=0;j<w;j++)
{
mat[i][j] = lin[k++]&255;
}
}
}
void matToLin(int mat[][],int lin[],int w,int h,int size)
{
int k = 0;
for (int i=0;i<h ;i++ )
{
for (int j=0;j<w;j++)
{
lin[k++] =255<<24|mat[i][j]<<16|mat[i][j]<<8|mat[i][j];
}
}
}

void grayScale(int pix[],int size)
{
int r,g,b,l,t;
for(int i=0;i<size;i++)
{
t = pix[i];
b = t&255; t = t >> 8;
g = t&255; t = t >> 8;
r = t&255; 
double y = .33*r + .56*g + .11*b;
l = (int)y;
t = 255<<24|l<<16|l<<8|l;
pix[i] = t;
}
}

public MemoryImageSource getImage()
{
return source;
}
}
