Imagemagick 从单通道12位little endian原始二进制数据转换

Imagemagick 从单通道12位little endian原始二进制数据转换,imagemagick,imagemagick-convert,Imagemagick,Imagemagick Convert,我有一个原始二进制图像文件,其中每个像素由12位数据(灰度)组成。例如,原始文件中的前四个像素: 0x0 0xC0 0x1 0x05 0x2 0x5C 0x3 0xC0 0x4 0x05 0x5 0x5C 这对应于值为0x5C0(小端点)的4个像素值 不幸的是,使用以下命令: convert -size 384x184 -depth 12 gray:frame_0.raw out.tiff 错误解释像素值(大端),导致像素值0xC00 0x55C 0xC00 0x55C 我尝试了

我有一个原始二进制图像文件,其中每个像素由12位数据(灰度)组成。例如,原始文件中的前四个像素:

0x0  0xC0
0x1  0x05
0x2  0x5C
0x3  0xC0
0x4  0x05
0x5  0x5C
这对应于值为0x5C0(小端点)的4个像素值

不幸的是,使用以下命令:

convert -size 384x184 -depth 12 gray:frame_0.raw out.tiff
错误解释像素值(大端),导致像素值
0xC00 0x55C 0xC00 0x55C

我尝试了选项
-endian LSB
-endian MSB
,但不幸的是,它们只更改输出字节顺序,而不更改输入字节顺序


如何进行转换以将原始图像作为12位小端数据打开?

我对此进行了快速尝试,但我没有测试数据,但它应该非常接近并易于检测图像的错误:

// pad12to16.c
// Mark Setchell
// Pad 12-bit data to 16-bit
//
// Compile with:
// gcc pad12to16.c -o pad12to16
//
// Run with:
// ./pad12to16 < 12-bit.dat > 16-bit.dat

#include <stdio.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/types.h>

#define BYTESPERREAD    6
#define PIXPERWRITE     4

int main(){
    unsigned char  buf[BYTESPERREAD];
    unsigned short pixel[PIXPERWRITE];

    // Read 6 bytes at a time and decode to 4 off 16-bit pixels
    while(read(0,buf,BYTESPERREAD)==BYTESPERREAD){
       pixel[0] = buf[0] | ((buf[1] & 0xf) << 8);
       pixel[1] = (buf[2] << 4) | ((buf[1] & 0xf0) >> 4);
       pixel[2] = buf[3] | ((buf[2] & 0xf) << 8);
       pixel[3] = (buf[5] << 4) | ((buf[4] & 0xf0) >> 4);
       write(1,pixel,PIXPERWRITE*2);
    }
    return 0;
}
//pad12to16.c
//马克·塞切尔
//将12位数据填充到16位
//
//编译时使用:
//gcc pad12to16.c-o pad12to16
//
//运行时使用:
//./pad12to16<12位.dat>16位.dat
#包括
#包括
#包括
#包括
#定义字节PerRead 6
#定义PIXPERWRITE 4
int main(){
无符号字符buf[BYTESPERREAD];
无符号短像素[PIXPERWRITE];
//一次读取6个字节,并解码为4个16位像素
while(read(0,buf,BYTESPERREAD)=BYTESPERREAD){
像素[0]=buf[0]|((buf[1]&0xf)4);
像素[2]=buf[3]|((buf[2]&0xf)4);
写入(1,像素,像素写入*2);
}
返回0;
}
所以你会运行这个(我认为):

/pad12to16<12位.dat |转换-尺寸384x184-深度16灰色:-result.tif

Mark的答案是正确的,因为您需要使用一些外部工具来整理数据流。通常在处理12位深度时会有一些填充。在提供的示例blob中,我们看到每对像素共享一个公共字节。拆分共享字节并将内容转移到何处的任务相当简单。这个答案是对马克的答案的恭维,并认为这个答案也可以使用

//my12bit\u convert.c
#包括
#包括
#包括
#包括
静态异常类型服务器;
#定义前导半(x)((x>>4)和0xF)
#定义下半部分(x)(x&0xF)
#定义为双(x)((双)x/(双)0xFFF);
#如果(x==MagickFalse){fprintf(stderr,“%s\n”,MagickGetException(y,&serverty)),则define是_OK(x,y);}
int main(int argc,const char*argv[]{
//原型变量
int
我
tmp_像素[2];
双像素缓冲区;
尺寸
w=0,
h=0,
总计=0,
迭代器=0;
ssize\u t
x=0,
y=0;
常量字符
*路径=空,
*输出=空;
无符号字符读取像素块[3];
文件*fh;
魔杖*魔杖;
像素棒*pwand;
magickboolean类型ok;
//迭代参数并收集大小、输入和输出。
对于(i=1;i0x05C0

tmp_像素[0]=后半部分(读取_像素_块[1])我可能错了,但我不相信ImageMagick可以处理那样的12位数据。我担心您可能需要自己编写一个小的
C
程序来提取和填充数据-我在这里做了类似的事情…您能提供一个指向示例
.raw
文件的链接吗?您已经超越了自己!:-)
./pad12to16 < 12-bit.dat | convert -size 384x184 -depth 16 gray:- result.tif 
LLVM_CFLAGS=`MagickWand-config --cflags`
LLVM_LDFLAGS=`MagickWand-config --ldflags`
clang $LLVM_CFLAGS $LLVM_LDFLAGS -o my12bit_convert my12bit_convert.c
./my12bit_convert -size 384x184 frame_0.raw out.tiff