How can I properly call emgucv retrieve command in Visual C++? - c#

I'm trying to translate a piece of code from visual c# to visual c++ and can't seem to translate this bit:
Mat m = new Mat();
capture.Retrieve(m);
pictureBox1.Image = m.ToImage<Bgr, byte>().Bitmap;
so far i've written
Mat^ m = gcnew Mat();
Emgu::CV::Capture::Retrieve(m);
pictureBox1->Image = m->ToImage<Bgr, Byte>()->Bitmap;
but i get the following errors
(E1767 function "Emgu::CV::Capture::Retrieve" cannot be called with the given argument list)
(E0304 no instance of function template "Emgu::CV::Mat::ToImage" matches the argument list)
Any help would be appreciated.

Related

Calling Matlab function from .net(C#) by using MLApp.Feval()

I tried to use Matlab function from my .net project
function [HR] = getHR(signal)
Fs = 200;
index = pan_tompkin(signal,Fs);
index = index(2:end-1);
idx_dur = (index(end) - index(1))/Fs;
idx_cnt = length(index)-1;
idx_int = idx_dur/idx_cnt;
HR = round(60/idx_int);
end
This is my Matlab code
MLApp.MLApp matlab = new MLApp.MLApp();
matlab.Execute(#"cd C:\Users\User\Desktop");
object result = null;
matlab.Feval("getHR", 1, out result,input_Data);
object[] res = result as object[];
tmp_HR = Convert.ToInt32(res[0]);
And this is part of my .net code where calling Matlab function
input_Data is 2000x1 double array
When I run this program, error is occur that "Undefined function 'getHR' for input arguments of type 'double'." on Matlab.Feval line
Someone advised me to 'varargin' to solve this problem, but I can not find the answer(I don't think it is necessary)
How can I revise my code to fix this problem?
I can not use the way to use Matlab compiler SDK or Matlab coder
maybe have to use only MLApp to solve this problem

How to serialize tensor input required by dnnclassifier (serving_input_reciever)

I want to be able to use the dnnclassifier (estimator) on top of IIS using tensorflowsharp. The model has previously been trained in python. I got so far that I can now generate PB files, know the correct input/outputs, however I am stuck in tensorflowsharp using string inputs.
I can create a valid .pb file of the iris dataset. It uses the following feate_spec:
{'SepalLength': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'SepalWidth': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'PetalLength': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'PetalWidth': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None)}
I have created a simple c# console to try and spin it up. The input should be an "input_example_tensor" and the output is located in "dnn/head/predictions/probabilities". This I discoved after alex_zu provided help using the saved_model_cli command here.
As far as I am aware all tensorflow estimator API's work like this.
Here comes the problem: the input_example_tensor should be of a string format which will be parsed internally by the ParseExample function. Now i am stuck. I have found TFTensor.CreateString, but this doesn't solve the problem.
using System;
using TensorFlow;
namespace repository
{
class Program
{
static void Main(string[] args)
{
using (TFGraph tfGraph = new TFGraph()){
using (var tmpSess = new TFSession(tfGraph)){
using (var tfSessionOptions = new TFSessionOptions()){
using (var metaGraphUnused = new TFBuffer()){
//generating a new session based on the pb folder location with the tag serve
TFSession tfSession = tmpSess.FromSavedModel(
tfSessionOptions,
null,
#"path/to/model/pb",
new[] { "serve" },
tfGraph,
metaGraphUnused
);
//generating a new runner, which will fetch the tensorflow results later
var runner = tfSession.GetRunner();
//this is in the actual tensorflow documentation, how to implement this???
string fromTensorflowPythonExample = "{'SepalLength': [5.1, 5.9, 6.9],'SepalWidth': [3.3, 3.0, 3.1],'PetalLength': [1.7, 4.2, 5.4],'PetalWidth': [0.5, 1.5, 2.1],}";
//this is the problem, it's not working...
TFTensor rawInput = new TFTensor(new float[4]{5.1f,3.3f,1.7f,0.5f});
byte[] serializedTensor = System.Text.Encoding.ASCII.GetBytes(rawInput.ToString());
TFTensor inputTensor = TensorFlow.TFTensor.CreateString (serializedTensor);
runner.AddInput(tfGraph["input_example_tensor"][0], inputTensor);
runner.Fetch("dnn/head/predictions/probabilities", 0);
//start the run and get the results of the iris example
var output = runner.Run();
TFTensor result = output[0];
//printing response to the client
Console.WriteLine(result.ToString());
Console.ReadLine();
}
}
}
}
}
}
}
This example will give the following error:
An unhandled exception of type 'TensorFlow.TFException' occurred in TensorFlowSharp.dll: 'Expected serialized to be a vector, got shape: []
[[Node: ParseExample/ParseExample = ParseExample[Ndense=4, Nsparse=0, Tdense=[DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT], dense_shapes=[[1], [1], [1], [1]], sparse_types=[], _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_input_example_tensor_0_0, ParseExample/ParseExample/names, ParseExample/ParseExample/dense_keys_0, ParseExample/ParseExample/dense_keys_1, ParseExample/ParseExample/dense_keys_2, ParseExample/ParseExample/dense_keys_3, ParseExample/Const, ParseExample/Const, ParseExample/Const, ParseExample/Const)]]'
How can I serialize tensors in such a way that I can use the pb file correctly?
I also posted the issue on github, here you can find the iris example python file, pb file and the console applications. In my opinion solving this creates a
neat solution for all tensorflow users having ancient production environments (like me).
The Expected serialized to be a vector, got shape: [] error can be fixed by using an overload of the TFTensor.CreateString function: Instead of directly taking a string, the model apparently expects a vector containing a single string:
TFTensor inputTensor = TFTensor.CreateString(new byte[][] { bytes }, new TFShape(1));
The input_example_tensor in your case now expects a serialized Example protobuf message (see also the docs and the example.proto file).
Using the protobuf compiler, I've generated a C# file containing the Example class. You can download it from here: https://pastebin.com/iLT8MUdR. Specifically, I used this online tool with CSharpProtoc and replaced the import "tensorflow/core/example/feature.proto"; line by the messages defined in that file.
Once you've added the file to your project, you'll need a package reference to Google.Protobuf. Then, you can pass serialized examples to the model like this:
Func<float, Tensorflow.Feature> makeFeature = (float x) => {
var floatList = new Tensorflow.FloatList();
floatList.Value.Add(x);
return new Tensorflow.Feature { FloatList = floatList };
};
var example = new Tensorflow.Example { Features = new Tensorflow.Features() };
example.Features.Feature.Add("SepalLength", makeFeature(5.1f));
example.Features.Feature.Add("SepalWidth", makeFeature(3.3f));
example.Features.Feature.Add("PetalLength", makeFeature(1.7f));
example.Features.Feature.Add("PetalWidth", makeFeature(0.5f));
TFTensor inputTensor = TFTensor.CreateString(
new [] { example.ToByteArray() }, new TFShape(1));
runner.AddInput(tfGraph["input_example_tensor"][0], inputTensor);
runner.Fetch("dnn/head/predictions/probabilities", 0);
//start the run and get the results of the iris example
var output = runner.Run();
TFTensor result = output[0];

Java.Nio.ByteBuffer to c#

I am tring to use the following code in a c# xamarin project.
In Java,
ByteBuffer buffer=ByteBuffer.allocate(8);
UsbRequest request=new UsbRequest();
now I'm trying to convert these two line to c# for my xamarin project,
Java.Nio.ByteBuffer m_rinfo;
Int32 m_bytes = 64;
UsbRequest m_request = new UsbRequest();
m_request.Queue(m_rinfo, 64);<<error
The last line gives an error, "Use of assigned variable 'm_rinfo'
I've tried to assign bytes to m_rinfo with,
Java.Nio.ByteBuffer m_rinfo = new byte[64];
Which gives error, Cannot implicitly convert type byte
Any help would be appreciated.
I find I can convert the lines to;
Java.Nio.ByteBuffer m_rinfo = Java.Nio.ByteBuffer.Allocate(64);
Int32 m_bytes = 64;
UsbRequest m_request = new UsbRequest();
m_request.Queue(m_rinfo, 64);
However when the program gets to line;
m_request.Queue(m_rinfo, 64);
I receive the error;
'Java.Lang.RuntimeException' was thrown
So what's wrong with this line?
Have you tried m_request.Queue(out m_rinfo, 64);? As far as I'm aware, out is used when a variable in c# is passed to a method with the intent of its value being changed within it. For example:
ListOfSomeKind list = null;
methodToFillListWithData(out list);

Using C++ method in c#

I'm writing a c# console application that uses a C++ class library. In C++ language class library I have a method:
public:bool GetMDC(char fileName[], char mdcStrOut[]){
// My Code goes Here
}
This method gets a file path in fileName parameter and puts a value in mdcStrOut.
I add this class library as reference to my C# console application. when I want to call GetMDC method the method needs two sbyte parameters. So it's signature in c# is GetMDC(sbyte* fileName, sbyte* mdcStrOut).
My code looks like this:
unsafe{
byte[] bytes = Encoding.ASCII.GetBytes(fileName);
var _mdc = new TelsaMDC.TelsaMDCDetection();
var outPut = new sbyte();
fixed (byte* p = bytes)
{
var sp = (sbyte*)p;
//SP is now what you want
_mdc.GetMDC(sp, &outPut);
}
}
It works without error. But the problem is that outPut variable only contains the first character of mdcStrOut. I'm unfamiliar with C++. I know that I'm passing the memory address of output to the GetMDC. So how can I get the value of it in my console application?
EDIT
when I declare output variable like this var outPut = new sbyte[MaxLength] I get an error on _mdc.GetMDC(sp, &outPut); line on the & sign. It says: Cannot take the address of, get the size of, or declare a pointer to a managed type ('sbyte[]')
The variable outPut is a single byte.
You need to create a receive buffer, for example, var outPut = new sbyte[MaxLength].
unsafe{
byte[] bytes = Encoding.ASCII.GetBytes(fileName);
var _mdc = new TelsaMDC.TelsaMDCDetection();
var outPut = new sbyte[256]; // Bad practice. Avoid using this!
fixed (byte* p = bytes, p2 = outPut)
{
var sp = (sbyte*)p;
var sp2 = (sbyte*)p2;
//SP is now what you want
_mdc.GetMDC(sp, sp2);
}
}
Also, I recommend to rewrite the code to avoid possible buffer overflow because the function GetMDC does not know the size of the buffer.

c# console application run matlab function

I have some code written in Matlab however I wish to call this code from a C# console application.
I do not require any data to be returned from Matlab to my app (although if easy would be nice to see).
There appears to be a few options however not sure which is best. Speed is not important as this will be an automated task.
MATLAB has a .Net interface that's well-documented. What you need to do is covered in the Call MATLAB Function from C# Client article.
For a simple MATLAB function, say:
function [x,y] = myfunc(a,b,c)
x = a + b;
y = sprintf('Hello %s',c);
..it boils down to creating an MLApp and invoking the Feval method:
class Program
{
static void Main(string[] args)
{
// Create the MATLAB instance
MLApp.MLApp matlab = new MLApp.MLApp();
// Change to the directory where the function is located
matlab.Execute(#"cd c:\temp\example");
// Define the output
object result = null;
// Call the MATLAB function myfunc
matlab.Feval("myfunc", 2, out result, 3.14, 42.0, "world");
// Display result
object[] res = result as object[];
Console.WriteLine(res[0]);
Console.WriteLine(res[1]);
Console.ReadLine();
}
}

Categories

Resources