SQlite3 二进制数据(BLOB)的存取【基于wxSqlite3的封装的 *** 作】

SQlite3 二进制数据(BLOB)的存取【基于wxSqlite3的封装的 *** 作】,第1张

概述问题描述: 由于需要,把一张图片加载到cv::Mat对象中(image), 并调用算法计算出一个特征向量(feature) 和一些关键点(std::vector<cv::KeyPoint> keyPoints ),把以上这三个对象写入Sqlite3数据库(BLOB类型), 之后如果需要又重新从数据库中读出来,并还原成对应的类型。 cv::Mat image = imread(...);cv::M


问题描述:

由于需要,把一张图片加载到cv::Mat对象中(image),并调用算法计算出一个特征向量(feature) 和一些关键点(std::vector<cv::KeyPoint> keyPoints ),把以上这三个对象写入sqlite3数据库(BLOB类型), 之后如果需要又重新从数据库中读出来,并还原成对应的类型。

cv::Mat image = imread(...);cv::Mat feature = algorithm.Calc(...);std::vector<cv::KeyPoint> ps = algorithm.Calc(...);


部分代码:

1. 写入:

int MTemplateFactory::New(const MTemplateFeature& feature){	MDatabaseArchive* archive = MDatabaseManager::getSingleton().GetArchive();	if (archive)	{		MString sql;		if (feature.Getcolor() <= 0)			sql = MString::Format("insert into tabTemplate (name,branch_ID,feature,image,keypoints) values ('%s',%d,?,?)",feature.Getname(),feature.GetBranchID());		else			sql = MString::Format("insert into tabTemplate (name,color,feature.GetBranchID(),feature.Getcolor());		try		{ 			//- Prepare data			cv::Mat img = feature.Ge@R_403_5411@();			cv::Mat f = feature.GetFeature();			std::vector<cv::KeyPoint> ps = feature.GetKeyPoints();			//- Image.			wxMemoryBuffer buf1;			buf1.AppendData(&img.rows,4); int type1 = img.type();			buf1.AppendData(&img.cols,4); buf1.AppendData(&type1,4);			buf1.AppendData(img.data,img.cols * img.rows * img.elemSize());			//- Feature.			wxMemoryBuffer buf2;			buf2.AppendData(&f.rows,4); int type2 = img.type();			buf2.AppendData(&f.cols,4); buf2.AppendData(&type2,4);			buf2.AppendData(f.data,f.cols * f.rows * f.eleSize());			//- keyPoints.			wxMemoryBuffer buf3;			int eleSize = sizeof(cv::KeyPoint);			for (auto point : ps)			{				buf3.AppendData(&point,eleSize);			} 			wxsqlite3Statement stmt = archive->PrepareStatement(sql);   			stmt.Bind(1,buf2);			stmt.Bind(2,buf1);			stmt.Bind(3,buf3);			if (stmt.ExecuteUpdate() > 0)				return archive->ExecuteScalar("select MAX(ID) from tabTemplate");		}		catch (wxsqlite3Exception& e)		{			throw MException(e.GetMessage());		}		catch (cv::Exception& e)		{			throw MException(e.msg);		} 	}	return 0;}<span ></span>

2. 读取:
MTemplateArray MTemplateFactory::List(){	MTemplateArray arr;	MDatabaseArchive* archive = MDatabaseManager::getSingleton().GetArchive();	if (archive)	{ 		try		{			wxsqlite3ResultSet res = archive->Executequery("select * from tabTemplate");			while (res.NextRow())			{				int ID = res.GetInt(0);				MString name = res.GetString(1);				int branch_ID = res.GetInt(2);				int colorID = res.GetInt(3);				wxMemoryBuffer f1,f2,f3;				res.GetBlob("image",f1);				res.GetBlob("feature",f2);				res.GetBlob("keypoints",f3);				if (f1.IsEmpty() == true || f2.IsEmpty() == true || f3.IsEmpty() == true)				{					throw MException(_("特征模版保存数据为空,无法创建对象!"));				} 								cv::Mat&& img = MakeMat(f1);				cv::Mat&& feature = MakeMat(f2);				//- Parse keypoints data.				uchar* data = (uchar*)f3.GetData();				int len = f3.GetDataLen();				std::vector<cv::KeyPoint> ps;				int eleSize = sizeof(cv::KeyPoint);				int cnt = len / eleSize;				for (int i = 0; i < cnt; i++)				{					cv::KeyPoint* p = (cv::KeyPoint*)(data + i * eleSize);					ps.push_back(cv::KeyPoint(*p));				}				//- Construct template feature object...				arr.push_back(MTemplateFeature(ID,name,colorID,img.clone(),feature.clone(),ps));			}		}		catch (cv::Exception &e)		{			throw MException(e.msg);		}		catch (wxsqlite3Exception& e)		{			throw MException(e.GetMessage());		}	}	return arr;}cv::Mat MTemplateFactory::MakeMat(const wxMemoryBuffer& buf ){	assert(buf.IsEmpty() == false);	voID* data = buf.GetData();	int len = buf.GetDataLen();	int* p = (int*)data;	int h = p[0];	int w = p[1]; <span >	</span>int _type = p[2]; int offset = sizeof(int) * 3;	return cv::Mat(h,w,_type,(uchar*)data + offset);}

说明几点注意的地方:

sqlite3 存取二进制的文章很多,不记录了。wxsqlite3对blob的 *** 作在wxsqlite3Statement类中,有类似绑定数据(Bind...)和提交 *** 作(ExecuteUpdate...)的函数,具体查看相应的文档或者看源码有注释的。关于KeyPoint的保存,由于cv::KeyPoint这个类的所有数据成员全部都是实体数据,比如int,float 这样的数据,那么直接可以把每个cv::KeyPoint对象的地址加上长度( int len = sizeof(cv::KeyPoint) )存入即可,读数据库还原的时候只需 获取当该片内存,强制转换成 cv::KeyPoint* 就行了,但是如果某些情况,比如对象的成员变量里面有指针指向了另外的地址上的数据,那么这样行不通,强转后的这些指针因为环境变化而无效,如果 *** 作程序会崩溃掉的。

总结

以上是内存溢出为你收集整理的SQlite3 二进制数据(BLOB)的存取【基于wxSqlite3的封装的 *** 作】全部内容,希望文章能够帮你解决SQlite3 二进制数据(BLOB)的存取【基于wxSqlite3的封装的 *** 作】所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1170439.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存