1

postgresql データベースから取得したイメージを c++ opencv にロードしたいと考えています。拡張子jpgの画像はベースにバイナリデータ(bytea型)で保存されており、libpqxxでアクセスできます。

問題は、データを cv::Mat インスタンスに変換する方法がわからないことです。通常の画像では imread('myImage.jpg', ...) を使用できますが、この場合、bmp ではなく jpeg であるため、Mat のデータ属性にデータベース画像をロードすることさえできません。

何か案が ?バイナリデータを直接理解して適切な構造に変換できるopencvメソッドはありますか? imdecode() 関数はビットマップ データに使用されているようです。

edit : Berak、ベクトルを使用すると imdecode 関数は null を返します。コードは次のとおりです。

pqxx::result r=bdd::requete("SELECT image FROM lrad.img WHERE id=3",1);//returns the bytea image in r[0]["image"]
const char* buffer=r[0]["image"].c_str();    
vector<uchar>::size_type size = strlen((const char*)buffer);
vector<uchar> jpgbytes(buffer, buffer+size);
Mat img = imdecode(jpgbytes, CV_LOAD_IMAGE_COLOR); 
//jpgbytes.size()=1416562 img.size()=[0 x 0]

何が欠けていますか?

4

2 に答える 2

1

わかりました、bytea データを cv::Mat に変換するプロセスがあります。コードは次のとおりです。

inline int dec(uchar x){ //convert uchar to int
    if (x>='0'&&x<='9') return (x-'0');
    else if (x>='a'&&x<='f') return (x-'a'+10);
    else if (x>='A'&&x<='F') return (x-'A'+10);
    return 0;
}
cv::Mat bytea2Mat(const pqxx::result::field& f){
    const char* buffer=f.c_str();  
    vector<uchar>::size_type size = strlen((const char*)buffer);
    vector<uchar> jpgbytes(size/2-1); 

    for (size_t i=0; i!=size/2-1;i++) { 
        jpgbytes[i]=(dec(buffer[2*(i+1)])<<4)+dec(buffer[2*(i+1)+1]);
    }
    cout <<size/2<<";"<<jpgbytes.size()<<endl;
    return imdecode(jpgbytes, CV_LOAD_IMAGE_COLOR);
}

bytea の出力は、"\x41204230" のような char* として暗号化され、16 進数形式の "a b0" の元の入力文字列に対して暗号化されます。元のデータを取得するには、2 つの文字 ('4','1'= 0x41=65) から元の入力を計算する必要があります。ベクトルは char* の半分のサイズです。

于 2014-10-08T14:28:06.593 に答える