我有一个 CV_32S 类型的 OpenCV 垫,其中包含 >= -1 的整数值。
我正在尝试访问底层 data pointer这是 uchar
类型的平面一维数组。
我想因为 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
指针传递给 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;
}
关于从uchar到int的C++数据打包(包括正数和负数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39190502/