EmguCV Access Violation Exception while using BlobFromImage - c#

I've been trying for a long time to implement pose detection in EmguCV without success.
I have a successful program in C++ using OpenCV. When I tried to translate it in C#, I couldn't go over the "BlobFromImage" because I get an Exception ("Access Violation")...
I tried multiple things, I'm compiling in x64, and the image is correct (I can show it without problem as an image). Before that I was using Mat instead of UMat, but it's just the same.
Emgu version: 4.2.0.3662 (also tried with other versions, still getting the same error.
If it can help, see the code below:
private void Prova()
{
VideoCapture cap = new VideoCapture(videoFile);
if (!cap.IsOpened)
{
Debug.WriteLine("Unable to connect to camera");
return;
}
UMat frame;
int frameWidth = (int)cap.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameWidth);
int frameHeight = (int)cap.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.FrameHeight);
VideoWriter video = new VideoWriter("Output-Skeleton-Davide-MPI-GPU-168.avi", VideoWriter.Fourcc('M', 'J', 'P', 'G'), new System.Drawing.Size(frameWidth, frameHeight), false);
Net net = Emgu.CV.Dnn.DnnInvoke.ReadNetFromCaffe("./pose_deploy_linevec.prototxt", "./pose_iter_160000.caffemodel");
net.SetPreferableBackend(Emgu.CV.Dnn.Backend.Default);
net.SetPreferableTarget(Emgu.CV.Dnn.Target.OpenCL);
frame = cap.QueryFrame().GetUMat(Emgu.CV.CvEnum.AccessType.ReadWrite);
if (frame.Rows != 0 && frame.Cols != 0)
{
// Exception thrown here...
Emgu.CV.UMat inpBlob = Emgu.CV.Dnn.DnnInvoke.BlobFromImage(frame).GetUMat(Emgu.CV.CvEnum.AccessType.ReadWrite);
net.SetInput(inpBlob);
}
}
I know that I could call the c++ code from C#, but I would rather do it from C# alone.
Thanks a lot

Related

How to create fast duplex scanning with WIA C#?

i am new to WIA. And i have been asked to make scaning service scan faster and duplex. My current service scan one page, then put it in pdf and so on untill there is less then 20 pages(this number just a crutch used before me, will be glad if someone explane how to get "if there is any paper in there" variable). I started to dig and found docs on MSDN describing properties and after found this post describing duplex sanning, but with mysterious 5 in set. After I found this and figured out what i need WIA_DPS_DOCUMENT_HANDLING_SELECT to set to 0x205(FEEDER + DUPLEX + AUTO_ADVANCE). So I tried to setup them like this:
private static void SetProperty(Property property, int value)
{
IProperty x = (IProperty)property;
Object val = value;
x.set_Value(ref val);
}
...some code...
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
SetProperty(prop, 517);
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
And it did't worked for me... It just stuck on setting... Can Somebody explain how to setup AUTO_ADVANCE and DUPLEX props? Or maybe "make scanning faster and duplex" need something more then just AUTO_ADVANCE and DUPLEX and my perception about them is wrong? Or I should considering "ISIS / TWAIN (Windows XP / Vista / 7 / 8 / 8.1 / 10)" string in my scan description and use other libraries?
(Window 10, Canon DR-M160||, DR-M160 & DR-M160II Driver for Windows)
and also here is the current fetch function:
public List<ImageFile> FetchImageList()
{
List<ImageFile> imageList = new List<ImageFile>();
//bool hasMorePages = true;
int testcount = 0;
while (testcount >= 0)
{
testcount--;
WIA.Device device = FindDevice(_deviceId);
if (device == null)
{
LOGGER.Warn("Scanner device not found");
return null;
}
// get item
WIA.Item scanItem = device.Items[1] as WIA.Item;
LOGGER.Debug($"ScanItem: {scanItem.ItemID}");
try
{
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
LOGGER.Warn("here");
SetProperty(prop, 517);
LOGGER.Warn("here");
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Front");
//get back side
image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Back");
}
catch (Exception e)
{
throw (e);
}
}
return imageList;
}
Well... I tried to make duplex scan without AUTO_ADVANCE and got HRESULT: 0x8000FFFF (E_UNEXPECTED) on Transfer call. According to this post(even though that was on Windows 7) I guess there is no way to solve this for me by using WIA, still hope there will other suggestions...
Solved problem
I used saraff.twain and it worked for me:
- git page :https://github.com/saraff-9EB1047A4BEB4cef8506B29BA325BD5A/Saraff.Twain.NET
good library with grate wiki page.(Also have similar library for .net 4.6.1)

error in realtime wasapi capture(from sound card) manipulate and play

I'm trying to capture all sound going through the computer to manipulate and play it in realTime (there can be a slight delay due to manipulation but nothing too serious).
I'm trying to do this using Naudio wasapi. The problem is:
When I do it in exclusive mode, this line: audioClient.Initialize(shareMode, AudioClientStreamFlags.EventCallback, latencyRefTimes, latencyRefTimes,outputFormat, Guid.Empty);
throws this exception:
An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in NAudio.dll
Additional information: HRESULT: 0x88890016
When I do it in shared mode I get lot of noise which I think is caused by sound feedback (similiar to what happens when recording and playing at the same time)
Here's my code:
WasapiLoopbackCapture source = new WasapiLoopbackCapture();
source.DataAvailable += CaptureOnDataAvailable;
bufferedWaveProvider = new BufferedWaveProvider(source.WaveFormat);
volumeProvider = new VolumeSampleProvider(bufferedWaveProvider.ToSampleProvider());
WasapiOut soundOut = new WasapiOut(AudioClientShareMode.Shared, 0);
soundOut.Init(volumeProvider);
soundOut.Play();
source.StartRecording();
soundOut.Volume = 0.5f;
}
private void CaptureOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
int length = waveInEventArgs.Buffer.Length;
byte[] byteSamples = new Byte[length];
float[] buffer = waveInEventArgs.Buffer.toFloatArray(waveInEventArgs.BytesRecorded);//buffer to contains the samples about to be manipulated
fixer.fixSamples(length / 2, buffer, ref fixedSamples);
if (fixedSamples.Count > 0)
{
//convert the fixed samples back to bytes in order for them to be able to play out
byteSamples = fixedSamples.convertToByteArray(position);
bufferedWaveProvider.AddSamples(byteSamples, 0, byteSamples.Length);
volumeProvider.Volume = .5f;
}
position = fixedSamples.Count;
}
How can I solve these problems?
Also, I don't know if it's the best approach for what i'm trying to do, so if anyone has a better idea how to do this I'm more than happy to hear.
(i thought about using asio, but decided not to since there are a lot of computers without an asio driver)
this error is AUDCLNT_E_UNSUPPORTED_FORMAT
You can only capture audio in certain formats with WASAPI. Usually has to be IEEE float, stereo, 44.1kHz / 48kHz

Opening AutoCAD drawing inside a Windows Form in C#

I have the following function which opens a dxf file in an Autocad Exe, by zooming a specific coordinate via my C# desktop application.
public static void zoomDrwaing(String drawingFile, String lotId)
{
AcadApplication acadApp = null;
AcadDocument doc = null;
double[] coordinates = new double[3];
String errorMessage = "";
try
{
coordinates = ReadCoordinates(drawingFile, lotId); // done via netDxf api
acadApp = new Autodesk.AutoCAD.Interop.AcadApplication();
acadApp.Visible = true;
doc = acadApp.Documents.Open(drawingFile, true);
double[] points = new double[3] { coordinates[0], coordinates[1], coordinates[2] };
acadApp.ZoomCenter(points, 30);
}
catch (Exception ex)
{
errorMessage = ex.ToString();
}
finally
{
if (acadApp != null) Marshal.FinalReleaseComObject(acadApp);
}
}
I would like to know whether there is any possibility of loading the Autocad Exe (with the zoomed dxf file) inside one of the Windows forms in my desktop application it-self rather than opening the exe separately.
I haven't tried it but apparently you can use the ActiveX control from DWG Trueview Here is a forum post on the Autodesk forum with some sample code. Googling DWG Trueview Activex should generate some reading material. Or you may just read this and abandon all hope. The $$ alternative is RealDwg or Open Design. Read the AutoCAD Tag wiki for more resources and info on that.
Because Autodesk love to destroy their inbound links from time to time, you should be able to land on the first topic I mentioned using Google if they kill it again. Don't get me started on that.

OpenCvSharp: CvtSeqToArray crashes

I am searching a contour, and at least one is found, as I can see with the debugger.
When I try to transform the sequence into an array of points a StackOverflowException (that's why I am here :-) is thrown.
I am sure the reason is some wrong allocation of buffers, I am a bit confused with the examples I have found in C, C++, but not in C#. OpenCvSharp uses generics which I never used before.
Platform: Windows 7 on x86, Sharpdevelop 4.2.2
Here follows the code snippet:
OpenCvSharp.CvMemStorage allContours = new OpenCvSharp.CvMemStorage();
OpenCvSharp.CvSeq<OpenCvSharp.CvPoint> contour = null;
OpenCvSharp.CvPoint[] border;
i = OpenCvSharp.Cv.FindContours (image[EDGE], allContours, out contour,
OpenCvSharp.CvContour.SizeOf, OpenCvSharp.ContourRetrieval.List,
OpenCvSharp.ContourChain.ApproxNone,
OpenCvSharp.Cv.Point(0,0));
if (i!=1)
{ Forms.MessageBox.Show( i.ToString() + " instead of 1 contours found", "Info");
return;
}
border = new OpenCvSharp.CvPoint [contour.Total];
OpenCvSharp.Cv.CvtSeqToArray<OpenCvSharp.CvPoint> (contour, out border);
It is the last line where the program crashes.

Can't open a mpg-File for capture using EmguCV with C#

I'm trying to open a mpg-File using emguCV. I use the following code:
if (instance == null)
{
lock (m_lock)
{
try
{
instance = new Capture(0); // capture from camera works fine if a camera is connected
}
catch (NullReferenceException)
{
String sFileName = #"C:\tmp\MarkerMovie.mpg";
try
{
if (File.Exists(sFileName))
{
instance = new Capture(sFileName); // here the exception is thrown
}
else
{
MessageBox.Show("No Camera and no Video-File found");
}
}
catch (NullReferenceException)
{
MessageBox.Show("Couldn't open Video: "+sFileName);
}
}
}
}
If a webcam is connected everything works fine, but when I unplug the webcam the line instance = new Capture(sFileName); throws a NullReferenceException:
Message = "Unable to create capture from C:\tmp\MarkerMovie.mpg"
I debugged and found the reason is in the constructor of capture. The following command always returns a Null-Pointer:
_ptr = CvInvoke.cvCreateFileCapture(fileName);
I could open the same video using C++ using this code:
cap = cvCaptureFromFile("C:\\tmp\\MarkerMovie.mpg");
I'm new to openCV, so I'm not sure which information you need to help me. I installed emguCV yesterday from http://sourceforge.net/projects/emgucv/ on a Windows XP computer. The installer-version is x86_2.3.0.1416. I included opencv_core231.dll, opencv_highgui231.dll and opencv_imgproc231.dll to my project.
Does somebody know how I can make this code working?
Let me know if you need more information.
Thanks.
I had the same problem and adding the opencv_ffmpeg.dll to the project seems to solve it. (Found in the bin directory in the Emgu CV directory) I have tried it on the project that you posted and it seems to be working too. Hope it helps.
With EmguCV in C#, you need to put the opencv_ffmpeg.dll, for example: opencv_ffmpeg2410.dll, be careful if you have x86 or 64 bits

Categories

Resources