如何使用 opencv 和 Java 将存储在字节数组中的原始图像转换为 rgb 图像

How convert a raw image stored in a byte array to a rgb image with opencv and Java

我正在使用 id3Fingerprint sdk 和 OpenCV 预览指纹扫描仪。如果我只显示 id3fingerprint sdk 的预览,一切都很好,但是如果我将它加载到 OpenCV 的 Mat 对象以便在图像中绘制一些矩形,那么: 1.- 指纹以正确的形式显示,但矩形在随机 x,y 位置显示为线条或像素。 2.- 矩形以正确的形式显示,但显示指纹 "blured"(看附图)。fingerprints are blured

我想,我的问题是当我将原始灰度图像(来自 id3fingerprint sdk 的字节数组)转换为 RGB 或 RGBA 图像时。

private void showPreview2(FingerImage image){
    int height = 750;
    int width = 750;
    int currentWidth = 0;
    int currentHeight = 0;
    try {
        currentWidth = image.getWidth();
        currentHeight = image.getHeight();
    } catch (FingerException ex) {
        Logger.getLogger(CallingID3Example.class.getName()).log(Level.SEVERE, null, ex);
    }
    byte[] pixels = image.getPixels();
    Mat dest = new Mat(); 
    Mat source = new Mat(); 
    Mat source2 = null;
        source2 = new Mat(currentWidth, currentHeight, CvType.CV_8UC1);
        source2.put(0, 0, pixels);
        MatOfByte pix = new MatOfByte();
        Imgcodecs.imencode(".bmp", source2, pix);
        source2.put(0, 0, pix.toArray());

        Imgproc.cvtColor(source2, source, Imgproc.COLOR_GRAY2RGBA);
        try {
            int i=0;
            for(FingerImage finger : image.getSegments()){
                Scalar color;
                        color = new Scalar(0, 250,0);
                FingerBounds bound = image.getSegmentBounds()[i];
                Imgproc.rectangle(source, new Point(bound.topLeft.x, bound.topLeft.y),      new Point(bound.bottomRight.x, bound.bottomRight.y), color, 3);
                double[] pixelTest;
                pixelTest = source.get(bound.topLeft.x, bound.topLeft.y);
                i++;
            }
        } catch (FingerException ex) {
            Logger.getLogger(CallingID3Example.class.getName()).log(Level.SEVERE, null, ex);
        }
        gc = canvas.getGraphicsContext2D();

        WritableImage writableImage = loadImage(source);

        imageView.setImage(writableImage);

}

private WritableImage loadImage(Mat matrix) {
  // Encoding the image
  MatOfByte matOfByte = new MatOfByte();
    Imgcodecs.imencode(".bmp", matrix, matOfByte);
  // Storing the encoded Mat in a byte array
  byte[] byteArray = matOfByte.toArray();

  // Displaying the image
  InputStream in = new ByteArrayInputStream(byteArray);
  BufferedImage bufImage = null;
    try {
        bufImage = ImageIO.read(in);
    } catch (IOException ex) {
    }
  // Creating the Writable Image
  WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
  return writableImage;
}

感谢您的回答。

您可以尝试这样的操作:

    // You need to know width/height of the image
    int width = 0;
    int height = 0;
    byte[] imageSrc = null;//


    // Convert 8bit greyscale byte array to RGBA byte array.
    byte[] imageRGBA = new byte[imageSrc.length * 4];
    int i;
    for (i = 0; i < imageSrc.length; i++) {
        imageRGBA[i * 4] = imageRGBA[i * 4 + 1] = imageRGBA[i * 4 + 2] = ((byte) ~imageSrc[i]);

        // Invert the source bits
        imageRGBA[i * 4 + 3] = -1;// 0xff, that's the alpha.
    }


    // Convert RGBA byte array to PNG 
    int samplesPerPixel = 4;
    int[] bandOffsets = {0,1,2,3}; // RGBA order

    byte[] bgraPixelData = new byte[width * height * samplesPerPixel];

    DataBuffer buffer = new DataBufferByte(bgraPixelData, bgraPixelData.length);
    WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null);

    ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);

    BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);

    System.out.println("image: " + image); // Should print: image: BufferedImage@<hash>: type = 0 ...

    ImageIO.write(image, "PNG", new File(path));

更新

在图像上绘制矩形: BufferedImage 图像 = ...

    Graphics2D graph = img.createGraphics();
    graph.setColor(Color.BLACK);
    graph.fill(new Rectangle(x, y, width, height));
    graph.dispose();

    ImageIO.write(image, "PNG", new File(path));