C# Emgu CV - how to use cuda in dnn - c#

public static void DetectObjects(Bitmap bitmapImage)
{
Image<Bgr, byte> image;
image = bitmapImage.ToImage<Bgr, byte>();
Mat input = DnnInvoke.BlobFromImage(image, 1 / 255.0, swapRB: true);
_netModel.SetInput(input);
Mat output = _netModel.Forward();
}
private static Net _netModel = DnnInvoke.ReadNetFromDarknet("B:/yolov3.cfg.txt", "B:/yolov3.weights");
The project has EmguCV version 4.4.0.4099 and the CUDA module of the same version.
As a result, I need the function to perform calculations on the GPU.
How many did not search about this, I did not find suitable information.

It seems enough to use
_netModel.SetPreferableBackend(Emgu.CV.Dnn.Backend.Cuda);
Source

Related

C# Emgu CV Trouble Predicting Face EigenFaceRecognizer

I'm trying to save face images and predict them using Emgu CV 4.4 with EigenFaceRecognizer using .Net5.
Basically I am getting a single image, resizing it (I read somewhere that smaller images have better accuracy),adding it to the List<Mat>and saving the trained data to see what is there out of curiosity.After that I'm using the same image and attempt to predict what it is (label).
Unfortunately it fails producing this error.
Emgu.CV.Util.CvException: 'OpenCV: Wrong shapes for given matrices. Was size(src) = (1,57600), size(W) = (19200,1).'
I also tried imageForTraining.Mat within Predict however the same error occurred.
// Get The GrayImage And Resize It.
Image<Bgr, byte> imageForTraining = grayImage.Resize(128, 150, Emgu.CV.CvEnum.Inter.Cubic);
// Create New cv::Mat Lists.
List<Mat> mats = new List<Mat>()
{
imageForTraining.Mat
};
// Dirty Solution For Label Testing.
List<int> labels = new List<int>()
{
0
};
// Create Face Recognizer And Tell It There Is Only 1 Item.
FaceRecognizer faceRecognizer = new EigenFaceRecognizer(1);
// Write Data To File To See If Something Is There.
faceRecognizer.Write("trainingData");
// Attempt To Train.
faceRecognizer.Train(new VectorOfMat(mats.ToArray()), new VectorOfInt(labels.ToArray()));
// Test Image That Was Just Trained.
FaceRecognizer.PredictionResult predictionResult = faceRecognizer.Predict(imageForTraining);

Create a Mat from a PvBuffer in C# using eBUS SDK and EmguCV

I'm using EmguCV 3.4.1 and the eBUS SDK. I have video coming in over GigE and I would like to convert the PvBuffer to a MAT so I can use OpenCV to create a display a histogram.
I followed a similar style to how you create a Mat in C++. Unfortunately this solution requires marking the project as unsafe.
unsafe private Mat convertPvBufferToMat(PvBuffer aBuffer)
{
PvImage lImage = aBuffer.Image;
lImage.Alloc(lImage.Width, lImage.Height, PvPixelType.Mono16);
int[] sizes = new int[2] { (int)lImage.Height, (int)lImage.Width };
Mat aMat = new Mat(sizes, DepthType.Cv16U, (IntPtr)lImage.DataPointer);
return aMat;
}
I'm taking images from an infared camera outputing 16 bit grayscale images.

C# Svg Library Engine ShapeRendering

Iam trying to convert a vector image(SVG) to PNG. I almost got it working except the final touch which has something todo with Shape Rendering.
I use the following code:
public string GeneratePng()
{
SvgDocument SvgDoc = SvgDocument.Open(#"C:\Temp\test.svg");
SvgDoc.Width = 1000;
SvgDoc.Height = 1000;
SvgDoc.ShapeRendering = SvgShapeRendering.GeometricPrecision;
Bitmap bmp = SvgDoc.Draw();
bmp.Save(#"C:\Temp\test.png", ImageFormat.Png);
return "done";
}
I use the nuget package: nuget.org/packages/Svg/
and the following svg file: https://www.w3.org/Icons/SVG/svg-logo-h.svg
The result https://i.stack.imgur.com/4bw9G.png with the edges pixelated. What I except it to do is to smoothen out the edges as stated GeometricPrecision would do.
Can anyone tell me what I am missing or doing wrong?

Image Stitching Emgu CV with GPU

I am running a EmguCV example for Image Stitching. Here's the important code from that example:
try
{
using (Stitcher stitcher = new Stitcher(false))
{
Image<Bgr, Byte> result = stitcher.Stitch(sourceImages);
IMGBXDisplayStitched.Image = result;
}
}
finally
{
foreach (Image<Bgr, Byte> img in sourceImages)
{
img.Dispose();
}
}
It works well, but when I change the value of Stitcher() to true (I want to use GPU), it shows this error:
An unhandled exception of type 'Emgu.CV.Util.CvException' occurred in Emgu.CV.dll
Additional information: OpenCV: You should explicitly call download method for gpu::GpuMat object
How can I solve this?
If you take a look at this example page, it says
There is currently a bug in Open CV such that GPU processing cannot produce the correct result. Must specify false as parameter. Hope this will be fixed soon to enable GPU processing

How to achieve good sharpness with twain/emgu/open cv?

I am using an Epson Perfection V700 scanner and selecting the following options when scanning using their tool:
ICM Color correction (source: EPSON-Standard and target: sRGB)
Unsharp Mask (medium)
That produces this image:
Now my problem is this - I actually need to interact with this scanner using TWAIN .Net and when I do so, the image I get back is this:
Aside: I unselected the aforementioned two options and scanned again with the Epson and got a very similar image to what I get through TWAIN.
So I figure that perhaps these are post processing steps that I can do myself on the image (maybe they are done in the hardware somehow though, I don't know).
I am using EmguCV so first of all I created an extension method that applies the ICM (I struggled to find any documentation for this, so it is a bit of a guess and maybe I am wrong straight away but I got the information from here: The bitmap transform class and it seems to make a difference to the image):
public static Image<Bgr, TDepth> ApplyIcm<TDepth>(
this Image<Bgr, TDepth> source,
string sourceIcm,
string targetIcm)
where TDepth : new()
{
var target = source.CopyBlank();
using (source)
{
using (var b = source.Bitmap)
{
using (var memory = new MemoryStream())
{
b.Save(memory, ImageFormat.Bmp);
memory.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
var ccb = new ColorConvertedBitmap();
ccb.BeginInit();
ccb.Source = bitmapImage;
ccb.SourceColorContext =
new ColorContext(new Uri(sourceIcm));
ccb.DestinationColorContext =
new ColorContext(new Uri(targetIcm));
ccb.EndInit();
var encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(ccb));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
target.Bitmap = new Bitmap(ms);
}
}
}
}
return target;
}
Then I looked at that unsharpen thing and came across this question: How to sharpen an image in OpenCV? which says:
You use a gaussian smoothing filter and subtract the smoothed version from the original image
(I also checked this question to find out what the equivalent emgucv call is Why might EmguCV Gaussian blur not return identical results as OpenCV Gaussian blur?) and came up with this additional extension method:
public static Image<Bgr, TDepth> UnsharpMask<TDepth>(
this Image<Bgr, TDepth> source,
Size kernelSize,
int kernelHoritonalStandardDeviation,
int kernelVerticalStandardDeviation,
double alpha,
double beta,
double gamma)
where TDepth : new()
{
Image<Bgr, TDepth> ret = source.CopyBlank();
CvInvoke.cvSmooth(source,
ret,
SMOOTH_TYPE.CV_GAUSSIAN,
kernelSize.Width,
kernelSize.Height,
kernelHoritonalStandardDeviation,
kernelVerticalStandardDeviation);
CvInvoke.cvAddWeighted(source, alpha, ret, beta, gamma, ret);
return ret;
}
Now I call it like so:
string sourceIcm = #"C:\Windows\System32\spool\drivers\color\ewrgb18.icm";
string targetIcm = #"C:\Windows\System32\spool\drivers\color\ewsrgb.icm";
using(var im = new Image<Bgr, byte>("out.bmp"))
{
using (var icmmed = im.ApplyIcm(sourceIcm, targetIcm))
{
using (var ret = icmmed.UnsharpMask(new Size(0, 0), 5, 5, 2.4, -1.5, 0))
{
ret.Save("ret.bmp");
}
}
}
and this is the result:
Not very good! :-(
I have fiddled with the parameters endlessly but I just cannot work out how (or even if) I can achieve the same result as the Epson tool.
So, my question is:
Does anyone know if it is possible to achieve a result using opencv/emgucv (or even TWAIN - I had a look through the documentation for that and tried adjusting some of the capability parameters but I just made the image worse) that is similar in sharpness to the original image above or is there another technique I should try (could it be that I would need to know some details about the hardware itself in order to achieve correct sharpening)?
I think you should know how using WIA (Windows Image Acquisition) in your project, you may don't need to get access to hardware using opencv. WIA is used for integrating with webcams and scanners. Or, you can use TWAIN as you mentioned
have a look at these examples they could by helpful for your project:
using WIA
and
using TWAIN
Concerning the sharpening, you can use opencv functionality at software level, as another choice to solve your problem

Categories

Resources