Assignment 4:
Computing Isocurves and Smoothing Polygon Curves
The goal of this assignment is to implement several isocurve extraction algorithms: regular triangulation, cuberille, and marching squares; as well as a simple smoothing algorithm for polygonal curves.
DATES
The assignment is out on Wednesday, October 31, 2012, and it is due on Monday, November 12, 2012.
ASSIGNMENT FILES
Download the zip file ENGN1610-2012-A4.zip containing all the Assignment 4 files. Unzip it to a location of your choice. You should have now a directory named assignment4 containing the following five files
- Makeflie
- JImgShopA4.zip
- JImgShopA4.lnk
- JImgPanelPixelOps.java
- ImgPixelOps.java
- JImgPanelFilters.java
- ImgFilters.java
- JImgPanelWarping.java
- ImgWarping.java
- JImgPanelIsocurve.java
- ImgIsocurve.java
- javac -O -classpath ".;JImgShopA4.zip" JImgPanelIsocurve.java
- javac -O -classpath ".;JImgShopA4.zip" JImgPanelWarping.java
- javac -O -classpath ".;JImgShopA4.zip" JImgPanelFilters.java
- javac -O -classpath ".;JImgShopA4.zip" JImgPanelPixelOps.java
- JImgPanelIsocurve.class
- ImgIsocurve.class
- JImgPanelWarping.class
- ImgWarping.class
- JImgPanelFilters.class
- ImgFilters.class
- JImgPanelPixelOps.class
- ImgPixelOps.class
In a windows machine you can run the JImgShop program by double clicking on the shortcut JImgShopA4.lnk. Otherwise, type the following command at a command promp.
- java -Xmx1000M -cp ".;jImgShopA4.zip" JImgShopApp -w 790 -h 800 -st
The file JImgPanelIsocurve.java contains the implementation of the graphical user interface associated with this assignment. You don't need to modify this file unless you want to modify the design of the GUI.
THE ImgIsocurve CLASS
The file ImgIsocurve.java contains the implementation of the class ImgIsocurve, which is designed to isolate the isocurve and polygon smoothing algorithms that you need to implement from the rest of the program. The class ImgIsocurve includes the following public methods already implemented- public void setAdd(boolean add);
- public void setOutside(boolean outside);
- public OrPoints convertToOrPoints();
- public void compute(float level);
- public void lowPass(float lambda, float kappa, int nSmooth);
- public void computeRegularTriangulation(float level);
- public void computeCuberille(float level);
- public void computeMarchingSquares(float level);
- public void laplacianSmooth(float lambda0, float lambda1, int nSmooth);
As provided, the class also includes a number of protected and private methods which should be regarded as hints. Feel free to delete those methods if you decide to implement your code in a different way.
THE GraphPlanar CLASS
This class, which extends the Graph class, is used to represent planar polygonal curves in indexed form. Every vertex of a polygonal curve has two coordinates and an index. The coordinates are stored in a linear array, and the indices correspond to locations within this array. Edges connect pairs of vertices. Each edge is represented as a pair of vertex indices. A Graph may be oriented or directed. In this assignment we will use directed graphs, to differentiate between the inside from the outside of closed curves.The application takes care of creating an instance of the GraphPlanar class for us to use to store isocurves extracted from images. The method
- public void erase(boolean oriented);
The method
- public VecFloat getCoord();
- public int getNumberOfCoord();
- public int pushBackCoord(float x, float y);
Edges are pairs of vertex indices. To add a new edge, you can use the following method
- public void insert(int iV0, int iV1);
The method
- public GraphEdge getEdge(int iV0, int iV1);
- public int getVertex(int i);
- public int getIndex();
To linearly traverse the edges you should use the following code structure
Graph g; GraphEdge e; for(int i=0;i<g.getNumberOfVertices();i++) { for(e=g.getFirstEdge(i);e!=null;e=g.getNextEdge(e)) { int iE = e.getIndex(); int iV0 = e.getVertex(0); int iV1 = e.getVertex(1); // ... } }
In this method the isocurve vertices are located at corners of image pixels, and the isocurve edges are some of the image edges shared by neighboring pixels. The algorithm runs in linear time and can be implemented with four image scans.
In the first scan a binary image is produced. Each image pixel value is tested against the desired isocurve level. If the image pixel value is larger than the isovalue the binary pixel value is set to 1; otherwise it is set to 0.
In the second scan the isosurface vertices are created. For this we look at the binary values in a 2x2 neighborhood around each pixel corner. An isosurface vertex must be created if not all four neighboring pixels have the same binary value. Image boundary vertices require special treatment, with pixels falling outside of the image boundary being assigned a predetermined binary value. An additional data structure such as an array is needed to store the association between pixel corners and isocurve vertex indices. The vertex index -1 is used to indicate that a particular vertex corner does not have an associated vertex index.
In the third scan the vertical edges are generated. Here we need to look at pairs of pixels consecutive in the horizontal direction. An edge has to be created if the two pixels have different binary values. There are two possible cases corresponding to the two possible orientations for the edge. Make sure that you create edges with consistent orientations. To create an edge we need to retrieve the two isocurve vertex indices from the data structure created to store them in the previous step.
In the fourth scan the horizontal edges are generated. This process is similar to the creation of vertical edges.
Read Monday, November 9, and Wednesday, November 11, 2009, class notes.
public void computeRegularTriangulation(float level)
Read Monday, November 9, and Wednesday, November 11, 2009, class notes.
public void laplacianSmooth(float lambda0, float lambda1, int nSmooth)
Read Monday, November 9, and Wednesday, November 11, 2009, class notes, as well as Wednesday, November 11, 2009, smoothing slides.