问题
I am reading some image from Azure Blob storage. This is a stream in c#.
In c++/cli I need to do this:
cv::Mat img_object = imdecode(data, IMREAD_UNCHANGED);
where data is of type cv::InputArray
so the question is how do I best get from c# to the cv::mat?
public ref class Client
{
public:
// TODO: Add your methods for this class here.
void Method(Stream ^ img1, Stream ^ img2);
};
void Client::Method(...){
}
I just put in Stream ^ img1, Stream ^img2, thats not a requirement, just not sure what is the best way to get from the c# stream to the cv::Mat class.
I know I could save the stream on a temp file location and use imread instead, but would be nice just to do it in memory.
in csharp i just have somehting like this: (I know its not the correct methods, but for the purpose of this example it illustrate the point).
Client client = new Client();
client.Method(blob.GetStream(), blob.GetStream())
Update : First try
void CVService::Stiching::StichingClient::FindHomography(cli::array<unsigned char>^ pCBuf1, cli::array<unsigned char> ^ pCBuf2)
{
pin_ptr<unsigned char> data1 = &pCBuf1[0];
pin_ptr<unsigned char> data2 = &pCBuf2[0];
Mat img_object = imdecode(*data1,IMREAD_COLOR);
Mat img_scene = imdecode(*data2, IMREAD_COLOR);
if (!img_object.data || !img_scene.data)
{
return;
}
imwrite("c:\\test.jpg", img_object);
}
and
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
StichingClient client = new StichingClient();
client.FindHomography(ReadByteArray(path1).Result
, ReadByteArray(path2).Result);
return base.OnStart();
}
private async Task<byte[]> ReadByteArray(string p)
{
using (var fs = File.OpenRead(p))
{
using (var ms = new MemoryStream())
{
await fs.CopyToAsync(ms);
return ms.ToArray();
}
}
}
}
Problem is that the loaded cv::mat is having data== 0 and not writing the image to disk. I have verified that the passed char arrays contains data. Is there any way to find out why imdecode do not decode the images?
update 2
the following test in c++/cli code part works:
Mat test1 = imread("DSC_023.tif");
std::vector<unsigned char> buf;
imencode(".jpg", test1, buf);
Mat test2 = imdecode(buf, IMREAD_COLOR);
With the above 4 lines the test2 is the loaded image and imdecode works. So wondering why it do not work when the data comes in as byte arrays
回答1:
So heres is my solution. It can be cleaned up ofcause but it works now.
void CVService::Stiching::StichingClient::FindHomography(cli::array<unsigned char>^ pCBuf1, cli::array<unsigned char> ^ pCBuf2)
{
pin_ptr<unsigned char> data1 = &pCBuf1[0];
pin_ptr<unsigned char> data2 = &pCBuf2[0];
pin_ptr<System::Byte> p1 = &pCBuf1[0];
unsigned char* pby1 = p1;
Mat img_data1(pCBuf1->Length, 1, CV_8U, pby1);
pin_ptr<System::Byte> p2 = &pCBuf2[0];
unsigned char* pby2 = p2;
Mat img_data2(pCBuf2->Length, 1, CV_8U, pby2);
cv::Mat img_object = imdecode(img_data1, IMREAD_UNCHANGED);
cv::Mat img_scene = imdecode(img_data2, IMREAD_UNCHANGED);
if (!img_object.data || !img_scene.data)
{
return;
}
imwrite("img_object.jpg", img_object);
imwrite("img_scene.jpg", img_scene);
}
I got this working with converting two images loaded from Azure Blob storage in memory and can now do my opencv stuff on the images. The test here just write the two passed images to the file system.
来源:https://stackoverflow.com/questions/21649136/how-to-come-from-c-sharp-stream-to-opencv-mat-by-using-c-cli