使用QByteArray::fromRawData()讲Mat数据转换为ByteArray,但这个函数不会保存Mat的长,宽,和类型,须要建立一个stream分别保存。web
此方法能够将任意cv::mat进行保存和加载sql
#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(); } }