Finding shape segemnts
Hello
I am currently working on a project called : Jigsaw solver where I load a jpeg picture of all the pieces of a jigsaw puzzle in an unmade state laid out on a plain white background. The image is analysed to isolate the images of each piece from the whole image.
At the moment i have made simple shape as my image as a jpeg. I will only be dealing wiht black and white colours for now. Therefore, my image will be black on a white background. I ahve written an edge detection algorithm as posted below. It detects the edge of a shape iteratively and saves the edge coordinates in an arraylist called, boundary.
I am successful at finding the edge of a shape.
My current problem is I need to find the coordinates within my shapes edge boundary. I need to find the inner coordinates as segments and store the segments in another arraylist. Not sure how to retrieve the coordinates as segments ?
Any help would be greatly appreciated :) many many thanks
I have posted my code below:
/*
* FindEdge.java
*/
package jigsaw;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
public class FindEdge
{
public void detectEdge(JigSawPanel jp) // does the walking around the edge
{
BufferedImage img = jp.getImage();
int width = img.getWidth();
int height = img.getHeight();
int fromDir = 0;
ArrayList<Point> boundary = new ArrayList<Point>();
for (int x = 0 ; x < width ; x++)
{
for (int y = 0 ; y < height ; y++)
{
int pixColour = img.getRGB(x, y);
Color rgbColour = new Color(pixColour);
int val = getRGBValue(rgbColour);
if (val < 80) // 80 is the threshold value that filters between black and white pixels... rgb val for white is 765 and for black its 0 but had to filter ou greys too
{
// System.out.println (val); // so if its is a black pixel then do the following find its next black neighbouring edge
Point current = new Point(x, y);
Point startPoint = new Point(current); // to check whether we have come back to the starting point after walking around
System.out.println("start point : " + startPoint);
Point nextPos = new Point();
do
{
int toDir;
for (toDir = 0 ; toDir < 6 ; toDir++)
{
step(fromDir, current, toDir, nextPos);
int nxtPix = img.getRGB(nextPos.x, nextPos.y); // getting rgb value of its neighbouring pixel
Color nxtcol = new Color(nxtPix);
int value = getRGBValue(nxtcol);
if (value < 80)// checking if the neighbouring pixl is black
//System.out.println("implements here 2");
break;
}
if (toDir == 6)
{
System.exit(1);
}
System.out.println(
"from: " +
fromDir +
" current: " +
current +
" to dir: " +
toDir +
" nextPos: " +
nextPos);
// debugging: we know that pixel is an edge and turns the edge pixel to red... to check if correct edge has been detected
//img.setRGB(nextPos.x, nextPos.y, Color.red.getRGB());
boundary.add(new Point(current)); // adds that pixel coord into an arraylist
//jp.repaint();
//System.out.println("size: "+ boundary.size());
fromDir = (fromDir + toDir + 6) % 8 ;
current.x = nextPos.x;
current.y = nextPos.y;
} while (!startPoint.equals(current));
System.out.println("end of scan!!!: found " + boundary.size() + " points on the boundary");
for (Point pt : boundary)
{
img.setRGB(pt.x, pt.y, Color.red.getRGB());
}
jp.repaint();
break;
}
}
}
}
public void step(int fromDirection, Point currentPoint, int toDirection, Point nextPoint)
{
switch (fromDirection)
{
case 0: //different directions for checking where the next black edge pixel is
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y - 1;
break;
case 1:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y - 1;
break;
case 2:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y;
break;
case 3:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y + 1;
break;
case 4:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y + 1;
break;
case 5:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y + 1;
break;
}
break;
case 1:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y - 1;
break;
case 1:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y;
break;
case 2:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y + 1;
break;
case 3:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y + 1;
break;
case 4:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y + 1;
break;
case 5:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y;
break;
}
break;
case 2:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y;
break;
case 1:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y + 1;
break;
case 2:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y + 1;
break;
case 3:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y + 1;
break;
case 4:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y;
break;
case 5:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y - 1;
break;
}
break;
case 3:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y + 1;
break;
case 1:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y + 1;
break;
case 2:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y + 1;
break;
case 3:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y;
break;
case 4:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y - 1;
break;
case 5:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y - 1;
break;
}
break;
case 4:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y + 1;
break;
case 1:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y + 1;
break;
case 2:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y;
break;
case 3:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y - 1;
break;
case 4:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y - 1;
break;
case 5:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y - 1;
break;
}
case 5:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y + 1;
break;
case 1:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y;
break;
case 2:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y - 1;
break;
case 3:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y - 1;
break;
case 4:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y - 1;
break;
case 5:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y;
break;
}
break;
case 6:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y ;
break;
case 1:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y - 1;
break;
case 2:
nextPoint.x = currentPoint.x ;
nextPoint.y = currentPoint.y - 1;
break;
case 3:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y - 1;
break;
case 4:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y ;
break;
case 5:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y + 1;
break;
}
break;
case 7:
switch (toDirection)
{
case 0:
nextPoint.x = currentPoint.x - 1;
nextPoint.y = currentPoint.y - 1;
break;
case 1:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y - 1;
break;
case 2:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y - 1;
break;
case 3:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y ;
break;
case 4:
nextPoint.x = currentPoint.x + 1;
nextPoint.y = currentPoint.y + 1;
break;
case 5:
nextPoint.x = currentPoint.x;
nextPoint.y = currentPoint.y + 1;
break;
}
break;
// case 6:
// {
// if (checkEnd(currentPoint.x, currentPoint.y, startPoint))
// }
// break;
}
}
public boolean checkEnd(int x, int y, Point startPoint)
{
if (x == startPoint.x && y + 1 == startPoint.y)
return true;
else
return false;
}
public int getRGBValue(Color colPix) // gets the sum of red, green, blue colour value for a pixel
{
int red = colPix.getRed();
int green = colPix.getGreen();
int blue = colPix.getBlue();
int value = red + green + blue;
return value;
}
}
import java.awt.image.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
public class JigSawPanel extends JPanel
{
private BufferedImage image;
/** Creates a new instance of JigSawPanel */
public JigSawPanel()
{
//file from location
String imgFile= ("/home/aps/projectStudents/Nikita/sample.jpg");
// try to load file to buffered image
try
{
image= ImageIO.read ( new File (imgFile));
setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
}
catch(IllegalArgumentException ie) // if file does not exist or corrupt
{
System.exit(1);
}
catch(IOException ie)
{
System.exit(1);
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
public BufferedImage getImage()
{
return image;
}
}
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
public class JigSawFrame extends JFrame
{
/** Creates a new instance of Main */
public JigSawFrame()
{
JigSawPanel jp = new JigSawPanel();
FindEdge fe= new FindEdge();
int x = jp.getImage().getWidth(this); // get image width from jig saw panel
int y = jp.getImage().getHeight(this); // get image height from jig saw panel
jp.setPreferredSize(new Dimension (x, y)); //set panel size
Container content= getContentPane();
content.add(jp, BorderLayout.CENTER);
pack();
setVisible(true);
show();
fe.detectEdge(jp);
}
public static void main(String[] args)
{
JFrame frame= new JigSawFrame();
}
}

