2017-03-14 2 views
0

Je suis impatient de lire l'image à partir de la base de données MS-SQL en utilisant ADO (C++). Les images sont stockées en tant que varBinary (max) dans la base de données. J'ai essayé d'obtenir et de convertir des images au format cv::Mat.Obtenir des données d'image à partir de la base de données en format cv :: Mat en utilisant C++ et Ado

Voici le code que j'ai,

HRESULT hr = ::CoInitialize(NULL); 

    ADODB::_ConnectionPtr pConnection; 
    hr = pConnection.CreateInstance(__uuidof(ADODB::Connection)); 
    pConnection->CursorLocation = ADODB::adUseClient; 

    hr=pConnection->Open(L"Provider=sqloledb;Data Source=SAMPLE-DB;" 
    L"Initial Catalog=IMAGE;User Id=sr;Password=****;", L"", 
    L"", ADODB::adConnectUnspecified); 

    if (FAILED(hr)) 
    { 
     //error handling... 
    } 

    ADODB::_RecordsetPtr recordset; 
    hr = recordset.CreateInstance(__uuidof(ADODB::Recordset)); 

    std::string cmd = "SQL COMMAND THAT PROVIDE IMAGE BINARY"; 

    recordset->Open(cmd.c_str(), pConnection.GetInterfacePtr(), 

    ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText); 

    std::vector<uchar> buffer; 
    buffer = recordset->Fields->GetItem(L"ImgBinary")->GetValue(); //problem!! 

    cv::Mat testImage = cv::imdecode(buffer,cv::IMREAD_COLOR); //problem!! 

    cv::namedWindow("MyWindow"); 
    cv::imshow("MyWindow",testImage); 

erreurs que j'ai,

1) 'cv :: imdecode': aucun des 2 pourrait convertir tous surcharges l'argument types

2-) IntelliSense: pas de conversion définie par l'utilisateur approprié de "_variant_t" à "std :: vector>" existe

Pourriez-vous aider s'il vous plaît? Comment puis-je obtenir l'image en format cv::Mat?

Merci à l'avance

Répondre

0

Problème résolu! Le problème était la méthode GetValue(). Nous devons utiliser la méthode GetChunk() car nous obtenons un tableau de la base de données. GetChunk() doit avoir un paramètre de taille. Nous pouvons obtenir la taille avec,

long lngSize = recordset->Fields->GetItem(L"ImgBinary")->ActualSize; 

ligne de code.

La version modifiée du code est ci-dessous,

HRESULT hr = ::CoInitialize(NULL); 
ADODB::_ConnectionPtr pConnection; 
hr = pConnection.CreateInstance(__uuidof(ADODB::Connection)); 
pConnection->CursorLocation = ADODB::adUseClient; 

hr=pConnection->Open(L"Provider=sqloledb;Data Source=SAMPLE-DB;" 
L"Initial Catalog=IMAGE;User Id=sr;Password=****;", L"", 
L"", ADODB::adConnectUnspecified); 

if (FAILED(hr)) 
{ 
    //error handling... 
} 

ADODB::_RecordsetPtr recordset; 
hr = recordset.CreateInstance(__uuidof(ADODB::Recordset)); 

std::string cmd = "SQL COMMAND THAT PROVIDE IMAGE BINARY"; 

recordset->Open(cmd.c_str(), pConnection.GetInterfacePtr(), 

ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, ADODB::adCmdText); 

/////////////// Edited Part /////////////// 

long lngSize = recordset->Fields->GetItem(L"ImgBinary")->ActualSize; 

_variant_t varChunk = recordset->Fields->GetItem(L"ImgBinary")->GetChunk(lngSize); 

    std::vector<uchar> buffer(lngSize); 
    SAFEARRAY* pData=NULL; 
    pData=V_ARRAY(&varChunk); 

    void *pVoid = 0; 
    hr = ::SafeArrayAccessData(pData, &pVoid); 
    uchar *pBinary = reinterpret_cast<uchar *>(pVoid); 

     for (int i = 0; i < pData->rgsabound[0].cElements; ++i) 
     { 
      buffer[i] = pBinary[i]; 
     } 

     hr = ::SafeArrayUnaccessData(pData); 
     cv::Mat testImage = cv::imdecode(buffer,cv::IMREAD_COLOR); 
     cv::namedWindow("MyWindow"); 
     cv::imshow("MyWindow",testImage); 
     cv::waitKey();