采用OpenCV Mat<doube>并转换为12位值数组。
Taking OpenCV Mat<doube> and converting to array of 12bit values.
我有一个 cv::Mat 的双打图像,我在 0.0 和 4095.0 之间截断了它。我希望能够转换这个矩阵/基于这个 12 位矩阵创建一个新矩阵。(容纳 0 -> 4095 整数值所需的最小整数大小)。 我可以取出原始缓冲区,但是我不确定矩阵内数据的格式。
手动我可以执行以下操作:
cv::Mat new_matrix(/*type CV_8UC3, size (matrix.rows, matrix.cols/2)*/);
for(int i = 0; i < matrix.rows; ++i){
for(int j = 0; j < matrix.cols; ++j){
std::uint16_t upper_half = static_cast<std::uint16_t>(matrix.at<double>(j*2,i));
std::uint16_t lower_half = static_cast<std::uint16_t>(matrix.at<double>(j*2+1,i));
std::uint8_t first_byte = static_cast<std::uint8_t>(upper_half>>4);
std::uint8_t second_byte = static_cast<std::uint8_t>(upper_half<<4) | static_cast<std::uint8_t>(lower_half << 12 >> 12);
std::uint8_t third_byte = static_cast<std::uint8_t>(lower_half>>4);
new_matrix.at<cv::Vec3B>(j, i) = cv::Vec3b(first_byte, second_byte, third_byte);
}
}
它本质上是将两个双精度值压缩为一个用于上半部分,一个用于下半部分,从中提取三个字节(12 + 12 = 24,24/8 = 3)到一个 3 字节矩阵中。 我不确定内存布局是否会与打包的 12 位布局相匹配(我确实有偶数个 col,所以划分 cols/2 不是问题),我不确定如何确保这符合字节序。
我什至可以使用自定义数据类型,但是如果说我做了联合结构 12 位类型或其他东西,我需要确保元素没有填充。
请注意,转换后,我不打算再在 OpenCV 中使用 12 位值,然后我需要提取原始值,然后将它们发送到另一个单独的进程。
cv::Mat 将以最少 8 位为单位存储数据。 这意味着您的 12 位值无论如何都会填充在矩阵中,正如 Mat::elemSize1() 的返回值所证明的那样,该值以 # 字节为单位。 对于您需要做的事情,最好的选择似乎是使用包含 2 个值的自定义结构(结构大小也是字节填充的),然后将所有内容打包在 std::vector<> 中。 然后,当您有奇数个样本时,您将在流数据上浪费 12 位填充。
关于打包的注意事项:如果使用类似以下内容的内容,如果需要将字节从一个体系结构传输到另一个体系结构,则需要根据计算机颠倒位大小元素的顺序。
#pragma pack(push, 1)
struct PackedSamples {
char lowA;
char highA : 4; // NOTE: the declaration of bit sized fields order is inverse when
char lowB : 4; // going from BIG_ENDIAN to SMALL_ENDIAN and vice-versa
char highB;
};
#pragma pack(pop)
以下是我用于测试字节序的宏,我假设Windows在x86/x64上运行。AMD正在__BIG_ENDIAN。
#ifdef WIN32
# ifndef __BYTE_ORDER
# define __LITTLE_ENDIAN 1234
# define __BIG_ENDIAN 4321
# define __BYTE_ORDER __LITTLE_ENDIAN
# endif
#else
# include <endian.h>
#endif
所以上面的声明将变成:
#pragma pack(push, 1)
struct PackedSamples {
char lowA;
#if __BYTE_ORDER == __LITTLE_ENDIAN
char highA : 4;
char lowB : 4;
#else
char lowB : 4;
char highA : 4;
#endif
char highB;
};
#pragma pack(pop)
- 将尾部调用void(i32,..)位转换为llvm::函数以获取FnAttribute
- 16 位到 10 位转换代码说明
- 如何处理来自MIPI相机的12位图像?
- 如何在C ++中将二进制字符串128位转换为十进制字符串?
- C++中的24位到32位转换
- 将字节数组转换为对象C++ |C++中的 C# 位转换器
- 将大数字(10-12 位数字)存储在无序映射中<字符串,整数>
- 我把我的编译器从32位转换为64位,但我仍然不能使用超过2GB:(为什么
- 如何将内存中的位转换为一串和零?
- 位操作将最左侧的设置位转换为右侧交替位?
- 采用OpenCV Mat<doube>并转换为12位值数组。
- 如何将单个位转换为字符
- C ++ 12位变量,我该怎么做?
- 当我输入12位数字时,为什么以下代码崩溃
- 如何在AVX2中从32位转换为16位未签名的整数
- 如何使用OPENCV C 将24位转换为8位深度PNG图像
- 以C++为单位将每 5 位转换为整数值
- 使用位操作将8字节数字中的每个字节中的一位转换为单个字节
- 如何宽色域,从8位转换到10位
- 从 8 位转换为 1 字节