package org.openpnp.util; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.openpnp.model.Configuration; import org.openpnp.model.Length; import org.openpnp.model.Location; import org.openpnp.spi.Camera; public class VisionUtils { /** * Given pixel coordinates within the frame of the Camera's image, get the offsets from Camera * center to the coordinates in Camera space and units. The resulting value is the distance the * Camera can be moved to be centered over the pixel coordinates. * * Example: If the x, y coordinates describe a position above and to the left of the center of * the camera the offsets will be -,+. * * If the coordinates position are below and to the right of center the offsets will be +, -. * * Calling camera.getLocation().add(getPixelCenterOffsets(...) will give you the location of x, * y with respect to the center of the camera. * * @param camera * @param x * @param y * @return */ public static Location getPixelCenterOffsets(Camera camera, double x, double y) { double imageWidth = camera.getWidth(); double imageHeight = camera.getHeight(); // Calculate the difference between the center of the image to the // center of the match. double offsetX = x - (imageWidth / 2); double offsetY = (imageHeight / 2) - y; // And convert pixels to units Location unitsPerPixel = camera.getUnitsPerPixel(); offsetX *= unitsPerPixel.getX(); offsetY *= unitsPerPixel.getY(); return new Location(camera.getUnitsPerPixel().getUnits(), offsetX, offsetY, 0, 0); } /** * Get the Location of a set of pixel coordinates referenced to the center of the given camera. * This is a helper method that simply adds the offsets from * {@link VisionUtils#getPixelCenterOffsets(Camera, double, double)} to the Camera's current * location. * * @param camera * @param x * @param y * @return */ public static Location getPixelLocation(Camera camera, double x, double y) { return camera.getLocation().add(getPixelCenterOffsets(camera, x, y)); } public static List<Location> sortLocationsByDistance(final Location origin, List<Location> locations) { // sort the results by distance from center ascending Collections.sort(locations, new Comparator<Location>() { public int compare(Location o1, Location o2) { Double o1d = origin.getLinearDistanceTo(o1); Double o2d = origin.getLinearDistanceTo(o2); return o1d.compareTo(o2d); } }); return locations; } public static Camera getBottomVisionCamera() throws Exception { for (Camera camera : Configuration.get().getMachine().getCameras()) { if (camera.getLooking() == Camera.Looking.Up) { return camera; } } throw new Exception("No up-looking camera found on the machine to use for bottom vision."); } public static double toPixels(Length length, Camera camera) { // convert inputs to the same units Location unitsPerPixel = camera.getUnitsPerPixel(); length = length.convertToUnits(unitsPerPixel.getUnits()); // we average the units per pixel because circles can't be ovals double avgUnitsPerPixel = (unitsPerPixel.getX() + unitsPerPixel.getY()) / 2; // convert it all to pixels return length.getValue() / avgUnitsPerPixel; } }