Error converting to Mat and performing affineWarp

asked 2019-10-03 04:24:26 -0500

Zyzyx gravatar image

I'm trying to use openCV to perform an affine-transformation on a BufferedImage. Datatype of my buffered image is 16 bits, so a USHORT. Since affine transformation requires the use of Mat, I need to convert to it (unless someone knows a way to simply perform the transformation on my USHORT buffered image?). I attempt the conversion:

public static Mat BufferedImageToMat(BufferedImage bi) {
      Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_16U);
      short[] data = ((DataBufferUShort) bi.getRaster().getDataBuffer()).getData();
      mat.put(0, 0, data);
      return mat;
    }

I then try the transformation and get an error:

private static void GeometricTransforms(ArrayList<MyCoordinates> mc, Sequence seq) {
        System.out.println("DATATYPE: " + seq.getLastImage().getDataType_().toString());

         Mat src = null;
        src = BufferedImageToMat(seq.getLastImage());


        if (src.empty()) {
            System.err.println("Cannot read image");
            System.exit(0);
        }

        Point[] srcTri = new Point[3];
        srcTri[0] = new Point( mc.get(0).getX(), mc.get(0).getY() );
        srcTri[1] = new Point( mc.get(1).getX(), mc.get(1).getY() );
        srcTri[2] = new Point( mc.get(2).getX(), mc.get(2).getY() );
//        srcTri[3] = new Point( mc.get(3).getX(), mc.get(3).getY() );
        Point[] dstTri = new Point[3];
        dstTri[0] = new Point( 0, 0 );
        dstTri[1] = new Point( 128, 0 );
        dstTri[2] = new Point( 128, 98 );
//        dstTri[3] = new Point( 0, 98 );

        System.out.println(dstTri[0] + ", " + dstTri[1] + ", " + dstTri[2]);

        Mat warpMat = Imgproc.getAffineTransform( new MatOfPoint2f(srcTri), new MatOfPoint2f(dstTri) );
        Mat warpDst = Mat.zeros( 98, 128, src.type() );
        Imgproc.warpAffine( src, warpDst, warpMat, warpDst.size() );
        Point center = new Point(warpDst.cols() / 2, warpDst.rows() / 2);
        double angle = -50.0;
        double scale = 0.6;
        Mat rotMat = Imgproc.getRotationMatrix2D( center, angle, scale );
        Mat warpRotateDst = new Mat();
        Imgproc.warpAffine( warpDst, warpRotateDst, rotMat, warpDst.size() );
        HighGui.imshow( "Source image", src );
        HighGui.imshow( "Warp", warpDst );
        HighGui.imshow( "Warp + Rotate", warpRotateDst );
        HighGui.waitKey(0);
        System.exit(0);
    }

java.lang.UnsupportedOperationException: Mat data type is not compatible: 2 at org.opencv.core.Mat.get(Mat.java:1045) at org.opencv.highgui.HighGui.toBufferedImage(HighGui.java:68) at org.opencv.highgui.HighGui.waitKey(HighGui.java:143)

So if I understand this correctly, it tries to convert back to a buffered image after the transformation but with a data-type of Byte, and this fails. Does anyone have any suggestion on how to make these conversions work out, without any loss in resolution or data?

edit retag flag offensive close merge delete

Comments

looks more, like warpAffine can handle your ushort (2) Mat, but imshow() / waitKey() fails on it.

berak gravatar imageberak ( 2019-10-03 04:36:13 -0500 )edit