cv::mat 保存sqlite數據庫,使用qt
- 環境:
- qt
- opencv
- sqlite
-
使用QByteArray::fromRawData()講Mat數據轉換爲ByteArray,但這個函數不會保存Mat的長,寬,和類型,需要創建一個stream分別保存。
-
此方法可以將任意cv::mat進行保存和加載
#include<opencv2/opencv.hpp>
#include<QDataStream>
#include<QSqlQuery>
// save sift into database with id
bool Database::addSift(int id, const cv::Mat &sift)
{
// set id if not exists
Database::setID(id);
// create a bytearray to accept the stream
QByteArray data; // = QByteArray((const char *)&sift, sizeof(sift));
QDataStream stream(&data, QIODevice::WriteOnly);
stream << sift.type(); // cv::Mat type
stream << sift.rows; // cv::Mat rows
stream << sift.cols; // cv::Mat cols
// calculate the data size of this matrix
const size_t data_size = sift.cols * sift.rows * sift.elemSize();
// save all data into stream.
// this part will not include the format and shape of the matrix
QByteArray siftByte = QByteArray::fromRawData( (const char*)sift.ptr(), data_size );
stream << siftByte;
// insert into database mytable
QSqlQuery query(db);
query.prepare("UPDATE mytable SET sift=:sift WHERE id=:id;");
query.bindValue(":id", id);
query.bindValue(":sift", data);
if(!query.exec()) {
qDebug() << "ERROR: addSift" << query.lastError().text();
return false;
} else {
return true;
}
}
// load sift mat from database
cv::Mat Database::getSift(int id)
{
// get data from database mytable
QSqlQuery query(db);
query.prepare("SELECT sift FROM mytable WHERE id = :id;");
query.bindValue(":id", id);
if(!query.exec()) {
qDebug() << "ERROR: getSift" << query.lastError().text();
std::abort();
} else {
query.next();
QByteArray data = query.value(0).toByteArray();
QDataStream stream(&data, QIODevice::ReadOnly);
// the same oders and format as in saveSift()
int matType, rows, cols;
stream >> matType >> rows >> cols;
QByteArray siftByte;
stream >> siftByte;
// resume the cv::Mat and return
return cv::Mat(rows, cols, matType, (void*)siftByte.data()).clone();
}
}