DirectShow和Windows不支持12位和16位灰度位图。LEAD已经定义了LGRY视频格式,以便使用DirectShow架构使用这种位图。这在DICOM滤波器中用于生成每像素超过8位的灰度视频。
当描述压缩的12/16位数据时,通过将media子类型设置为FORMAT_LGRYVideoInfo来指示媒体类型格式使用LGRYVideoInfo结构。当描述未压缩的12/16位数据时,通过将biccompression设置为LGRY来指示媒体类型格式使用LGRYVideoInfo结构。但即使在这种情况下,最好也将媒体子类型设置为FORMAT_LGRYVideoInfo。
下面的定义语句和结构可以在
静态GUID FORMAT_LGRYVideoInfo = {0x48799704, 0x2735, 0x4be6, {0xa0, 0xce, 0xdd, 0xc6, 0x2c, 0x25, 0xa4, 0xf2}};
媒体类型的formattype成员必须设置为FORMAT_LGRYVideoInfo(或ltmmFORMAT_LGRYVideoInfo),以指示使用LGRYVIDEOINFO结构来描述12位或16位压缩数据。没有必要将formattype设置为表示未压缩的12/16位数据,但建议即使对于未压缩的数据也这样做。
请注意: FORMAT_LGRYVideoInfo在LGRYType.h中定义,而ltmmFORMAT_LGRYVideoInfo在ltmm.h中定义。
类型定义结构体
{
矩形rcSource;
矩形rcTarget;
DWORD dwBitRate;
DWORD dwBitErrorRate;
REFERENCE_TIME AvgTimePerFrame;
LGRYINFOHEADER bmiHeader;
RGBQUAD bmiColors [65536];
} LGRYVIDEOINFO, FAR*pLGRYVIDEOINFO;
描述灰度视频格式:
成员 |
描述 |
rcSource |
要使用的图像部分 |
rcTarget |
视频的目标位置 |
dwBitRate |
近似比特数据率 |
dwBitErrorRate |
这个流的误码率 |
AvgTimePerFrame |
每帧平均时间(100ns单位) |
bmiHeader |
包含灰度图像信息的结构。 |
bmiColors |
重新映射查找表(LUT)。这是可选的。该字段被忽略,除非bmiHeader。biClrUsed是非零的。 |
类型定义结构体tagLGRYINFOHEADER
{
* BITMAPINFOHEADER字段*/
DWORD biSize;
长biWidth;
长biHeight;
单词双翼飞机;
单词biBitCount;
DWORD biCompression;
DWORD biSizeImage;
长biXPelsPerMeter;
长biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
/*仅针对LGRY格式的字段*/
长biLowBit;
长biHighBit;
长biMinVal;
长biMaxVal;
长biWindowWidth;
长biWindowCenter;
双biRescaleIntercept;
双biRescaleSlope;
DWORD biFlags;
长nReserved1;
长nReserved2;
长nReserved3;
} LGRYINFOHEADER, FAR*pLGRYINFOHEADER;
描述灰度图像。
成员 |
描述 |
biSize |
这个结构的大小。应该是sizeof(LGRYINFOHEADER)。 |
biWidth |
视频宽度。 |
biHeight |
使用正值指定自顶向下的图像。这与Windows对未压缩RGB图像的约定相反。 |
双翼飞机 |
应该是1 |
biBitCount |
应该是12或16岁: |
biCompression |
应该是mmioFOURCC('L','G','R','Y')来表示未压缩的数据。 应该是mmioFOURCC('L','j','p','g')来表示无损的JPEG数据。 应该是mmioFOURCC('J','P','E','G')或mmioFOURCC('M','J','P','G')来表示有损JPEG数据。 当使用JPEG数据时,将格式类型设置为FORMAT_LGRYVideoInfo或ltmmFORMAT_LGRYVideoInfo。 |
biSizeImage |
以字节为单位的图像大小。每行的大小需要是4字节的倍数,因此可能需要填充。计算这个字段正确的公式是:biSizeImage = ((((biWidth * biBitCount) + 31) & ~31) / 8) * abs(biHeight) |
biXPelsPerMeter |
指定水平分辨率,单位为像素/米。 |
biYPelsPerMeter |
指定垂直分辨率,单位为像素/米。 |
biClrUsed |
如果LUT不存在,则为0。在本例中,不使用/不需要bmiColors字段。 = 0,如果有LUT。在本例中,bmiColors包含LUT。biClrUsed应该等于1<<(biHighBit - biLowBit + 1) |
biClrImportant |
目前未使用。将此值设置为0 |
biLowBit |
像素数据的低位(0 <= biLowBit <= biHighBit <= biBitCount-1)。 |
biHighBit |
高位用于像素数据。 |
biMinVal |
只有像素数据的最小值(忽略非像素位)。 |
biMaxVal |
仅为像素数据的最大值(忽略非像素位)。 |
biWindowWidth |
DICOM窗口宽度。这可以用来重新生成LUT。 |
biWindowCenter |
DICOM窗口中心。这可以用来重新生成LUT。 |
biRescaleIntercept |
DICOM重新调整拦截。这可以用来重新生成LUT。 |
biRescaleSlope |
DICOM调整坡度。这可以用来重新生成LUT。 |
biFlags |
指示哪些字段是有效的。可能的值有: LGRY_RESCALE_VALID [0x0001]如果设置,则biRescaleIntercept和biRescaleSlope有效 LGRY_WINDOW_VALID [0x0002]如果设置,则biWindowSize和biWindowCenter有效 LGRY_BITRANGE_VALID [0x0004]如果设置,则biLowBit和biHighBit有效 LGRY_MINMAX_VALID [0x0010]如果设置,则biMinVal和biMaxVal有效 LGRY_LUT_ISGENERATED [0x0020]如果有LUT:如果设置,则从有效的l灰色特定字段生成LUT。如果不设置,则不能从其他LGRY字段重新生成LUT。在这种情况下,需要将LUT保存在文件中。 LGRY_LUT_ISGRAYSCALE [0x0040]如果存在LUT并且设置了此标志,则LUT仅包含灰度值。设置此标志是为了避免每次都通过LUT来检测LUT是否只包含灰度颜色。 LGRY_LUT_ISCOLOR [0x0080]如果存在LUT并且设置了此标志,则LUT包含非灰度值。设置此标志是为了避免每次都通过LUT来检测LUT是否只包含灰度颜色。 LGRY_LUT_COLORMASK [0x00C0]这不是一个标志。它是一个MASK,可以用来检测LUT是彩色的、灰度的还是未知的。 |
nReserved1 |
保留以备将来使用。 |
nReserved2 |
保留以备将来使用。 |
nReserved3 |
保留以备将来使用。 |
12位数据被打包:每2个像素占用3个字节。
例如,如果你有(2)个12位值,它们的十六进制值是0xABC和0xDEF,它们将像这样存储在内存中:0xBC 0xFA 0xDE
这种打包的优点是,您可以通过一次读取和一次逻辑操作在Intel处理器上获得每个值(第一个值为0xFFF的“and”,第二个值为右移4位)。
以下宏可用于处理12位打包数据(请记住,这些是C多行宏,重要的是它们在行尾有“\”):
//指针自增的helper宏
#define PTR_INC(p) ((BYTE*)p)+1)
//读取第一个12位值
#define GET12_0(p) ((*(WORD*)p) & 0xFFF)
//读取第二个12位值
#define GET12_1(p) ((*(WORD*)PTR_INC(p)) >> 4)
//写入两个12位的值
#定义PUT12(p, val0, val1) *(WORD*)p = (((val0) & 0xFFF) |
((WORD)(val1) << 12));\
((BYTE*)p)[2] = ((DWORD)(val1) >) > 4)
//写入第一个12位值
#定义PUT12_0 (p, val0) *(字*)p =((*(字*)(p) & 0 xf000) | \
((val0) & 0 xfff))
//写入第二个12位值
#定义PUT12_1(p, val1) *(WORD*)PTR_INC(p) = \
(*(WORD*)PTR_INC(p) & 0xF) | \
((WORD)(val1) << 4))
下面的示例描述了如何设置各种字段来描述灰度16位数据,其中只使用低10位:
LGRYVIDEOINFO信息;/ *警告:做不把这在堆栈上,因为它非常大*/
info.bmiHeader.biSize =运算符(LGRYINFOHEADER);
info.bmiHeader.biWidth = VideoWidth;
info.bmiHeader.biHeight = VideoHeight;/*应该是正数为正常(未翻转视频)*/
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 16;/*我有16位每像素,虽然只有低10位包含有用的数据*/
info. bmiheader . biccompression = mmioFOURCC('L', 'G', 'R', 'Y');
info.bmiHeader.biSizeImage = (((VideoWidth * 2) + 3) & ~3) * VideoHeight;
info.bmiHeader.biClrUsed = 0;/*没有LUT */
info. bmiheader . biclimportant = 0;/*现在不使用。集这价值到0 */
/*仅针对LGRY格式的字段*/
info.bmiHeader.biLowBit = 0;/*低位为像素数据(0 <= biLowBit <= biHighBit <= biBitCount-1) */
info.bmiHeader.biHighBit = 9;/* 10-1 = 9。高一些为像素数据。* /
info.bmiHeader.biFlags = LGRY_BITRANGE_VALID;/*只有biLowBit和biHighBit有效*/
/ *自这情况下不使用LUT,只将LGRYVIDEOINFO字段设置为并包括bmiHeader就足够了。的有用大小
LGRYVIDEOINFO结构是offset (LGRYVIDEOINFO, bmiColors)。* /