我尝试使用存储在SQLite数据库中的数据重新创建Mat对象。我打开一个图像,获取它的描述符(使用Surf),然后将数据存储在SQLite DB中。之后,我尝试从数据库中读取该数据,并使用该数据重新创建相同的Mat对象。
这是我的表:
create table images(
id INTEGER,
descriptors BLOB
);
这是获取描述符&将它们存储在数据库部分中:
Mat image;
vector<KeyPoint> keypoints;
image = imread(nameImage,0);
SurfFeatureDetector surf(500);
surf.detect(image, keypoints);
SurfDescriptorExtractor surfDesc;
Mat descriptors, descriptors;
surfDesc.compute(image, keypoints, descriptors);
string command = "insert into images values(" << id << ",'" << descriptors << "');";
sqlite3_exec(db, command, callback, (void*)data, &errMsg);
这就是我从数据库中获取数据的方式:
string command = "select id, descriptors from images;";
sqlite3_exec(db, command, callback, (void*)data, &errMsg);
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int id = atoi(argv[0]);
/*argv[1] contains the matrix data and it is untouched, the fun begins */
/*when I try to put that data into a Mat object: */
Mat currentDescriptors;
currentDescriptors = Mat(h,w,CV_16S,argv[1]);
/*after this, the Mat data gets borked /*
return 0;
}
问题是,这个数据(基本上是一个数组,char *,它是sqlite方法返回的数据)由有符号值组成(我使用数据库客户端检查了数据库中的值和从读取数据库获得的char数组的值是正确的)。但是,在创建Mat对象时,这些值似乎会转换为无符号数,因此Mat值是错误的。
以下是我打算做的事情以及每一步检查存储值的摘要:
我使用的Mat构造函数如下:
TempMat = cv::Mat(height, width, CV_32F, buffer);
我使用的是CV_32F,因为这是我在获取描述符后检查它时得到的类型(我得到类型5,我发现它是CV_32F)。
我尝试过更改mat类型并手动将值插入Mat对象,但似乎没有任何效果(或者我不知道如何使其工作)。有没有办法用签名数据构造Mat对象?
答案 0 :(得分:-1)
嗯,问题解决了。看起来这是解决两个不同问题的问题:
首先,出于某种原因,直接用CV_32F类型创建矩阵(我用于SURF识别的类型)将使用错误的顺序创建它。我不知道为什么,我搜索了几个来源,我开始相信这是一个错误。我甚至尝试过简单的例子(创建一个2x2矩阵并手动添加值),它只是不起作用(值没有结束我告诉他们去的地方)。这是通过使用CV_64F类型创建矩阵,然后将其转换为CV_32F来解决的:
Mat m = Mat(h,w,CV_64F);
fillValues(...);
m.convertTo(m,CV_32F);
另一个问题是,我提供矩阵构造函数的数据看起来是错误的格式。在解决了第一个问题之后,这些数字似乎没有被正确读取(它们最终到达了必须的位置,但它们已被更改),所以我尝试了不同的方法。将char数组转换为双向量并逐个手动插入值是我想出来的,它可以工作:
vector<double> fvalues;
int position = 0;
for(int i=0;i<h;i++){
for(int j=0;j<w;j++){
if(position!=fvalues.size()){
currentDescriptors.at<double>(i,j)=fvalues.at(position);
position++;
} else {
break;
}
}
}
在包含这两个修复程序后,问题得以解决 - 重新创建的矩阵与首先创建的矩阵相同(并存储在SQLite数据库中)。