使用 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();
我正在尝试使用 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();