/** * Clipps and scales the input iamge as neccisary * @param input Input image. Typically larger than output * @param output Output image */ public void massage( T input , T output ) { if( clip ) { T inputAdjusted = clipInput(input, output); // configure a simple change in scale for both axises transform.a11 = input.width / (float) output.width; transform.a22 = input.height / (float) output.height; // this change is automatically reflected in the distortion class. It is configured to cache nothing distort.apply(inputAdjusted, output); } else { // scale each axis independently. It will have the whole image but it will be distorted transform.a11 = input.width / (float) output.width; transform.a22 = input.height / (float) output.height; distort.apply(input, output); } }
@Override public void process(ImageBase input) { if( removeDistortion == null ) return; removeDistortion.apply(input,undistorted); ConvertBitmap.boofToBitmap(undistorted, bitmap, bitmapTmp); } }
private void renderCameraModel() { undistorter.apply(dist,undist); if( out != null && (out.getWidth() != undist.width || out.getHeight() != undist.height )) { out = new BufferedImage(undist.width, undist.height, out.getType()); } out = ConvertBufferedImage.convertTo(undist,out,true); gui.setImageUI(out); }
private void renderOutput(T in) { distortImage.apply(in,distorted); ConvertBufferedImage.convertTo(distorted,rendered,true); panelImage.setImageUI(rendered); }
private void renderOutput(T in) { distortImage.apply(in,distorted); ConvertBufferedImage.convertTo(distorted,rendered,true); panelImage.setImageUI(rendered); }
private void renderPinhole() { if( distortImage == null ) return; imageRendered.reshape(pinholeModel.width,pinholeModel.height); distortImage.apply(imageFisheye,imageRendered); bufferedRendered = ConvertBufferedImage.checkDeclare( imageRendered.width,imageRendered.height,bufferedRendered,BufferedImage.TYPE_INT_RGB); ConvertBufferedImage.convertTo(imageRendered,bufferedRendered,true); }
private void rerenderPinhole() { // long before = System.nanoTime(); distortImage.apply(equi,pinhole); // long after = System.nanoTime(); // System.out.println("Rendering time "+(after-before)/1e6+" ms"); ConvertBufferedImage.convertTo(pinhole,buffPinhole,true); panelPinhole.setImageUI(buffPinhole); panelEqui.repaint(); }
private void rerenderPinhole() { // long before = System.nanoTime(); distortImage.apply(fisheye,pinhole); // long after = System.nanoTime(); // System.out.println("Rendering time "+(after-before)/1e6+" ms"); ConvertBufferedImage.convertTo(pinhole,buffPinhole,true); panelPinhole.setImageUI(buffPinhole); panelFisheye.repaint(); }
/** * Applies a pixel transform to a single band image. More flexible but order to use function. * * @deprecated As of v0.19. Use {@link FDistort} instead * * @param input Input (source) image. * @param output Where the result of transforming the image image is written to. * @param renderAll true it renders all pixels, even ones outside the input image. * @param transform The transform that is being applied to the image * @param interp Interpolation algorithm. */ public static <Input extends ImageGray<Input>,Output extends ImageGray<Output>> void distortSingle(Input input, Output output, boolean renderAll, PixelTransform2_F32 transform, InterpolatePixelS<Input> interp) { Class<Output> inputType = (Class<Output>)input.getClass(); ImageDistort<Input,Output> distorter = FactoryDistort.distortSB(false, interp, inputType); distorter.setRenderAll(renderAll); distorter.setModel(transform); distorter.apply(input,output); }
private void renderDistorted(BufferedImage buffered, T undistorted) { // if not enough points have been set it can blow up if( !control.isShowOriginal() && validTransform ) { distortImage.apply(undistorted, distorted); ConvertBufferedImage.convertTo(distorted, distortedBuff, true); } else { if( buffered != null ) distortedBuff.createGraphics().drawImage(buffered,0,0,undistorted.width,undistorted.height,null); else { ConvertBufferedImage.convertTo(undistorted, distortedBuff, true); } } BoofSwingUtil.invokeNowOrLater(new Runnable() { @Override public void run() { gui.setBufferedImage(distortedBuff); gui.repaint(); } }); }
/** * Provides recent images from all the cameras (should be time and lighting synchronized) and renders them * into an equirectangular image. The images must be in the same order that the cameras were added. * * @param cameraImages List of camera images */ public void render( List<T> cameraImages ) { if( cameraImages.size() != cameras.size()) throw new IllegalArgumentException("Input camera image count doesn't equal the expected number"); // avoid divide by zero errors by initializing it to a small non-zero value GImageMiscOps.fill(weightImage,1e-4); GImageMiscOps.fill(averageImage,0); for (int i = 0; i < cameras.size(); i++) { Camera c = cameras.get(i); T cameraImage = cameraImages.get(i); distort.setModel(c.equiToCamera); distort.apply(cameraImage,cameraRendered); /// sum up the total weight for each pixel PixelMath.add(weightImage,c.mask,weightImage); // apply the weight for this image to the rendered image GPixelMath.multiply(c.mask,cameraRendered,workImage); // add the result to the average image GPixelMath.add(workImage, averageImage, averageImage); } // comput the final output by dividing GPixelMath.divide(averageImage,weightImage,averageImage); }
/** * Applies a distortion to a {@link Planar} image. * * @deprecated As of v0.19. Use {@link FDistort} instead * * @param input Image being distorted. Not modified. * @param output Output image. modified. * @param distortion The distortion model * @param <Input> Band type. */ public static <Input extends ImageGray<Input>,Output extends ImageGray<Output>> void distortPL(Planar<Input> input , Planar<Output> output , ImageDistort<Input,Output> distortion ) { for( int band = 0; band < input.getNumBands(); band++ ) distortion.apply(input.getBand(band),output.getBand(band)); }
/** * Applies a pixel transform to a single band image. Easier to use function. * * @deprecated As of v0.19. Use {@link FDistort} instead * * @param input Input (source) image. * @param output Where the result of transforming the image image is written to. * @param transform The transform that is being applied to the image * @param interpType Which type of pixel interpolation should be used. BILINEAR is in general recommended * @param borderType Specifies how to handle image borders. */ public static <Input extends ImageGray<Input>,Output extends ImageGray<Output>> void distortSingle(Input input, Output output, PixelTransform2_F32 transform, InterpolationType interpType, BorderType borderType) { boolean skip = borderType == BorderType.SKIP; if( skip ) borderType = BorderType.EXTENDED; Class<Input> inputType = (Class<Input>)input.getClass(); Class<Output> outputType = (Class<Output>)input.getClass(); InterpolatePixelS<Input> interp = FactoryInterpolation.createPixelS(0, 255, interpType, borderType, inputType); ImageDistort<Input,Output> distorter = FactoryDistort.distortSB(false, interp, outputType); distorter.setRenderAll(!skip); distorter.setModel(transform); distorter.apply(input,output); }
@Override public void apply(Planar<Input> srcImg, Planar<Output> dstImg, GrayU8 mask ) { if( srcImg.getNumBands() != dstImg.getNumBands() ) throw new IllegalArgumentException("Number of bands must be the same. "+srcImg.getNumBands()+" vs "+dstImg.getNumBands()); int N = srcImg.getNumBands(); for( int i = 0; i < N; i++ ) { // save a little bit of CPU by only computing the mask once if( i == 0 ) layerDistort.apply(srcImg.getBand(i),dstImg.getBand(i),mask); else layerDistort.apply(srcImg.getBand(i),dstImg.getBand(i)); } }
@Override public void apply(Planar<Input> srcImg, Planar<Output> dstImg) { if( srcImg.getNumBands() != dstImg.getNumBands() ) throw new IllegalArgumentException("Number of bands must be the same. "+srcImg.getNumBands()+" vs "+dstImg.getNumBands()); int N = srcImg.getNumBands(); for( int i = 0; i < N; i++ ) { layerDistort.apply(srcImg.getBand(i),dstImg.getBand(i)); } }
@Override public void apply(Planar<Input> srcImg, Planar<Output> dstImg, int dstX0, int dstY0, int dstX1, int dstY1) { if( srcImg.getNumBands() != dstImg.getNumBands() ) throw new IllegalArgumentException("Number of bands must be the same. "+srcImg.getNumBands()+" vs "+dstImg.getNumBands()); int N = srcImg.getNumBands(); for( int i = 0; i < N; i++ ) { layerDistort.apply(srcImg.getBand(i),dstImg.getBand(i),dstX0, dstY0, dstX1, dstY1); } }
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); }}); }
private void undoRadialDistortion(BufferedImage image) { ConvertBufferedImage.convertFromMulti(image, origMS,true, GrayF32.class); for( int i = 0; i < origMS.getNumBands(); i++ ) { GrayF32 in = origMS.getBand(i); GrayF32 out = correctedMS.getBand(i); undoRadial.apply(in,out); } if( correctedMS.getNumBands() == 3 ) ConvertBufferedImage.convertTo(correctedMS,undistorted,true); else if( correctedMS.getNumBands() == 1 ) ConvertBufferedImage.convertTo(correctedMS.getBand(0),undistorted); else throw new RuntimeException("What kind of image has "+correctedMS.getNumBands()+"???"); }
private void undoRadialDistortion(BufferedImage image) { if( undoRadial == null ) return; ConvertBufferedImage.convertFrom(image,origMS,true); if( correctedMS.getNumBands() != origMS.getNumBands() ) correctedMS.setNumberOfBands(origMS.getNumBands()); correctedMS.reshape(origMS.width,origMS.height); for( int i = 0; i < origMS.getNumBands(); i++ ) { GrayF32 in = origMS.getBand(i); GrayF32 out = correctedMS.getBand(i); undoRadial.apply(in,out); } undistorted = ConvertBufferedImage.checkDeclare(origMS.width,origMS.height,undistorted,image.getType()); ConvertBufferedImage.convertTo(correctedMS,undistorted,true); }
/** * Applies the distortion. */ public void apply() { // see if the distortion class needs to be created again if( distorter == null ) { Class typeOut = output.getImageType().getImageClass(); switch( input.getImageType().getFamily() ) { case GRAY: distorter = FactoryDistort.distortSB(cached, (InterpolatePixelS)interp, typeOut); break; case PLANAR: distorter = FactoryDistort.distortPL(cached, (InterpolatePixelS)interp, typeOut); break; case INTERLEAVED: distorter = FactoryDistort.distortIL(cached, (InterpolatePixelMB) interp, output.getImageType()); break; default: throw new IllegalArgumentException("Unsupported image type"); } } distorter.setModel(outputToInput); distorter.apply(input,output); } }