/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package boofcv.gui.tracker; import boofcv.gui.feature.VisualizeFeatures; import boofcv.gui.feature.VisualizeShapes; import georegression.geometry.UtilPolygons2D_F64; import georegression.metric.Area2D_F64; import georegression.struct.point.Point2D_F64; import georegression.struct.shapes.Quadrilateral_F64; import georegression.struct.shapes.RectangleLength2D_I32; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; /** * Panel for displaying results of {@link boofcv.abst.tracker.TrackerObjectQuad}. * * @author Peter Abeles */ public class TrackerObjectQuadPanel extends JPanel implements MouseListener, MouseMotionListener { int numSelected = 0; Quadrilateral_F64 quad = new Quadrilateral_F64(); boolean targetVisible; Listener listener; BufferedImage bg; Mode mode = Mode.IDLE; public TrackerObjectQuadPanel(Listener listener) { super(new BorderLayout()); this.listener = listener; if( listener != null ){ addMouseListener(this); addMouseMotionListener(this); grabFocus(); } } public synchronized void setBackGround( BufferedImage image ) { if( bg == null || bg.getWidth() != image.getWidth() || bg.getHeight() != image.getHeight() ) { bg = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_RGB); } bg.createGraphics().drawImage(image,0,0,null); } public synchronized void enterIdleMode() { mode = Mode.IDLE; repaint(); } public synchronized void enterSelectMode() { mode = Mode.PLACING_POINTS; numSelected = 0; repaint(); } public synchronized void setTarget( Quadrilateral_F64 quad , boolean visible ) { if( quad != null ) this.quad.set(quad); mode = Mode.TRACKING; targetVisible = visible; repaint(); } public synchronized void setTarget( RectangleLength2D_I32 rect , boolean visible ) { if( quad != null ) UtilPolygons2D_F64.convert(rect, quad); mode = Mode.TRACKING; targetVisible = visible; repaint(); } @Override protected synchronized void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.drawImage(bg, 0, 0, null); g2.setStroke(new BasicStroke(5)); g2.setColor(Color.gray); if (mode == Mode.PLACING_POINTS) { if (numSelected == 1) { drawCorner(g2, quad.a, Color.RED); } else if (numSelected == 2) { drawLine(g2, quad.a, quad.b); drawCorner(g2, quad.a, Color.RED); drawCorner(g2, quad.b, Color.ORANGE); } else if (numSelected == 3) { drawLine(g2, quad.a, quad.b); drawLine(g2, quad.b, quad.c); drawCorner(g2, quad.a, Color.RED); drawCorner(g2, quad.b, Color.ORANGE); drawCorner(g2, quad.c, Color.CYAN); } else if (numSelected == 4) { VisualizeShapes.drawQuad(quad, g2, true, Color.gray, Color.CYAN); drawCorner(g2, quad.a, Color.RED); drawCorner(g2, quad.b, Color.ORANGE); drawCorner(g2, quad.c, Color.CYAN); drawCorner(g2, quad.d, Color.BLUE); } } else if (mode == Mode.DRAGGING_RECT) { VisualizeShapes.drawQuad(quad, g2, true, Color.gray, Color.gray); drawCorner(g2, quad.a, Color.RED); drawCorner(g2, quad.b, Color.RED); drawCorner(g2, quad.c, Color.RED); drawCorner(g2, quad.d, Color.RED); } else if (mode == Mode.TRACKING) { if (targetVisible) { VisualizeShapes.drawQuad(quad, g2, true, Color.gray, Color.CYAN); drawCorner(g2, quad.a, Color.RED); drawCorner(g2, quad.b, Color.RED); drawCorner(g2, quad.c, Color.RED); drawCorner(g2, quad.d, Color.RED); } } } private void drawLine( Graphics2D g2 , Point2D_F64 a , Point2D_F64 b ) { g2.drawLine((int)(a.x+0.5),(int)(a.y+0.5),(int)(b.x+0.5),(int)(b.y+0.5)); } private void drawCorner( Graphics2D g2 , Point2D_F64 a , Color color ) { VisualizeFeatures.drawPoint(g2,a.x,a.y,6,color,false); } @Override public synchronized void mouseClicked(MouseEvent e) { if( mode == Mode.IDLE ) { mode = Mode.PLACING_POINTS; numSelected = 0; listener.pauseTracker(); } else if( mode != Mode.PLACING_POINTS ) { return; } if( numSelected == 0 ) { quad.a.set(e.getX(),e.getY()); } else if( numSelected == 1 ) { quad.b.set(e.getX(),e.getY()); } else if( numSelected == 2 ) { quad.c.set(e.getX(),e.getY()); } else if( numSelected == 3 ) { quad.d.set(e.getX(),e.getY()); } numSelected++; repaint(); if( numSelected == 4 ) { mode = Mode.TRACKING; listener.selectedTarget(quad); } } @Override public void mousePressed(MouseEvent e) { if( mode == Mode.PLACING_POINTS ) return; mode = Mode.DRAGGING_RECT; quad.a.set(e.getX(),e.getY()); setCornerC(e.getX(),e.getY()); listener.pauseTracker(); repaint(); } private void setCornerC( double x , double y ) { quad.b.set(quad.a.x,y); quad.c.set(x,y); quad.d.set(x,quad.a.y); } @Override public void mouseReleased(MouseEvent e) { if( mode != Mode.DRAGGING_RECT ) return; setCornerC(e.getX(),e.getY()); double area = Area2D_F64.quadrilateral(quad); if( area < 10*10 ) { mode = Mode.IDLE; repaint(); } else { mode = Mode.TRACKING; listener.selectedTarget(quad); repaint(); } } @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} public synchronized void setDefaultTarget(Quadrilateral_F64 target) { this.quad.set(target); numSelected = 4; mode = Mode.TRACKING; targetVisible = true; repaint(); } public Mode getMode() { return mode; } public void setMode(Mode mode) { this.mode = mode; } @Override public void mouseDragged(MouseEvent e) { if( mode != Mode.DRAGGING_RECT ) return; setCornerC(e.getX(),e.getY()); repaint(); } @Override public void mouseMoved(MouseEvent e) { } public enum Mode { IDLE, DRAGGING_RECT, PLACING_POINTS, TRACKING } public static interface Listener { public void selectedTarget( Quadrilateral_F64 target ); public void pauseTracker(); } }