package ip.gui.frames;
import gui.run.RunButton;
import ip.gabor.FilterCanvas;
import ip.gabor.GaborPanel;
import ip.gabor.MartelliParams;
import ip.gabor.MartelliView;
import ip.gui.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import graphics.ImageUtils;
public class MartelliFrame extends PaintFrame {
private EdgeElements finalEdgeList = new EdgeElements();
public static final int maximumNumberOfEdges = 15000;
public static final int edgeLength = 20;
private MartelliParams mp = new MartelliParams();
public static final int runTimeInSeconds = 10;
private Timer t = new Timer();
public void erase() {
super.eraseShapes();
finalEdgeList = new EdgeElements();
setPolyList(new Polygons());
initialize();
}
Menu heuristicMenu = getMenu("heuristics");
MenuItem processUserPoints_mi =
addMenuItem(heuristicMenu, "[E-M]process user points");
MenuItem erase_mi =
addMenuItem(heuristicMenu, "erase path");
MenuItem negativeRobertsOnGreen_mi =
addMenuItem(heuristicMenu, "use NegativeRobertsOnGreen");
MenuItem averageWithChild_mi =
addMenuItem(getFileMenu(), "averageWithChild");
MenuItem printPath_mi = addMenuItem(heuristicMenu, "printPath");
MenuItem gabor_mi = addMenuItem(heuristicMenu, "Gabor...");
MenuItem grabGabor_mi = addMenuItem(heuristicMenu, "grab gabor");
GaborPanel gp = null;
public MartelliFrame(String title) {
super(title);
getBoundaryMenu().add(heuristicMenu);
}
public static void main(String args[]) {
MartelliFrame xf = new MartelliFrame("MartelliFrame");
}
public void averageWithChild() {
for (int x = 0; x < getImageWidth(); x++)
for (int y = 0; y < getImageHeight(); y++) {
getR()[x][y] = (short) ((getR()[x][y] + getChild().getR()[x][y]) / 2);
getG()[x][y] = (short) ((getR()[x][y] + getChild().getG()[x][y]) / 2);
getB()[x][y] = (short) ((getR()[x][y] + getChild().getB()[x][y]) / 2);
}
short2Image();
}
public void negativeRobertsOnGreen() {
int p[] = new int[4];
float delta_u = 0;
float delta_v = 0;
for (int x = 0; x < getImageWidth() - 1; x++)
for (int y = 0; y < getImageHeight() - 1; y++) {
p[0] = getR()[x][y];
p[1] = getR()[x + 1][y];
p[2] = getR()[x][y + 1];
p[3] = getR()[x + 1][y + 1];
delta_u = p[0] - p[3];
delta_v = p[1] - p[2];
getG()[x][y] =
(short) (255 - Math.sqrt(delta_u * delta_u + delta_v * delta_v));
}
}
public static int clip(int x) {
if (x < 0) return 0;
return x;
}
private boolean terminateSearch(EdgeElement el, Point nextPoint) {
if (t.getElapsedTime() > runTimeInSeconds) {
t.start(); return true;
}
if (el.distance(nextPoint) < 2) {
t.start(); return true;
}
return false;
}
EdgeElement getMarked(EdgeElement inputEdgeElement) {
for (int i = 0; i < finalEdgeList.getSize(); i++) {
EdgeElement el = finalEdgeList.getElementAt(i);
if ((el.p1.x == inputEdgeElement.p1.x) &&
(el.p1.y == inputEdgeElement.p1.y) &&
(el.p2.x == inputEdgeElement.p2.x) &&
(el.p2.y == inputEdgeElement.p2.y)) {
return el;
}
}
return null;
}
private int C22(EdgeElement e, Point nextPoint) {
int pc = 0;
EdgeElement p = e.getParent();
int d = e.distance(nextPoint);
if (p != null) ; return
clip(pc +
d + -(
getG()[e.p1.x][e.p1.y] -
getG()[e.p2.x][e.p2.y])
);
}
FilterCanvas subBands[];
int getMinSubBand(Point p) {
int subBand = 0;
int maxValue = Integer.MIN_VALUE;
int i;
for (i = 1; i < subBands.length; i++) {
int v = subBands[i].getGreenValueAt(p);
if (v > maxValue) {
maxValue = v;
subBand = i;
}
}
return subBand;
}
int getMaxSubBand(Point p) {
int subBand = 0;
int minValue = Integer.MAX_VALUE;
int i;
for (i = 1; i < subBands.length; i++) {
int v = subBands[i].getGreenValueAt(p);
if (v < minValue) {
minValue = v;
subBand = i;
}
}
return subBand;
}
private int C(EdgeElement e, Point nextMarker, int subBand, MartelliParams mp) {
Point edgeEndPoint = e.p2;
subBand = getMinSubBand(edgeEndPoint);
int v = subBands[subBand].getGreenValueAt(edgeEndPoint);
v = v; int ply = -e.getPly();
int d = e.distance(nextMarker);
return
(int) (ply * mp.getPly()) +
(int) (d * mp.getGreediness()) +
(int) (v * mp.getPixel());
}
private int CSimple(EdgeElement e, Point nextPoint) {
int pc = 0;
EdgeElement p = e.getParent();
int d = 2 * e.distance(nextPoint);
return
clip(pc +
d + getChild().getG()[e.p1.x][e.p1.y]);
}
private void addElementToExpandedList(
Point p1, Point p2,
EdgeElement parentEdgeElement, Point nextMarker,
EdgeElements expandedEdgeElements,
int subBand) {
if (!Points.isRangeValid(p1, p2, new Dimension(getImageWidth(), getImageHeight()))) return;
EdgeElement e = new EdgeElement();
e.setCoordinates(p1, p2);
e.setParent(parentEdgeElement);
e.setCost(C(e, nextMarker, subBand, mp));
expandedEdgeElements.add(e);
}
public void paint(Graphics g) {
super.paint(g);
Polygons p = getPolyList();
if (p != null)
p.drawPolys(g);
}
private void expand(EdgeElement el, Point nextMarker,
EdgeElements expandedEdgeElements,
int subBand) {
Points nextPoints = GeometryUtils.getNextPoints(el.p2, nextMarker);
while (nextPoints.hasMorePoints()) {
Point p = nextPoints.nextPoint();
addElementToExpandedList(el.p2, p, el, nextMarker, expandedEdgeElements, subBand);
}
}
private void initialize() {
finalEdgeList = new EdgeElements();
}
private void processUserPoints(Points userPoints) {
if (userPoints.getSize() < 2) {
System.out.println("Select start and end point(s)");
return;
}
if (subBands == null)
lowLevelPreProcessForMartelli();
Polygons polyList = new Polygons();
setPolyList(polyList);
Point startPoint = userPoints.getPointAt(0);
for (int i = 1; i < userPoints.getSize(); i++) {
Point nextPoint = userPoints.getPointAt(i);
Polygon p1 =
searchFromPoint(
new Point(startPoint.x, startPoint.y), nextPoint).getPath();
startPoint = nextPoint;
polyList.addElement(p1);
}
}
private void lowLevelPreProcessForMartelli() {
copyToChildFrame();
getChild().gauss3();
getChild().unahe();
NegateFrame.negate(getChild());
subBands = ImageUtils.getSubBands(getChild().getImage(), getChild());
show();
}
public EdgeElement searchFromPoint(Point startPoint, Point nextMarker) {
initialize();
EdgeElement lowestCostEdgeElement;
EdgeElement startEdgeElement = new EdgeElement();
EdgeElements expandedEdgeElements = new EdgeElements();
Point nextPoint = GeometryUtils.getNextPointOnLine(startPoint, nextMarker);
startEdgeElement.setCoordinates(startPoint, nextPoint);
startEdgeElement.setOpen(true);
finalEdgeList.add(startEdgeElement);
int subBand = getMaxSubBand(startPoint);
System.out.println("new subband=" + subBand);
while (
(lowestCostEdgeElement = finalEdgeList.getMinOpenNode())
!= null) {
if (terminateSearch(lowestCostEdgeElement, nextMarker)) break;
lowestCostEdgeElement.setOpen(false);
expand(lowestCostEdgeElement, nextMarker, expandedEdgeElements, subBand);
if (expandedEdgeElements.getSize() == 0) continue;
processExpandedNodes(expandedEdgeElements);
}
lowestCostEdgeElement = finalEdgeList.getMinOpenNode();
return lowestCostEdgeElement;
}
private void processExpandedNodes(EdgeElements expandedEdgeElements) {
for (int i = 0; i < expandedEdgeElements.getSize(); i++) {
EdgeElement e = expandedEdgeElements.getElementAt(i);
EdgeElement MarkedNode = getMarked(e);
if (MarkedNode == null) {
finalEdgeList.add(e);
continue;
}
if (e.getCost() < MarkedNode.getCost())
MarkedNode = e;
}
}
public void gabor() {
gp = new GaborPanel(getImage());
Frame f = new Frame();
f.setLayout(new BorderLayout());
f.add(gp, BorderLayout.CENTER);
gp.init();
f.show();
f.setSize(200, 200);
}
public void grabGabor() {
subBands = gp.getFilters();
MartelliView mv = new MartelliView(mp);
RunButton rb = new RunButton("Apply") {
public void run() {
processUserPoints();
}
};
mv.addRunButton(rb);
}
public void actionPerformed(ActionEvent e) {
if (match(e, gabor_mi)) {
gabor();
return;
}
if (match(e, grabGabor_mi)) {
grabGabor();
return;
}
if (match(e, averageWithChild_mi)) {
averageWithChild();
return;
}
if (match(e, negativeRobertsOnGreen_mi)) {
negativeRobertsOnGreen();
return;
}
if (match(e, erase_mi)) {
erase();
return;
}
if (match(e, processUserPoints_mi)) {
processUserPoints();
return;
}
super.actionPerformed(e);
}
private void processUserPoints() {
System.out.println("shapes.size()=" + userPoints.getSize());
Timer martelliTimer = new Timer();
martelliTimer.start();
processUserPoints(userPoints);
martelliTimer.print("Martelli done");
}
}