[英]C++ data packing from uchar to int (both positive and negative numbers)
我有一个CV_32S类型的OpenCV Mat,其中包含> = -1的整数值。 我试图访问底层数据指针 ,这是一个类型为uchar
的平面1D数组。
我想因为int
是4字节[32位]而uchar
是1字节[8位]我需要将数据解包为int类型,这最初是在OpenCV Mat结构中提供的。
cv::Mat opencv_data; //! data of type CV_32 with both negative and positive values.
我将opencv_data
的uchar *data
指针opencv_data
给cuda内核。 要将四个uchars
解压缩为单个int
我会执行以下操作。
int value = (uchar)opencv_data[index] |
(((uchar)opencv_data[index + 1]) << 8) |
(((uchar)opencv_data[index + 2]) << 16);
当opencv_data只有正值时,我得到正确的解包value
。 但是,如果我在opencv_data
放入一个负数,则上面的解包会产生value = -1
。
我无法理解这个问题背后的原因,我需要帮助。
编辑:基于使用reinterpret_cast
建议。 更新代码如下,但对于负数,结果仍然不正确。
//! for test only
cv::Mat test = cv::Mat(40, 60, CV_32S);
for (int j = 0; j < test.rows; j++) {
for (int i = 0; i < test.cols; i++) {
test.at<int>(j, i) = -2;
}
}
int INDICES_BYTE = test.step * test.rows;
uchar *data = reinterpret_cast<uchar*>(test.data);
for (int i = 0; i < INDICES_BYTE; i += 4) {
int index = reinterpret_cast<uchar>(data[i]) |
(reinterpret_cast<uchar>(data[i + 1]) << 8) |
(reinterpret_cast<uchar>(data[i + 2]) << 16) |
(reinterpret_cast<uchar>(data[i + 3]) << 32);
std::cout << index << "\n";
}
编辑后的代码生成正数的正确结果,但不会生成test
负数。
例如:对于-2,结果为16777215
看来你在这里误解了一些概念。
openCV mat
存储内存分配的地址,该地址分配将矩阵数据保存在uchar *
。 这并不意味着数据以任何方式进行转换。 如果要直接访问与矩阵关联的数据,只需将指针强制转换为正确的类型并使用该转换指针即可。 像这样:
#include <opencv2/core/core.hpp>
#include <iostream>
int main()
{
cv::Mat test = cv::Mat(4, 6, CV_32S);
for (int j = 0; j < test.rows; j++) {
for (int i = 0; i < test.cols; i++) {
test.at<int>(j, i) = -2*i;
}
}
int *p = reinterpret_cast<int*>(test.data);
for(int j=0; j<test.rows; ++j) {
for(int i=0; i<test.cols; ++i) {
std::cout << j << "," << i << " = " << p[i] << std::endl;
}
p += test.cols;
}
return 0;
}
你错误输入了最后一个班次,它应该是:
(reinterpret_cast<uchar>(data[i + 3]) << 24);
请注意,如果最后一次移位溢出,此方法将调用未定义的行为,但对于大多数当前实现,它不应导致问题。 顺便说一下,你不需要reinterpret_cast<uchar>
因为data
是一个uchar
数组。 这是一个更安全的方法:
for (int i = 0; i < INDICES_BYTE; i += 4) {
unsigned u32 = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) |
((unsigned)data[i + 3] << 24);
int index = (u32 <= INT_MAX) ? u32 : ~(int)~u32;
std::cout << index << "\n";
}
还要注意,此方法假设整数类型的字节顺序。 一种更简单的方法是将test.data
视为使用int *p = reinterpret_cast<int*>(test.data);
指向一个简单的int
数组int *p = reinterpret_cast<int*>(test.data);
发表于talomies的回答。
最后,所有这些方法都假设打包了2D数组,即: test.step == test.cols * sizeof(int)
,这可能无法保证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.