OpenCV图像转换出错
OpenCV image conversion goes wrong
我有一个算法做一些事情。其中,如果我正在处理CV_8UC3
映像,则有一种转换可以正常工作,但如果文件类型为C_16UC3
则会出错。这是一些代码:
//new image is created
Mat3w img(100,100,Vec3w(1000,0,0));
//Image Conversion - ERROR!
cv::Mat inputSource;
//saving the image here will work
img.convertTo(inputSource, CV_64FC3);
//saving the image here will not work -> black image
问题是CV_16UC3
图像的处理结果是一个正确的尺寸,但全黑的图像。问题是在转换中,因为在之前保存图像会得到一个合法的图像,而在之后保存图像会得到一个几乎完全白色的图像。
我做了一些更改:删除一些无用的代码并添加inputSource声明。现在,当我尝试这些东西的时候,我得出的结论是,要么我不理解简历类型,要么发生了一些奇怪的事情。我一直认为类型中的数字表示每个通道的位数。因此,在我的脑海中,CV_16UC3
是一个3通道,每个通道16位。我在测试期间保存的图像(在image . convertto之前)实际上每个通道号都有匹配的位,这一事实加强了这个想法。奇怪的是,保存的inputSource(类型CV_64FC3
)是一个8bpc的图像。
我错过了什么?
您会混淆imwrite
和imread
在OpenCV中的工作方式。来自OpenCV文档
imwrite
imwrite
函数将图像保存到指定的文件中。图像格式是根据文件名扩展名选择的(参见imread()
的扩展名列表)。只有8位(或16位无符号(CV_16U
)在PNG、JPEG 2000和TIFF的情况下)单通道或3通道(具有"BGR"通道顺序)图像可以使用此功能保存。如果格式、深度或通道顺序不同,请使用Mat::convertTo()
和cvtColor()
进行转换后再保存。或者,使用通用的FileStorage
I/O函数将图像保存为XML或YAML格式。
imread
imread函数从指定的文件中加载并返回图像。可能的标志是:
- IMREAD_UNCHANGED:如果设置,则返回加载的图像(带有alpha通道,否则会被裁剪)。
- IMREAD_GRAYSCALE:如果设置,总是将图像转换为单通道灰度图像。 IMREAD_COLOR:如果设置,总是将图像转换为3通道BGR彩色图像。
- IMREAD_ANYDEPTH:如果设置,当输入有相应深度时返回16位/32位图像,否则转换为8位。
- IMREAD_ANYCOLOR:如果设置,图像以任何可能的颜色格式读取。
所以对于您的情况,CV_16U
被保存而不进行转换,而CV_64F
被转换并保存为CV_8U
。如果想存储double
数据,应该使用FileStorage
。您还应该注意使用带有适当标志的imread
图像。
这个例子应该说明:
#include <opencv2opencv.hpp>
using namespace cv;
int main()
{
// Create a 16-bit 3 channel image
Mat3w img16UC3(100, 200, Vec3w(1000, 0, 0));
img16UC3(Rect(0, 0, 20, 50)) = Vec3w(0, 2000, 0);
// Convert to 64-bit (double) 3 channel image
Mat3d img64FC3;
img16UC3.convertTo(img64FC3, CV_64FC3);
// Save to disk
imwrite("16UC3.png", img16UC3); // No conversion
imwrite("64FC3.png", img64FC3); // Converted to CV_8UC3
FileStorage fout("64FC3.yml", FileStorage::WRITE);
fout << "img" << img64FC3; // No conversion
fout.release();
Mat img_maybe16UC3_a = imread("16UC3.png" /*, IMREAD_COLOR*/); // Will be CV_8UC3
Mat img_maybe16UC3_b = imread("16UC3.png", IMREAD_ANYDEPTH); // Will be CV_16UC1
Mat img_maybe16UC3_c = imread("16UC3.png", IMREAD_UNCHANGED); // Will be CV_16UC3
Mat img_maybe64FC3_a = imread("64FC3.png" /*, IMREAD_COLOR*/); // Will be CV_8UC3
Mat img_maybe64FC3_b = imread("64FC3.png", IMREAD_ANYDEPTH); // Will be CV_8UC1
Mat img_maybe64FC3_c = imread("64FC3.png", IMREAD_UNCHANGED); // Will be CV_8UC3
Mat img_mustbe64FC3;
FileStorage fin("64FC3.yml", FileStorage::READ);
fin["img"] >> img_mustbe64FC3; // Will be CV_64FC3
fin.release();
return 0;
}
- 将链表转换为指针数组时出错
- 将类指针类型转换为键时出错
- 将代码从 Python 转换为 C++ 时出错
- 从DLL导出函数,LoadLibrary()需要用TEXT转换的字符串才能编译而不会出错
- 编译时出错 - 从 DWORD 到 LPCVOID 的转换
- 在 Rcpp 中的字符串类型之间转换时出错
- 使用emscripten将c++文件转换为wasm时出错
- 从 uint8_t 到 int 的隐式转换出错了,当显式转换进展顺利时
- 将常量字符* 转换为字符时出错
- 浮点到整数转换出错(即使浮点数已经是整数)
- 在 C# 中从二进制值转换为双精度值时出错
- 将运算符<<与隐式转换的非基本数据类型一起使用时出错
- 为什么常量字符*到常量字符转换出错?
- 转换(常量字符*)变量出错
- 尝试将 C++11 代码转换为 C++03 时默认函数模板参数出错
- 将双精度转换为整数时出错
- 为什么我从字符转换为字符时出错
- 在Linux上构建Ogre时出错:缩小转换范围
- 编译C++代码时出错(转换无效)
- 链接libsodium时出错.a转换为共享对象