使用 FreeImage 加载 RAW 灰度图像
Loading RAW grayscale image with FreeImage
如何使用FreeImage加载RAW 16位灰度图像?
我有unsigned char*
原始数据的缓冲区。我知道它的尺寸以像素为单位,我知道它是 16 位灰度。
我正在尝试加载它
FIBITMAP* bmp = FreeImage_ConvertFromRawBits(buffer, 1000, 1506, 2000, 16, 0, 0, 0);
并获得损坏的RGB888图像。目前还不清楚我应该为灰度使用什么颜色的蒙版,因为它只有一个通道。
经过多次实验,我找到了部分有效的解决方案FreeImage_ConvertFromRawBitsEx
:
FIBITMAP* bmp = FreeImage_ConvertFromRawBitsEx(true, buffer, FIT_UINT16, 1000, 1506, 2000, 16, 0xFFFF, 0xFFFF, 0xFFFF);
(感谢@1201ProgramAlarm对面具的提示)。
通过这种方式,FreeImage 加载数据,但采用某种半自定义格式。大多数转换和保存功能(尝试:JPG,PNG,BMP,TIF)都失败了。
由于我无法以本机 16 位格式加载数据,因此我更喜欢将其转换为 8 位灰度
unsigned short* buffer = new unsigned short[1000 * 1506];
// load data
unsigned char* buffer2 = new unsigned char[1000 * 1506];
for (int i = 0; i < 1000 * 1506; i++)
buffer2[i] = (unsigned char)(buffer[i] / 256.f);
FIBITMAP* bmp = FreeImage_ConvertFromRawBits(buffer2, 1000, 1506, 1000, 8, 0xFF, 0xFF, 0xFF, true);
这真的不是最好的解决方案,我什至不想将其标记为正确答案(将等待更好的答案)。但是在此之后,该格式对于FreeImage来说将很方便,并且可以将数据保存/转换为任何内容。
关于您的问题:我从他们的PDF文档中读到了这个 FreeImage1370.pdf:
FreeImage_ConvertFromRawBits
1 4 8 16 24 32
DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertFromRawBits(BYTE *bits, int width, int 高度, 国际音高, 无符号 BPP, 无符号red_mask, 无符号green_mask, 无符号 blue_mask,布尔自上而下FI_DEFAULT(假));
将内存中某处的原始位图转换为 FIBITMAP。其中的参数 函数用于描述原始位图。第一个参数是指向 原始位。宽度和高度参数描述位图的大小。球场 定义源位图中扫描线的总宽度,包括填充字节,这些字节可能是 应用的。bpp 参数告诉 FreeImage 位图的位深度是多少。这 red_mask,green_mask和blue_mask参数告诉FreeImage颜色的位布局 位图中的组件。最后一个参数 topdown 将存储位图左上角像素 当它为 TRUE 时首先出现,当它为 FALSE 时,首先是左下角像素。
- 当源位图使用 32 位填充时,可以使用 以下公式: 整数间距 = (((bpp * 宽度) + 31)/32) * 4);
在你显示的代码中:
FIBITMAP* bmp = FreeImage_ConvertFromRawBits(buffer, 1000, 1506, 2000, 16, 0, 0, 0);
您具有适当的FIBTMAP*
返回类型,则传入raw bits
的buffer
。从那里开始,第 2 和第 3 个参数是width
和height
:width = 1000
height = 1506
和第4 个参数,即pitch
:pitch = 2000
(如果位图使用 32 位填充,请参阅上面的最后一条注释),第5个参数将是bpp
测量的位深度,如bpp = 16
,接下来的 3 个参数适用于您的RGB color masks
。在这里,您将它们全部标记为0
。最后一个参数是image
orientation
的布尔标志:
省
略值
if (topdown == true ) {
stores top-left pixel first )
else {
bottom left pixel is stored first
}
。
如果没有更多代码来说明您如何读取文件、解析标头信息等以准备您的buffer
,很难判断其他地方可能存在错误或问题,但从您提供的内容来看;我认为您需要检查color channel masks
是否有grayscale images
.
编辑- 我从这里找到了另一个 FreeImage 的 PDF standford.edu 它引用了旧版本3.13.1
但是函数声明 - 定义看起来没有任何变化,它们提供了 bFreeImage_ConvertToRawBits
&Free_Image_ConvertFromRawBits
的示例:
// this code assumes there is a bitmap loaded and // present in a variable called ‘dib’ // convert a bitmap to a 32-bit raw buffer (top-left pixel first) // -------------------------------------------------------------- FIBITMAP *src = FreeImage_ConvertTo32Bits(dib); FreeImage_Unload(dib); // Allocate a raw buffer int width = FreeImage_GetWidth(src); int height = FreeImage_GetHeight(src); int scan_width = FreeImage_GetPitch(src); BYTE *bits = (BYTE*)malloc(height * scan_width); // convert the bitmap to raw bits (top-left pixel first) FreeImage_ConvertToRawBits(bits, src, scan_width, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); FreeImage_Unload(src); // convert a 32-bit raw buffer (top-left pixel first) to a FIBITMAP // ---------------------------------------------------------------- FIBITMAP *dst = FreeImage_ConvertFromRawBits(bits, width, height, scan_width, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, FALSE);
我认为这应该可以帮助您解决有关灰度图像中颜色通道bit masks
的问题。
您已经提到了FreeImage_ConvertFromRawBitsEx()
函数,它是在 FreeImage v3.8 和 v3.17 之间的某个时候添加的,但你是否正确调用它?我能够将此功能用于 16 位灰度数据:
int nBytesPerRow = nWidth * 2;
int nBitsPerPixel = 16;
FIBITMAP* pFIB = FreeImage_ConvertFromRawBitsEx(TRUE, pImageData, FIT_UINT16, nWidth, nHeight, nBytesPerRow, nBitsPerPixel, 0, 0, 0, TRUE);
请注意,必须为 16 位数据正确指定nBytesPerRow
和nBitsPerPixel
。另外,我相信颜色遮罩参数与此数据无关,因为它是单色的。
编辑:我注意到您说保存16位数据无法正常工作。 这可能是由于文件格式本身。我发现唯一与 16 位灰度数据兼容的文件格式是 TIFF。因此,如果您有 16 位灰度数据,则可以使用FreeImage_Save()
保存 TIFF,但无法保存 BMP。
- OpenCV - 如何在灰度图像上应用 Kmeans?
- C++灰度图像处理
- 如何显示具有 opengl 纹理的灰度图像
- (C++)(Visual Studio) 将高斯模糊滤镜应用于 RGB 中的灰度图像
- 使用 SSE 以最快的速度缩小 8 位灰度图像
- 使用 OpenCV 和 C++将 16 位灰度图像更改为彩色图像
- 有没有办法使用 glDrawPixel 渲染单通道灰度图像?
- 如何在OpenCV中减去两个不同尺寸的图像和灰度图像
- 使用 ImageMagick 从像素强度数组创建灰度图像时遇到问题
- 将高斯模糊应用于灰度图像
- 在OpenCV中将灰度图像转换为单色
- Mat的convertTo函数在OpenCV中将灰度图像的类型转换为CV_32F时抱怨断言错误
- 使用 FreeImage 加载 RAW 灰度图像
- 使用条款 使用Opencv和Qt减去两个灰度图像
- 使用OpenCV在Android上使用神经网络进行灰度图像分类
- 使用 C++ 从 16 位数据创建灰度图像
- 使用Opencv直接从网络摄像头获取灰度图像
- 在 openCV 中访问某些像素的强度值(灰度图像)
- 在 C 或 C++ 中翻转灰度图像
- 如何在OpenCV中创建二进制非灰度图像