• 2006-09-06

    用matlab读取16位灰度bmp图像(续) - [Matlab]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://darnshong.52blog.net/logs/2187046.html

    昨天导师让我读取一14位灰度的bmp图像。因为我原来是在matlab下整过14位灰度bmp图像的。我用原来写的matlab程序来读取这种图像。但是与正确的数据总是偏差一点。究竟是哪里出了问题。费了好大的劲还是没找到原因。是不是我的原理有问题?对了,可以看一下matlab是如何读取16位的bmp图像的。因为matlab在读取完16位bmp图像之后还得将其转化为RGB三分量。如果知道了matlab是如何将16位数据转化为RGB三分量的话,将RGB三分量复原为16位的数据也就不复杂了。经过长时间的仔细查找,终于在readbmpdata.m这个文件中找到了matlab将16位数据转化为RGB三分量的那段代码。代码如下:
    RGB(1:abs(height), 1:width, 1) = uint8(bitslice(X,11,15));
    RGB(:,:,2) = uint8(bitslice(X,6,10));
    RGB(:,:,3) = uint8(bitslice(X,1,5));

    %Scale data for display
    RGB = bitor(bitshift(RGB,3),bitshift(RGB,-2));

    原来RGB三分量是各自从16位的数据X中取其中的5位。将这5位的数据左移3位与这5位数据右移2位相或,最终得到了8位的数据。如此的话,将RGB三分量复原成16位的数据就不困难了。

    原来的程序是这样的:
     function b=read16graybmp(filename)
    if(nargin~=1)
        error('Need 1 parameters!');
    end;0
      i=0:2^5-1;index5=floor(i*255.99/(2^5-1));%for 5bits
     value5(index5 1)=0:2^5-1;
     a=imread(filename);
      b1=value5(a(:,:,1) 1);
      b2=value5(a(:,:,2) 1);
      b3=value5(a(:,:,3) 1);
     b=bitshift(uint16(b1),10) bitshift(uint16(b2),5) uint16(b3);
    如果按照matlab将16位数据转化成RGB三分量的原理的话,程序可以是这样:
     function b=read16graybmp(filename)
    if(nargin~=1)
        error('Need 1 parameters!');
    end;0
      i=0:2^5-1;index5=floor(i*255.99/(2^5-1));%for 5bits
     value5(index5 1)=0:2^5-1;
      a=imread(filename);
      b1=bitshift(a(:,:,1),-3);
      b2=bitshift(a(:,:,2),-3);
      b3=bitshift(a(:,:,3),-3); 
      b=bitshift(uint16(b1),10) bitshift(uint16(b2),5) uint16(b3);
    但是仔细想想,两者的原理是相类似的。如果在运行
    i=0:2^5-1;index5=floor(i*255.99/(2^5-1));
    i8=uint8(i);index55=bitor(bitshift(i8,3),bitshift(i8,-2));
    a=index5==index55;find(a==0)
    结果显示index5与index55是一样的。但原来写的程序读出来的数据有的就是有偏差,究竟是怎么回事呢。费了好大的劲才找到问题。原来a=imread(filename);执行后,a的类型是uint8,如果a是255的话,那么加1等于0而不是256,问题就出在这里。于是,我们可以将原来的程序稍微改动一下就可以了。
     function b=read16graybmp(filename)
    if(nargin~=1)
        error('Need 1 parameters!');
    end;0
      i=0:2^5-1;index5=floor(i*255.99/(2^5-1));%for 5bits
     value5(index5 1)=0:2^5-1;
     a=double(imread(filename));
      b1=value5(a(:,:,1) 1);
      b2=value5(a(:,:,2) 1);
      b3=value5(a(:,:,3) 1);
     b=bitshift(uint16(b1),10) bitshift(uint16(b2),5) uint16(b3);

    参考:用matlab读取16位、14位、12位灰度bmp图像(*.bmp)


    收藏到:Del.icio.us




    评论

  • 你好!
    从你的文章可以看出你是使用MATLAB的高手,我以前从来没有用过这个软件,我现在急需用MATLAB做基于SVD的数字水印(嵌入和提取水印),希望你能指教一下.
    我的联系方式是email:luanyiting!@hotmail.com
    希望能尽快收到你的回信
    万分感激!

发表评论

您将收到博主的回复邮件
记住我