2

我正在尝试在 Matlab 中对数据库中的一些图像数据进行模拟。图像数据来自 java,输出为 base64 编码的字节数组。我不熟悉 [java image] 格式。但是,我根据与我一起工作的人编写的一些 java 编写了以下 Matlab 代码。它们遵循相同的基本轮廓,Java 代码能够很好地读取图像。Matlab 代码如下所示:

function [ result ] = queryDb( theQuery )
  conn   = database( ... ); % connect to the database
  result = fetch( exec( conn, theQuery ) );
  result = result.Data;

  close( conn );
end

data = queryDb( 'sql query to get the data' );
data = uint8( data{1,1} );
data = org.apache.commons.codec.binary.Base64.decodeBase64( data );
data = uint8( 127 + data ); % the base64 decoder returns signed int8

import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;

dataStream    = ByteArrayInputStream( data );
bufferedimage = ImageIO.read( dataStream );

经检查bufferedimage,它是一个空数组,double而不是 javaBufferedImage实例。

我进行了一些测试dataStream,看看它是否符合预期;类似于以下内容的迷你单元测试:

for jj = 1:10
  for kk 1:10
    assert( dataStream.read() == data(kk) );
  end;

  dataStream.reset();
end;

它检查了,所以这让我相信问题出在 ImageIO 或我对它的使用上。

不幸的是,我发现的使用 ImageIO(以及其中一些其他 API)的示例都没有以我在此处概述的方式(即在 Matlab 中)使用。

此代码java.io.ByteArrayInputStream相同的方式使用——从某种意义上说,提供的数据是一个字节数组。

这段代码本质上就是我想要做的——将 java 图像转换为 Matlab 数组。不幸的是,他们通过获取 Matlab 图像,将其转换为 java 图像,然后将其转回来作弊。

此代码使用 ImageIO,但它是通过从文件流中读取来实现的。我尝试将数据写入文件然后在 using 中读取它java.io.File,但无论哪种方式我都得到相同的结果。

所以,我很茫然。

4

1 回答 1

0

问题中概述的方法有效......我唯一与上面的代码有任何不同的是我没有将 127 添加到 uint8 数组中:

% Do all the imports
% sql query to get the data
dataStream    = ByteArrayInputStream( decodeBase64( rows.data{1} ) );
bufferedImage = ImageIO.read( dataStream );
[w h] = deal( theWidth, theHeight );
imageData     = uint8( bufferedImage.getData.getPixels( 0,0,w,h,[] ) );
imageData     = permute( reshape( imageData, [3 w h] ), [2 3 1] );

imshow( imageData );
% voila

编辑合并文本 @kchja链接到,以防该链接失效:

主题:如何将“Java Image”对象转换为 MATLAB 图像矩阵?

问题描述:IM2JAVA函数可用于将MATLAB图像转换为Java图像。我想将 Java 图像转换为 MATLAB 图像。

解决方案:没有将Java图像转换为MATLAB图像的内置函数。但是,使用 Java API,您可以从 Java 图像中提取数据并将其存储为矩阵,这是 MATLAB 的图像表示。

下面是一个将 MATLAB 图像转换为 Java 并返回到 MATLAB 图像的示例。此示例中使用的图像是 MATLAB 演示的一部分,位于 MATLAB 路径中。在此示例中,Java 类“Raster”的“getPixels”函数返回图像的 RGB 值。

根据 Java 映像的格式,可能需要额外的工作。Java 图像可以以多种格式中的一种存储;“getPixels”函数以该格式返回像素数据。有关详细信息,请参阅http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/Raster.html上的 java.awt.image.Raster 类的 javadoc 页面

% create java image
I = imread('office_3.jpg');
javaImage = im2java(I);

% get image properties
H=javaImage.getHeight;
W=javaImage.getWidth;

% repackage as a 3D array (MATLAB image format)
B = uint8(zeros([H,W,3]));
pixelsData = uint8(javaImage.getBufferedImage.getData.getPixels(0,0,W,H,[]));
for i = 1 : H
base = (i-1)*W*3+1;
B(i,1:W,:) = deal(reshape(pixelsData(base:(base+3*W-1)),3,W)');
end

% display image
imshow(B);

以下是其他两种实现方式(以更优化的方式):

示例 1:(更快的执行)

pixelsData = reshape(typecast(jImage.getData.getDataStorage, 'uint8'), 4, w, h);
imgData = cat(3, ...
        transpose(reshape(pixelsData(3, :, :), w, h)), ...
        transpose(reshape(pixelsData(2, :, :), w, h)), ...
        transpose(reshape(pixelsData(1, :, :), w, h)));

示例 2:

imgData = zeros([H,W,3],'uint8');
pixelsData = reshape(typecast(javaImage.getBufferedImage.getData.getDataStorage,'uint32'),W,H).';
imgData(:,:,3) = bitshift(bitand(pixelsData,256^1-1),-8*0);
imgData(:,:,2) = bitshift(bitand(pixelsData,256^2-1),-8*1);
imgData(:,:,1) = bitshift(bitand(pixelsData,256^3-1),-8*2);
于 2011-11-16T06:58:38.397 回答