我有一个 cv::Mat 的双打图像,我在 0.0 和 4095.0 之间截断。我希望能够转换这个矩阵/创建一个基于这个 12 位的新矩阵。(容纳 0 -> 4095 个整数值所需的最小 int 大小)。我可以取出原始缓冲区,但是我不确定矩阵内数据的格式。
手动我可以执行以下操作:
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 位匹配(我确实有偶数列,所以除以 cols/2 不是问题)而且我不确定如何确保这符合字节序.
我什至可以使用自定义数据类型,但如果说我制作了 Union Struct 12bit 类型或其他东西,我需要确保元素没有被填充。
注意转换后,我不再打算在 OpenCV 中使用 12 位值,然后我需要提取原始值并将它们发送到另一个单独的进程。