HDFql 保存和加载图像
HDFql Saving and Loading Images
我正在尝试使用 HDFql 将图像从 OpenCV 保存到 HDF5。这是我要实现的目标的一个最小示例(假设您在 /tmp/lena.jpg
有一张图片):
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <HDFql.hpp>
int main() {
char script[1024];
HDFql::execute("CREATE FILE /tmp/test.h5");
HDFql::execute("USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP image");
cv::Mat img = cv::imread("/tmp/lena.jpg", CV_8UC3);
cv::Size size(img.size());
std::cout << "Size = " << size.width << ", " << size.height;
for(int i=0; i<100; i++)
{
// Show a few pixel values - cast is necessary, since values are unsigned char
std::cout << i << ": " << (int)img.data[i] << std::endl;
}
sprintf(script, "CREATE CONTIGUOUS DATASET test/image AS UNSIGNED TINYINT(%d)", size.width*size.height*3);
HDFql::execute(script);
sprintf(script, "INSERT INTO test/image VALUES FROM MEMORY %d", HDFql::variableRegister(img.data));
HDFql::execute("CLOSE FILE");
HDFql::execute("USE FILE /tmp/test.h5");
cv::Mat img_loaded = cv::Mat::zeros(cv::Size(size.width, size.height), CV_8UC3);
HDFql::variableRegister(img_loaded.data);
HDFql::execute("SELECT AS INT FROM image VALUES INTO MEMORY " + HDFql::variableGetNumber(img_loaded.data));
HDFql::variableUnregister(img_loaded.data);
HDFql::execute("CLOSE FILE");
cv::imshow("loaded image", img_loaded);
cv::waitKey();
return 0;
}
此代码主要是创建一个新的 HDF5 文件,然后使用 OpenCV 打开图像并将该图像保存到 HDF5 文件中。然后它从 HDF5 文件加载相同的图像并显示它。
如果你没有 OpenCV,你总是可以用一个 uchar 数组替换 image.data
,例如:uchar image_data[10] = {1,2,3,4,5,6,7,8,9,10};
长话短说,这不起作用,在检查 HDF5 文件时,它在保存步骤中已经失败。任何对我做错事的帮助将不胜感激!
您的代码片段中的 HDFql SELECT
操作包含两个问题:1) 您不能在那里指定 AS INT
和 2) 数据集 image
位于组 test
。此外,从未调用(即执行)将数据写入数据集的脚本。
此外,还可以对代码片段做一些优化,即:
- 删除关键字“CONTIGUOUS”,因为在创建数据集时它是
默认连续。
- 将数据集的数据类型更改为
OPAQUE
- 我相信你想存储图像的原始数据所以这种数据类型更合适。
- 以瞬态方式注册变量,以便在(由 HDFql)使用它们后自动取消注册 - 这将减轻您的负担。
这里是代码片段 corrected/refactored:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <HDFql.hpp>
int main() {
char script[1024];
HDFql::execute("CREATE AND USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP image");
cv::Mat img = cv::imread("/tmp/lena.jpg", CV_8UC3);
cv::Size size(img.size());
std::cout << "Size = " << size.width << ", " << size.height;
for(int i=0; i<100; i++)
{
// Show a few pixel values - cast is necessary, since values are unsigned char
std::cout << i << ": " << (int)img.data[i] << std::endl;
}
sprintf(script, "CREATE DATASET test/image AS OPAQUE(%d) VALUES FROM MEMORY %d", size.width*size.height*3, HDFql::variableTransientRegister(img.data));
HDFql::execute(script);
HDFql::execute("CLOSE FILE");
cv::Mat img_loaded = cv::Mat::zeros(cv::Size(size.width, size.height), CV_8UC3);
sprintf(script, "SELECT FROM /tmp/test.h5 test/image INTO MEMORY %d", HDFql::variableTransientRegister(img_loaded.data));
HDFql::execute(script);
cv::imshow("loaded image", img_loaded);
cv::waitKey();
return 0;
}
这是基于@SOG 给出的答案 - 谢谢!
#include <iostream.h>
#include <HDFql.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int main (int argc, const char * argv[]) {
char script[1024];
//Create HDF5 file and group "test"
HDFql::execute("CREATE TRUNCATE FILE /tmp/test.h5");
HDFql::execute("USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP test");
//==== Load Image, save it to test.h5/test/image ====
//Choose color or grayscale
//cv::ImreadModes read_mode = cv::IMREAD_GRAYSCALE;
cv::ImreadModes read_mode = cv::IMREAD_COLOR;
cv::Mat img = cv::imread("/tmp/lena.jpg", read_mode);
cv::Size size(img.size());
int num_pixels = size.width*size.height*img.channels();
cv::imshow("image", img);
cv::waitKey();
sprintf(script, "CREATE DATASET test/image AS UNSIGNED TINYINT(%d) "
"VALUES FROM MEMORY %d", num_pixels,
HDFql::variableTransientRegister(img.data));
HDFql::execute(script);
HDFql::execute("CLOSE FILE");
//==== Load HDF5, and load saved image data to a new cv::Mat image ====
HDFql::execute("USE FILE /tmp/test.h5");
cv::Mat img_loaded;
if(read_mode == cv::IMREAD_COLOR)
{
img_loaded = cv::Mat::zeros(size, CV_8UC3);
} else
{
img_loaded = cv::Mat::zeros(size, CV_8UC1);
}
std::cout << "size = " << img_loaded.size() << ", type = " << img_loaded.type()
<< ", channels = " << img_loaded.channels() <<std::endl;
sprintf(script, "SELECT FROM test/image INTO MEMORY %d",
HDFql::variableTransientRegister(img_loaded.data));
HDFql::execute(script);
HDFql::execute("CLOSE FILE");
cv::imshow("loaded image", img_loaded);
cv::waitKey();
}
此代码适用于灰度和彩色图像。 @SOG 的回答还有一些问题,除了一些小问题,我无法让它与数据类型 OPAQUE
一起使用,所以我又回到使用 UNSIGNED TINYINT
。我不知道为什么会这样。
除此之外,@SOG 的详尽回答几乎抓住了我的代码无法正常工作的原因。
我正在尝试使用 HDFql 将图像从 OpenCV 保存到 HDF5。这是我要实现的目标的一个最小示例(假设您在 /tmp/lena.jpg
有一张图片):
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <HDFql.hpp>
int main() {
char script[1024];
HDFql::execute("CREATE FILE /tmp/test.h5");
HDFql::execute("USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP image");
cv::Mat img = cv::imread("/tmp/lena.jpg", CV_8UC3);
cv::Size size(img.size());
std::cout << "Size = " << size.width << ", " << size.height;
for(int i=0; i<100; i++)
{
// Show a few pixel values - cast is necessary, since values are unsigned char
std::cout << i << ": " << (int)img.data[i] << std::endl;
}
sprintf(script, "CREATE CONTIGUOUS DATASET test/image AS UNSIGNED TINYINT(%d)", size.width*size.height*3);
HDFql::execute(script);
sprintf(script, "INSERT INTO test/image VALUES FROM MEMORY %d", HDFql::variableRegister(img.data));
HDFql::execute("CLOSE FILE");
HDFql::execute("USE FILE /tmp/test.h5");
cv::Mat img_loaded = cv::Mat::zeros(cv::Size(size.width, size.height), CV_8UC3);
HDFql::variableRegister(img_loaded.data);
HDFql::execute("SELECT AS INT FROM image VALUES INTO MEMORY " + HDFql::variableGetNumber(img_loaded.data));
HDFql::variableUnregister(img_loaded.data);
HDFql::execute("CLOSE FILE");
cv::imshow("loaded image", img_loaded);
cv::waitKey();
return 0;
}
此代码主要是创建一个新的 HDF5 文件,然后使用 OpenCV 打开图像并将该图像保存到 HDF5 文件中。然后它从 HDF5 文件加载相同的图像并显示它。
如果你没有 OpenCV,你总是可以用一个 uchar 数组替换 image.data
,例如:uchar image_data[10] = {1,2,3,4,5,6,7,8,9,10};
长话短说,这不起作用,在检查 HDF5 文件时,它在保存步骤中已经失败。任何对我做错事的帮助将不胜感激!
您的代码片段中的 HDFql SELECT
操作包含两个问题:1) 您不能在那里指定 AS INT
和 2) 数据集 image
位于组 test
。此外,从未调用(即执行)将数据写入数据集的脚本。
此外,还可以对代码片段做一些优化,即:
- 删除关键字“CONTIGUOUS”,因为在创建数据集时它是 默认连续。
- 将数据集的数据类型更改为
OPAQUE
- 我相信你想存储图像的原始数据所以这种数据类型更合适。 - 以瞬态方式注册变量,以便在(由 HDFql)使用它们后自动取消注册 - 这将减轻您的负担。
这里是代码片段 corrected/refactored:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <HDFql.hpp>
int main() {
char script[1024];
HDFql::execute("CREATE AND USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP image");
cv::Mat img = cv::imread("/tmp/lena.jpg", CV_8UC3);
cv::Size size(img.size());
std::cout << "Size = " << size.width << ", " << size.height;
for(int i=0; i<100; i++)
{
// Show a few pixel values - cast is necessary, since values are unsigned char
std::cout << i << ": " << (int)img.data[i] << std::endl;
}
sprintf(script, "CREATE DATASET test/image AS OPAQUE(%d) VALUES FROM MEMORY %d", size.width*size.height*3, HDFql::variableTransientRegister(img.data));
HDFql::execute(script);
HDFql::execute("CLOSE FILE");
cv::Mat img_loaded = cv::Mat::zeros(cv::Size(size.width, size.height), CV_8UC3);
sprintf(script, "SELECT FROM /tmp/test.h5 test/image INTO MEMORY %d", HDFql::variableTransientRegister(img_loaded.data));
HDFql::execute(script);
cv::imshow("loaded image", img_loaded);
cv::waitKey();
return 0;
}
这是基于@SOG 给出的答案 - 谢谢!
#include <iostream.h>
#include <HDFql.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
int main (int argc, const char * argv[]) {
char script[1024];
//Create HDF5 file and group "test"
HDFql::execute("CREATE TRUNCATE FILE /tmp/test.h5");
HDFql::execute("USE FILE /tmp/test.h5");
HDFql::execute("CREATE GROUP test");
//==== Load Image, save it to test.h5/test/image ====
//Choose color or grayscale
//cv::ImreadModes read_mode = cv::IMREAD_GRAYSCALE;
cv::ImreadModes read_mode = cv::IMREAD_COLOR;
cv::Mat img = cv::imread("/tmp/lena.jpg", read_mode);
cv::Size size(img.size());
int num_pixels = size.width*size.height*img.channels();
cv::imshow("image", img);
cv::waitKey();
sprintf(script, "CREATE DATASET test/image AS UNSIGNED TINYINT(%d) "
"VALUES FROM MEMORY %d", num_pixels,
HDFql::variableTransientRegister(img.data));
HDFql::execute(script);
HDFql::execute("CLOSE FILE");
//==== Load HDF5, and load saved image data to a new cv::Mat image ====
HDFql::execute("USE FILE /tmp/test.h5");
cv::Mat img_loaded;
if(read_mode == cv::IMREAD_COLOR)
{
img_loaded = cv::Mat::zeros(size, CV_8UC3);
} else
{
img_loaded = cv::Mat::zeros(size, CV_8UC1);
}
std::cout << "size = " << img_loaded.size() << ", type = " << img_loaded.type()
<< ", channels = " << img_loaded.channels() <<std::endl;
sprintf(script, "SELECT FROM test/image INTO MEMORY %d",
HDFql::variableTransientRegister(img_loaded.data));
HDFql::execute(script);
HDFql::execute("CLOSE FILE");
cv::imshow("loaded image", img_loaded);
cv::waitKey();
}
此代码适用于灰度和彩色图像。 @SOG 的回答还有一些问题,除了一些小问题,我无法让它与数据类型 OPAQUE
一起使用,所以我又回到使用 UNSIGNED TINYINT
。我不知道为什么会这样。
除此之外,@SOG 的详尽回答几乎抓住了我的代码无法正常工作的原因。