C ++ OpenCV从SIGNED char数组创建Mat(不是unsigned)

时间:2014-11-14 00:21:31

标签: c++ opencv char signed mat

我尝试使用存储在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值是错误的。

以下是我打算做的事情以及每一步检查存储值的摘要:

  1. 获取图像描述符 - 确定
  2. 将它们存储在数据库中 - 确定
  3. 从数据库中读取它们 - 确定
  4. 与他们一起创建一个Mat并查看Mat的值 - 错误
  5. 我使用的Mat构造函数如下:

    TempMat = cv::Mat(height, width, CV_32F, buffer);
    

    我使用的是CV_32F,因为这是我在获取描述符后检查它时得到的类型(我得到类型5,我发现它是CV_32F)。

    我尝试过更改mat类型并手动将值插入Mat对象,但似乎没有任何效果(或者我不知道如何使其工作)。有没有办法用签名数据构造Mat对象?

1 个答案:

答案 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数据库中)。