【问题标题】:Matlab : convert a uint8 matrix (made of 0 and 1) to export as binary dataMatlab:将 uint8 矩阵(由 0 和 1 组成)转换为二进制数据
【发布时间】:2023-03-18 06:42:01
【问题描述】:

我的问题:

我在 Matlab 中有一个由零和一组成的 1920x1080 uint8 矩阵。让我们称之为我的“形象”。我想要做的是将此图像导出为二进制,这意味着输出的每个字节都应包含 8 个像素的信息。 简而言之:我想要每像素 1 位。

如果我理解得很好,我不能在 Matlab 中使用“logical(...)”函数将其转换为二进制,因为逻辑仍然以 8 位的形式存储在内存中(尽管它们的值只能是 0 或 1当然)。

我为什么需要这个?

我想通过接受特定格式图像的“.dll”导出图像(以便更快地传输到 USB 设备)。

输出格式:

这是“.dll”所期望的:(1 字节 = 8 个连续位)

  • 图像从左到右读取,然后从上到下(通常的约定)
  • 每个数据字节代表 8 个像素,例如
    • (第一个字节)= [px8|px7|...|px1]
    • (第二个字节)= [px16|px15|...|px9]
    • 等等。
  • 请注意,图像的每一行都有 1920 个像素(可以除以 8,1920/8=240),因此每行图像有 240 个字节

我的问题:

我应该如何重新组织数据?我想这取决于 Matlab 如何将数据存储在内存中(然后将其发送到任何“.dll”)?我不知道...

如果没有预期的记忆技巧,这是我将使用的代码。我们的想法是每 8 个像素并以正确的顺序用它们构建一个 8 位值,例如这些像素值 (1 0 0 0 0 0 1 0) 将变为 65(以十进制表示)。然后我会将新矩阵发送到“.dll”并希望它有效。

FinalImage=zeros(1920,240); % 240 = number of bytes per line
for myRow=1:1080
    for myByte=1:240 
        currentByte=0;
        for myBit=0:7
            currentByte=currentByte + 2^(7-myBit) * Image(myRow, 1 + 8*(myByte-1) + myBit );
        end
        FinalImage(myRow, myByte) = currentByte;
    end
end

解决办法:

Divakar的帮助下,我终于忘记了循环,更喜欢这个简单的代码:

% convert every 8 pixels (values 0 or 1) in a row to one single pixel (value 0 to 255)
% (bi2de option used : "left most significant bit" in my case)
% (make sure the width of your image is a multiple of 8)

vect=bi2de(reshape(input_img',8,[])','left-msb');
img=reshape(vect,img_width/8,[])';

这个解决方案可能会对其他人有所帮助,总有一天!

【问题讨论】:

    标签: matlab dll binary-data


    【解决方案1】:

    假设input_image是输入二进制矩阵,output_dll_filepath是输出dll文件的路径,你可以试试这个cell-array方法-

    代码

    %// Convert to 8-bit data
    [M,N] = size(input_image)
    cell1 = mat2cell(input_image,ones(1,M),8.*ones(1,N/8))
    output_data = cellfun(@(x) bin2dec(num2str(fliplr(x),'%1d')),cell1);
    output_data = reshape(output_data',[],1)
    
    %// Write the 8-bit data as a dll file
    fid = fopen(output_dll_filepath , 'w');
    fwrite(fid, output_data, 'uint8');
    fclose(fid);
    

    或者使用 -

    output_data = bin2dec(fliplr(num2str(reshape(input_image',8,[])','%1d')))
    

    然后使用之前使用的Write the 8-bit data as a dll file


    或者只是这个 -

    fid = fopen(output_dll_filepath , 'w');
    fwrite(fid, reshape(input_image',8,[]), 'ubit1');
    fclose(fid);
    

    【讨论】:

    • 感谢您的回答。我错误地说我使用了一个 dll,实际上我使用了一个链接到 dll 的库。我用 calllib(...) 从 Matalb 调用它的函数。我的输出数据应该是这个 calllib 调用的参数。 (所以 fopen 和 fwrite 不适合这种情况)无论如何,您的第二个解决方案对我帮助很大,但是对于 1080*1920 矩阵(我有 1024 个这些矩阵要加载),代码仍然很慢。我继续寻找。 :)
    • @GhislainBugnicourt 第二个解决方案必须很快,因为它避免了早期方法中使用的元胞数组,但是如果您正在使用 1024 个这样的矩阵,那么您将多次调用这样的代码并执行 1024对慢速硬盘的 I/O 操作。您不能将所有这 1024 个矩阵的组合写入一个文件吗?
    • 我终于做了几处更改(包括将所有矩阵与 cat() 函数结合起来,然后按照您的建议将它们在一个块中发送到库),但问题的关键是这一行:vect=bi2de(reshape(input_img',8,[])','left-msb');.它改编自您的答案,因此我选择了您的解决方案,但我在问题本身中添加了真正的答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2015-06-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多