public PixelTransformCached_F32(int width, int height, Point2Transform2_F32 transform ) { this(width,height, new PointToPixelTransform_F32(transform)); }
/** * Used to manually specify a transform. From output to input */ public FDistort transform( Point2Transform2_F32 outputToInput ) { return transform( new PointToPixelTransform_F32(outputToInput)); }
@Override public void processImage(int sourceID, long frameID, BufferedImage buffered, ImageBase input) { synchronized (imageLock) { // create a copy of the input image for output purposes if (buffFisheye.getWidth() != buffered.getWidth() || buffFisheye.getHeight() != buffered.getHeight()) { buffFisheye = new BufferedImage(buffered.getWidth(), buffered.getHeight(), BufferedImage.TYPE_INT_BGR); panelFisheye.setPreferredSize(new Dimension(buffered.getWidth(),buffered.getHeight())); panelFisheye.setImageUI(buffFisheye); distortImage.setModel(new PointToPixelTransform_F32(distorter)); } buffFisheye.createGraphics().drawImage(buffered, 0, 0, null); fisheye.setTo((T)input); rerenderPinhole(); } }
public static void fullViewLeft(int imageWidth,int imageHeight, FMatrixRMaj rectifyLeft, FMatrixRMaj rectifyRight ) { Point2Transform2_F32 tranLeft = new PointTransformHomography_F32(rectifyLeft); RectangleLength2D_F32 bound = DistortImageOps.boundBox_F32(imageWidth, imageHeight, new PointToPixelTransform_F32(tranLeft)); float scaleX = imageWidth/bound.width; float scaleY = imageHeight/bound.height; float scale = (float)Math.min(scaleX,scaleY); adjustUncalibrated(rectifyLeft, rectifyRight, bound, scale); }
public static void allInsideLeft( int imageWidth,int imageHeight, FMatrixRMaj rectifyLeft, FMatrixRMaj rectifyRight ) { PointTransformHomography_F32 tranLeft = new PointTransformHomography_F32(rectifyLeft); RectangleLength2D_F32 bound = LensDistortionOps_F32.boundBoxInside(imageWidth, imageHeight, new PointToPixelTransform_F32(tranLeft)); float scaleX = imageWidth/(float)bound.width; float scaleY = imageHeight/(float)bound.height; float scale = (float)Math.max(scaleX, scaleY); adjustUncalibrated(rectifyLeft, rectifyRight, bound, scale); }
/** * <p> * Adjust the rectification such that only pixels which overlap the original left image can be seen. For use with * uncalibrated images with unknown baselines. Image processing is easier since only the "true" image pixels * are visible, but information along the image border has been discarded. The rectification matrices are * overwritten with adjusted values on output. * </p> * * @param imageWidth Width of left image. * @param imageHeight Height of left image. * @param rectifyLeft Rectification matrix for left image. Input and Output. Modified. * @param rectifyRight Rectification matrix for right image. Input and Output. Modified. */ public static void allInsideLeft( int imageWidth,int imageHeight, DenseMatrix64F rectifyLeft, DenseMatrix64F rectifyRight ) { Point2Transform2_F32 tranLeft = new PointTransformHomography_F32(rectifyLeft); RectangleLength2D_F32 bound = LensDistortionOps.boundBoxInside(imageWidth, imageHeight, new PointToPixelTransform_F32(tranLeft)); double scaleX = imageWidth/(double)bound.width; double scaleY = imageHeight/(double)bound.height; double scale = Math.max(scaleX, scaleY); adjustUncalibrated(rectifyLeft, rectifyRight, bound, scale); }
public static void fullViewLeft(CameraPinholeRadial paramLeft, FMatrixRMaj rectifyLeft, FMatrixRMaj rectifyRight, FMatrixRMaj rectifyK) { // need to take in account the order in which image distort will remove rectification later on paramLeft = new CameraPinholeRadial(paramLeft); Point2Transform2_F32 tranLeft = transformPixelToRect(paramLeft, rectifyLeft); RectangleLength2D_F32 bound = DistortImageOps.boundBox_F32(paramLeft.width, paramLeft.height, new PointToPixelTransform_F32(tranLeft)); float scaleX = paramLeft.width/bound.width; float scaleY = paramLeft.height/bound.height; float scale = (float)Math.min(scaleX, scaleY); adjustCalibrated(rectifyLeft, rectifyRight, rectifyK, bound, scale); }
@Override public synchronized void updatedPinholeModel(CameraPinholeRadial desired) { if( undist.width != desired.width || undist.height != desired.height ) { undist.reshape(desired.width, desired.height); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { gui.setPreferredSize(new Dimension(undist.width, undist.height)); // gui.invalidate(); } }); } Point2Transform2_F32 add_p_to_p = LensDistortionOps_F32. transformChangeModel(adjustment, origModel,desired,true,null); undistorter.setModel(new PointToPixelTransform_F32(add_p_to_p)); if( inputMethod == InputMethod.IMAGE ) renderCameraModel(); }
public static void allInsideLeft(CameraPinholeRadial paramLeft, FMatrixRMaj rectifyLeft, FMatrixRMaj rectifyRight, FMatrixRMaj rectifyK) { // need to take in account the order in which image distort will remove rectification later on paramLeft = new CameraPinholeRadial(paramLeft); Point2Transform2_F32 tranLeft = transformPixelToRect(paramLeft, rectifyLeft); RectangleLength2D_F32 bound = LensDistortionOps_F32.boundBoxInside(paramLeft.width, paramLeft.height, new PointToPixelTransform_F32(tranLeft)); LensDistortionOps_F32.roundInside(bound); float scaleX = paramLeft.width/(float)bound.width; float scaleY = paramLeft.height/(float)bound.height; float scale = (float)Math.max(scaleX, scaleY); adjustCalibrated(rectifyLeft, rectifyRight, rectifyK, bound, scale); }
/** * Easy way to create {@link ImageDistort} given {@link PixelTransform2_F32}. To improve * performance the distortion is automatically cached. * * @see FactoryDistort * @see FactoryInterpolation * * @deprecated As of v0.19. Use {@link FDistort} instead * * @param transform Image transform. * @param interpType Which interpolation. Try bilinear. * @param inputType Image of single band image it will process. * @return The {@link ImageDistort} */ public static <Input extends ImageGray<Input>,Output extends ImageGray<Output>> ImageDistort<Input,Output> createImageDistort(Point2Transform2_F32 transform, InterpolationType interpType, BorderType borderType, Class<Input> inputType, Class<Output> outputType) { InterpolatePixelS<Input> interp = FactoryInterpolation.createPixelS(0, 255, interpType,borderType, inputType); ImageDistort<Input,Output> distorter = FactoryDistort.distortSB(true, interp, outputType); distorter.setModel(new PointToPixelTransform_F32(transform)); return distorter; }
/** * <p> * Adjust the rectification such that only pixels which overlap the original left image can be seen. For use with * calibrated stereo images having a known baseline. Image processing is easier since only the "true" image pixels * are visible, but information along the image border has been discarded. The rectification matrices are * overwritten with adjusted values on output. * </p> * * @param paramLeft Intrinsic parameters for left camera. Not modified. * @param rectifyLeft Rectification matrix for left image. Input and Output. Modified. * @param rectifyRight Rectification matrix for right image. Input and Output. Modified. * @param rectifyK Rectification calibration matrix. Input and Output. Modified. */ public static void allInsideLeft(CameraPinholeRadial paramLeft, DenseMatrix64F rectifyLeft, DenseMatrix64F rectifyRight, DenseMatrix64F rectifyK) { // need to take in account the order in which image distort will remove rectification later on paramLeft = new CameraPinholeRadial(paramLeft); Point2Transform2_F32 tranLeft = transformPixelToRect_F32(paramLeft, rectifyLeft); RectangleLength2D_F32 bound = LensDistortionOps.boundBoxInside(paramLeft.width, paramLeft.height, new PointToPixelTransform_F32(tranLeft)); LensDistortionOps.roundInside(bound); double scaleX = paramLeft.width/(double)bound.width; double scaleY = paramLeft.height/(double)bound.height; double scale = Math.max(scaleX, scaleY); adjustCalibrated(rectifyLeft, rectifyRight, rectifyK, bound, scale); }
private void addUndistorted(final String name, final Point2Transform2_F32 model) { // Set up image distort InterpolatePixel<T> interp = FactoryInterpolation. createPixel(0,255,InterpolationType.BILINEAR, BorderType.ZERO, undist.getImageType()); ImageDistort<T,T> undistorter = FactoryDistort.distort(false, interp, undist.getImageType()); undistorter.setModel(new PointToPixelTransform_F32(model)); undistorter.apply(dist,undist); final BufferedImage out = ConvertBufferedImage.convertTo(undist,null,true); // Add this rectified image SwingUtilities.invokeLater(new Runnable() { public void run() { gui.addItem(new ImagePanel(out), name); }}); }
/** * Creates an {@link ImageDistort} for rectifying an image given its radial distortion and * rectification matrix. * * @param param Intrinsic parameters. * @param rectify Transform for rectifying the image. * @param imageType Type of single band image the transform is to be applied to. * @return ImageDistort for rectifying the image. */ public static <T extends ImageBase> ImageDistort<T,T> rectifyImage(CameraPinholeRadial param, DenseMatrix64F rectify , BorderType borderType, ImageType<T> imageType) { boolean skip = borderType == BorderType.SKIP; if( skip ) { borderType = BorderType.EXTENDED; } InterpolatePixel<T> interp = FactoryInterpolation.createPixel(0,255, InterpolationType.BILINEAR,borderType,imageType); // only compute the transform once ImageDistort<T,T> ret = FactoryDistort.distort(true, interp, imageType); ret.setRenderAll(!skip); Point2Transform2_F32 transform = transformRectToPixel_F32(param, rectify); ret.setModel(new PointToPixelTransform_F32(transform)); return ret; }
/** * Creates an {@link ImageDistort} for rectifying an image given its radial distortion and * rectification matrix. * * @param param Intrinsic parameters. * @param rectify Transform for rectifying the image. * @param imageType Type of single band image the transform is to be applied to. * @return ImageDistort for rectifying the image. */ public static <T extends ImageBase<T>> ImageDistort<T,T> rectifyImage(CameraPinholeRadial param, FMatrixRMaj rectify , BorderType borderType, ImageType<T> imageType) { boolean skip = borderType == BorderType.SKIP; if( skip ) { borderType = BorderType.EXTENDED; } InterpolatePixel<T> interp = FactoryInterpolation.createPixel(0,255, InterpolationType.BILINEAR,borderType,imageType); // only compute the transform once ImageDistort<T,T> ret = FactoryDistort.distort(true, interp, imageType); ret.setRenderAll(!skip); Point2Transform2_F32 transform = transformRectToPixel(param, rectify); ret.setModel(new PointToPixelTransform_F32(transform)); return ret; }
@Override public void initialize(int imageWidth, int imageHeight, int sensorOrientation) { undistorted = imageType.createImage(imageWidth,imageHeight); CameraPinholeRadial intrinsic = app.preference.lookup( imageWidth,imageHeight); if( intrinsic != null ) { // define the transform. Cache the results for quick rendering later on CameraPinhole desired = new CameraPinhole(); desired.set(intrinsic); Point2Transform2_F32 fullView = LensDistortionOps.transformChangeModel_F32(AdjustmentType.FULL_VIEW, intrinsic,desired,false,null); InterpolatePixelS<GrayU8> interp = FactoryInterpolation. bilinearPixelS(GrayU8.class, BorderType.ZERO); // for some reason not caching is faster on a low end phone. Maybe it has to do with CPU memory // cache misses when looking up a point? removeDistortion = FactoryDistort.distort(false,interp,imageType); removeDistortion.setModel(new PointToPixelTransform_F32(fullView)); } }
/** * Creates an {@link ImageDistort} for rectifying an image given its rectification matrix. * Lens distortion is assumed to have been previously removed. * * @param rectify Transform for rectifying the image. * @param imageType Type of single band image the transform is to be applied to. * @return ImageDistort for rectifying the image. */ public static <T extends ImageGray<T>> ImageDistort<T,T> rectifyImage( FMatrixRMaj rectify , BorderType borderType, Class<T> imageType) { boolean skip = borderType == BorderType.SKIP; if( skip ) { borderType = BorderType.EXTENDED; } InterpolatePixelS<T> interp = FactoryInterpolation.bilinearPixelS(imageType, borderType); FMatrixRMaj rectifyInv = new FMatrixRMaj(3,3); CommonOps_FDRM.invert(rectify,rectifyInv); PointTransformHomography_F32 rectifyTran = new PointTransformHomography_F32(rectifyInv); // don't bother caching the results since it is likely to only be applied once and is cheap to compute ImageDistort<T,T> ret = FactoryDistort.distortSB(false, interp, imageType); ret.setRenderAll(!skip); ret.setModel(new PointToPixelTransform_F32(rectifyTran)); return ret; }
/** * Creates an {@link ImageDistort} for rectifying an image given its rectification matrix. * Lens distortion is assumed to have been previously removed. * * @param rectify Transform for rectifying the image. * @param imageType Type of single band image the transform is to be applied to. * @return ImageDistort for rectifying the image. */ public static <T extends ImageGray> ImageDistort<T,T> rectifyImage( DenseMatrix64F rectify , BorderType borderType, Class<T> imageType) { boolean skip = borderType == BorderType.SKIP; if( skip ) { borderType = BorderType.EXTENDED; } InterpolatePixelS<T> interp = FactoryInterpolation.bilinearPixelS(imageType, borderType); DenseMatrix64F rectifyInv = new DenseMatrix64F(3,3); CommonOps.invert(rectify,rectifyInv); PointTransformHomography_F32 rectifyTran = new PointTransformHomography_F32(rectifyInv); // don't bother caching the results since it is likely to only be applied once and is cheap to compute ImageDistort<T,T> ret = FactoryDistort.distortSB(false, interp, imageType); ret.setRenderAll(!skip); ret.setModel(new PointToPixelTransform_F32(rectifyTran)); return ret; }
private void changeFocus(MouseEvent e) { double scale = panelFisheye.scale; double omniX = e.getX()/scale; double omniY = e.getY()/scale; if( !fisheye.isInBounds((int)omniX,(int)omniY)) return; panelPinhole.grabFocus(); synchronized (imageLock) { Point3D_F32 norm = new Point3D_F32(); fisheyeDistort.undistortPtoS_F32().compute((float)omniX, (float)omniY, norm); Rodrigues_F32 rotation = new Rodrigues_F32(); Vector3D_F32 canonical = new Vector3D_F32(0,0,1); rotation.theta = UtilVector3D_F32.acute(new Vector3D_F32(norm),canonical); GeometryMath_F32.cross(canonical,norm,rotation.unitAxisRotation); rotation.unitAxisRotation.normalize(); FMatrixRMaj R = ConvertRotation3D_F32.rodriguesToMatrix(rotation,null); distorter.setRotationWideToNarrow(R); distortImage.setModel(new PointToPixelTransform_F32(distorter)); if (inputMethod == InputMethod.IMAGE) { rerenderPinhole(); } } }
public void setCalibration(CameraUniversalOmni fisheyeModel) { BoofSwingUtil.checkGuiThread(); LensDistortionNarrowFOV pinholeDistort = new LensDistortionPinhole(pinholeModel); fisheyeDistort = new LensDistortionUniversalOmni(fisheyeModel); distorter = new NarrowToWidePtoP_F32(pinholeDistort,fisheyeDistort); // Create the image distorter which will render the image InterpolatePixel<Planar<GrayF32>> interp = FactoryInterpolation. createPixel(0, 255, InterpolationType.BILINEAR, BorderType.ZERO, imageFisheye.getImageType()); distortImage = FactoryDistort.distort(false,interp,imageFisheye.getImageType()); // Pass in the transform created above distortImage.setModel(new PointToPixelTransform_F32(distorter)); setPinholeCenter(fisheyeModel.width/2,fisheyeModel.height/2); renderPinhole(); }
public void setPinholeCenter( double pixelX , double pixelY ) { this.pixelX = pixelX; this.pixelY = pixelY; Point3D_F32 norm = new Point3D_F32(); fisheyeDistort.undistortPtoS_F32().compute((float)pixelX, (float)pixelY, norm); Rodrigues_F32 rotation = new Rodrigues_F32(); Vector3D_F32 canonical = new Vector3D_F32(0,0,1); rotation.theta = UtilVector3D_F32.acute(new Vector3D_F32(norm),canonical); GeometryMath_F32.cross(canonical,norm,rotation.unitAxisRotation); rotation.unitAxisRotation.normalize(); FMatrixRMaj R = ConvertRotation3D_F32.rodriguesToMatrix(rotation,null); distorter.setRotationWideToNarrow(R); distortImage.setModel(new PointToPixelTransform_F32(distorter)); }