提交 4eac1982 编写于 作者: A Alexander Alekhin

core(persistence): fix types format handling, fix 16F support

上级 735a79ae
...@@ -143,17 +143,17 @@ static const char symbols[9] = "ucwsifdh"; ...@@ -143,17 +143,17 @@ static const char symbols[9] = "ucwsifdh";
static char typeSymbol(int depth) static char typeSymbol(int depth)
{ {
CV_StaticAssert(CV_64F == 6, ""); CV_StaticAssert(CV_64F == 6, "");
CV_Assert(depth >=0 && depth <= CV_64F); CV_CheckDepth(depth, depth >=0 && depth <= CV_16F, "");
return symbols[depth]; return symbols[depth];
} }
static int symbolToType(char c) static int symbolToType(char c)
{ {
if (c == 'r')
return CV_SEQ_ELTYPE_PTR;
const char* pos = strchr( symbols, c ); const char* pos = strchr( symbols, c );
if( !pos ) if( !pos )
CV_Error( CV_StsBadArg, "Invalid data type specification" ); CV_Error( CV_StsBadArg, "Invalid data type specification" );
if (c == 'r')
return CV_SEQ_ELTYPE_PTR;
return static_cast<int>(pos - symbols); return static_cast<int>(pos - symbols);
} }
...@@ -245,8 +245,12 @@ int calcStructSize( const char* dt, int initial_size ) ...@@ -245,8 +245,12 @@ int calcStructSize( const char* dt, int initial_size )
{ {
int size = calcElemSize( dt, initial_size ); int size = calcElemSize( dt, initial_size );
size_t elem_max_size = 0; size_t elem_max_size = 0;
for ( const char * type = dt; *type != '\0'; type++ ) { for ( const char * type = dt; *type != '\0'; type++ )
switch ( *type ) {
char v = *type;
if (v >= '0' && v <= '9')
continue; // skip vector size
switch (v)
{ {
case 'u': { elem_max_size = std::max( elem_max_size, sizeof(uchar ) ); break; } case 'u': { elem_max_size = std::max( elem_max_size, sizeof(uchar ) ); break; }
case 'c': { elem_max_size = std::max( elem_max_size, sizeof(schar ) ); break; } case 'c': { elem_max_size = std::max( elem_max_size, sizeof(schar ) ); break; }
...@@ -255,7 +259,9 @@ int calcStructSize( const char* dt, int initial_size ) ...@@ -255,7 +259,9 @@ int calcStructSize( const char* dt, int initial_size )
case 'i': { elem_max_size = std::max( elem_max_size, sizeof(int ) ); break; } case 'i': { elem_max_size = std::max( elem_max_size, sizeof(int ) ); break; }
case 'f': { elem_max_size = std::max( elem_max_size, sizeof(float ) ); break; } case 'f': { elem_max_size = std::max( elem_max_size, sizeof(float ) ); break; }
case 'd': { elem_max_size = std::max( elem_max_size, sizeof(double) ); break; } case 'd': { elem_max_size = std::max( elem_max_size, sizeof(double) ); break; }
default: break; case 'h': { elem_max_size = std::max(elem_max_size, sizeof(float16_t)); break; }
default:
CV_Error_(Error::StsNotImplemented, ("Unknown type identifier: '%c' in '%s'", (char)(*type), dt));
} }
} }
size = cvAlign( size, static_cast<int>(elem_max_size) ); size = cvAlign( size, static_cast<int>(elem_max_size) );
...@@ -1054,6 +1060,7 @@ public: ...@@ -1054,6 +1060,7 @@ public:
CV_Assert(write_mode); CV_Assert(write_mode);
size_t elemSize = fs::calcStructSize(dt.c_str(), 0); size_t elemSize = fs::calcStructSize(dt.c_str(), 0);
CV_Assert(elemSize);
CV_Assert( len % elemSize == 0 ); CV_Assert( len % elemSize == 0 );
len /= elemSize; len /= elemSize;
......
...@@ -1837,4 +1837,69 @@ TEST(Core_InputOutput, FileStorage_copy_constructor_17412_heap) ...@@ -1837,4 +1837,69 @@ TEST(Core_InputOutput, FileStorage_copy_constructor_17412_heap)
EXPECT_EQ(0, remove(fname.c_str())); EXPECT_EQ(0, remove(fname.c_str()));
} }
static void test_20279(FileStorage& fs)
{
Mat m32fc1(5, 10, CV_32FC1, Scalar::all(0));
for (size_t i = 0; i < m32fc1.total(); i++)
{
float v = (float)i;
m32fc1.at<float>((int)i) = v * 0.5f;
}
Mat m16fc1;
// produces CV_16S output: convertFp16(m32fc1, m16fc1);
m32fc1.convertTo(m16fc1, CV_16FC1);
EXPECT_EQ(CV_16FC1, m16fc1.type()) << typeToString(m16fc1.type());
//std::cout << m16fc1 << std::endl;
Mat m32fc3(4, 3, CV_32FC3, Scalar::all(0));
for (size_t i = 0; i < m32fc3.total(); i++)
{
float v = (float)i;
m32fc3.at<Vec3f>((int)i) = Vec3f(v, v * 0.2f, -v);
}
Mat m16fc3;
m32fc3.convertTo(m16fc3, CV_16FC3);
EXPECT_EQ(CV_16FC3, m16fc3.type()) << typeToString(m16fc3.type());
//std::cout << m16fc3 << std::endl;
fs << "m16fc1" << m16fc1;
fs << "m16fc3" << m16fc3;
string content = fs.releaseAndGetString();
if (cvtest::debugLevel > 0) std::cout << content << std::endl;
FileStorage fs_read(content, FileStorage::READ + FileStorage::MEMORY);
Mat m16fc1_result;
Mat m16fc3_result;
fs_read["m16fc1"] >> m16fc1_result;
ASSERT_FALSE(m16fc1_result.empty());
EXPECT_EQ(CV_16FC1, m16fc1_result.type()) << typeToString(m16fc1_result.type());
EXPECT_LE(cvtest::norm(m16fc1_result, m16fc1, NORM_INF), 1e-2);
fs_read["m16fc3"] >> m16fc3_result;
ASSERT_FALSE(m16fc3_result.empty());
EXPECT_EQ(CV_16FC3, m16fc3_result.type()) << typeToString(m16fc3_result.type());
EXPECT_LE(cvtest::norm(m16fc3_result, m16fc3, NORM_INF), 1e-2);
}
TEST(Core_InputOutput, FileStorage_16F_xml)
{
FileStorage fs("test.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
test_20279(fs);
}
TEST(Core_InputOutput, FileStorage_16F_yml)
{
FileStorage fs("test.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
test_20279(fs);
}
TEST(Core_InputOutput, FileStorage_16F_json)
{
FileStorage fs("test.json", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
test_20279(fs);
}
}} // namespace }} // namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册