Преобразование BufferedImage для Affine в Java - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь использовать openCV для выполнения аффинного преобразования:

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);
    }

Тип данных моего буферизованного изображения - 16 бит, поэтому USHORT. Поскольку для этого требуется использование Mat, мне нужно преобразовать его (если кто-то не знает, как просто выполнить преобразование моего буферизованного изображения USHORT?). Я пытаюсь выполнить преобразование:

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;
    }

При выполнении преобразования после преобразования появляется сообщение об ошибке:

java.lang.UnsupportedOperationException: Тип данных Mat несовместим: 2

Это происходит в строке, содержащей HighGui.waitKey(0);, которая указывает на ImageIcon icon = new ImageIcon(toBufferedImage(win.img)); внутри HighGui.class, который указывает на метод toBufferedImage:

public static Image toBufferedImage(Mat m) {
    int type = BufferedImage.TYPE_BYTE_GRAY;

    if (m.channels() > 1) {
        type = BufferedImage.TYPE_3BYTE_BGR;
    }

    int bufferSize = m.channels() * m.cols() * m.rows();
    byte[] b = new byte[bufferSize];
    m.get(0, 0, b); // get all the pixels
    BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);

    final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    System.arraycopy(b, 0, targetPixels, 0, b.length);

    return image;
}

Ошибкапроисходит в строке m.get(0, 0, b);

Так что, если я правильно понимаю, он пытается преобразовать обратно в буферизованное изображение после преобразования, но с типом данных Byte, и это не удается. Кто-нибудь есть какие-либо предложения о том, как заставить эти преобразования работать без потери разрешения или данных?

Я знаю, что есть много похожих вопросов, но я не мог найти ответ, который подходит для моей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...