使用 C++ 和 Ado 从数据库中以 cv::Mat 格式获取图像数据

Getting Image Data from Database as cv::Mat format using C++ and Ado

我正在尝试使用 ADO (C++) 从 MS-SQL 数据库中读取图像。图像在数据库中存储为 varBinary(max)。我试图获取图像并将其转换为 cv::Mat 格式。

这是我的代码,

    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);
   

            

我遇到的错误,

1-) 'cv::imdecode' : none of the 2 overloads could convert all the argument types

2-) IntelliSense: no suitable user-defined conversion from "_variant_t" to "std::vector<uchar, std::allocator>" exists

你能帮忙吗?如何获取 cv::Mat 格式的图像?

问题解决了!问题是 GetValue() 方法。我们需要使用 GetChunk() 方法,因为我们从数据库中获取了一个数组。 GetChunk() 必须有一个大小参数。我们可以得到尺寸,

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

代码行。

编辑后的代码版本如下,

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();