C++ 更改cv::Mat图像的类型(解释)
无论出于何种原因,我有一个C++ 更改cv::Mat图像的类型(解释),c++,opencv,image-processing,C++,Opencv,Image Processing,无论出于何种原因,我有一个.tiff图像,它被OpenCVcv::imread错误地输入为cv_16U类型,而不是cv_16S。我知道这是不正确的,因为我的数据已经向我解释过了(图像应该包含-9999的伪值和一个正的最大值),我在Matlab中输入时得到了正确的值 我仍然可以通过.at函数自己处理它,因为我知道真正的类型,所以我可以使用.at。但是,cv::Mat::type()是错误的,如果我使用其他函数进行可能依赖于此参数的进一步处理(处理可能依赖于cv::Mat::type()) 如何在不
.tiff
图像,它被OpenCVcv::imread
错误地输入为cv_16U
类型,而不是cv_16S
。我知道这是不正确的,因为我的数据已经向我解释过了(图像应该包含-9999的伪值和一个正的最大值),我在Matlab
中输入时得到了正确的值
我仍然可以通过.at
函数自己处理它,因为我知道真正的类型,所以我可以使用.at
。但是,cv::Mat::type()
是错误的,如果我使用其他函数进行可能依赖于此参数的进一步处理(处理可能依赖于cv::Mat::type()
)
如何在不转换图像的情况下更改cv::Mat::type()
?也就是说,我不希望将值从无符号short
重新计算为short
表示,而只是改变读取它们的方式
如何更改与图像关联的cv::Mat::type()
。(但不只是将图像转换为其他类型)
下面是一些示例代码及其输出,以说明问题:
cv::Mat test = cv::imread(argv[1], CV_LOAD_IMAGE_ANYDEPTH);
if (test.type() == CV_16U){ // true
std::cerr << (short)(*std::min_element(test.begin<short>(),
test.end<short>()))
<< std::endl;
std::cerr << (short)(*std::max_element(test.begin<short>(),
test.end<short>()))
<< std::endl;
// output is OK, "-9999" and "1645"
std::cerr << (unsigned short)
(*std::min_element(test.begin<unsigned short>(),
test.end<unsigned short>()))
<< std::endl;
std::cerr << (unsigned short)
(*std::max_element(test.begin<unsigned short>(),
test.end<unsigned short>()))
<< std::endl;
// output is not OK: "1" and "55537"
cv::Mat test2;
test.convertTo(test2, CV_16S);
// also tried:
// test.assignTo(test2, CV_16S);
std::cerr << (short)(*std::min_element(test2.begin<short>(),
test2.end<short>()))
<< std::endl;
std::cerr << (short)(*std::max_element(test2.begin<short>(),
test2.end<short>()))
<< std::endl;
// output is not OK: "1" and "32767"
test.type = CV_16U; // what I would like to do
}
cv::Mat test=cv::imread(argv[1],cv\u LOAD\u IMAGE\u ANYDEPTH);
如果(test.type()==CV_16U){//true
默认情况下,OpenCV将其数据成员保留为公共成员(尽管您通常不想自己弄乱它们)。继续尝试一下;如果它工作得很好!如果不好
警告:未经测试的黑客解决方案
test.flags = (test.flags & ~CV_MAT_TYPE_MASK) | CV_16S;
OpenCV默认情况下将其数据成员保留为公共成员(尽管您通常不想自己弄乱他们)。继续尝试一下;如果它工作得很好!如果不好
警告:未经测试的黑客解决方案
test.flags = (test.flags & ~CV_MAT_TYPE_MASK) | CV_16S;
@BeyelerStudios这不是一个bug,opencv不知道内容是有符号的还是无符号的,并按默认值将其设置为无符号。您始终可以构造第二个矩阵cv::Mat actual(test.size(),cv_16S,test.ptr());
(test
必须是连续的,请参阅),但这也有点糟糕:)@vu1p3n0x我能强迫它将其设置为输入时签名吗?我可以看出如何无法从数据中确定它…@BeyelerStudios副本按预期工作。复制数据并不理想,但除非找到更好的解决方案,否则我会使用它。Tyvm.watch:获取数据参数的矩阵构造函数ter不复制,您需要保留两个矩阵或原始图像around@BeyelerStudios这不是一个bug,opencv不知道内容是有符号的还是无符号的,并通过默认值将其设置为无符号。您始终可以构造第二个矩阵cv::Mat actual(test.size(),cv_16S,test.ptr());
(test
为此必须是连续的,请参见),但这种测试也很糟糕:)@vu1p3n0x是否可以强制将其设置为在输入时签名?我可以看出无法从数据中确定它…@BeyelerStudios副本按预期工作。复制数据并不理想,但除非找到更好的解决方案,否则我将使用它。Tyvm.watch注意:使用数据参数的矩阵构造函数不会复制,您需要o保留两个矩阵或原始图像