Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 更改cv::Mat图像的类型(解释)_C++_Opencv_Image Processing - Fatal编程技术网

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
图像,它被OpenCV
cv::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保留两个矩阵或原始图像