I am using Alturos.YOLO with Emgu CV 3.2 (World.dll) in a C# WPF Application. I am testing this app on an 8GB RAM. But, it is VERY slow. I don't know what seems to be the problem. Here is my code:
private void Timer_Tick(object sender, EventArgs e)
{
var img = capture.QueryFrame();
videoViewer.Source = ToBitmapSource(img);
var memoryStream = new MemoryStream();
img.Bitmap.Save(memoryStream, ImageFormat.Png);
var _items = yolo.Detect(memoryStream.ToArray()).ToList();
var graphics = Graphics.FromImage(img.Bitmap);
var brush = new SolidBrush(Color.LightGreen);
foreach (var item in _items)
{
var x = item.X;
var y = item.Y;
var width = item.Width;
var height = item.Height;
var type = item.Type; // class name of the object
var rect = new Rectangle(x, y, width, height);
var pen = new Pen(Color.LightGreen, 6);
var point = new System.Drawing.Point(x + width / 2, y + height / 2);
graphics.DrawRectangle(pen, rect);
graphics.DrawString($"{item.Type} : {item.Height} * {item.Width}", new Font("Arial", 23f), brush, point);
MessageBox.Show(type);
}
}
You can try one of two things, or both, either reducing the number of classes in your YOLO database to the objects you target only, here is some details, or try to use GPU to accelerate detection using CUDA C++, but you must own a NVidia card. These two methods worked for me and reduced detection time greatly.
Related
I made a windows service that's runs in background service and listening for web app to order to print.
the web app send a pdf file and width and height of the printer paper with count of copies
I wrote the code this way
convert pdf to image
public Image ConverPdfToImage(IFormFile pdfFile)
{
if (pdfFile == null || pdfFile.Length==0)
{
return null;
}
var documemt = new Spire.Pdf.PdfDocument();
documemt.LoadFromStream(pdfFile.OpenReadStream());
Image image = documemt.SaveAsImage(0,PdfImageType.Bitmap);
return image;
}
then the event handler
private void PrintPage(object sender, PrintPageEventArgs ev,Image img)
{
Rectangle pageBounds = ev.PageBounds;
int x = pageBounds.Left - (int) ev.PageSettings.HardMarginX;
int y = pageBounds.Top - (int) ev.PageSettings.HardMarginY;
int width = pageBounds.Width;
int height = pageBounds.Height;
ev.Graphics.CompositingQuality = CompositingQuality.HighQuality;
ev.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
ev.Graphics.SmoothingMode = SmoothingMode.HighQuality;
ev.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
local = new Rectangle(x, y, width, height);
ev.Graphics.FillRectangle(Brushes.Transparent, local);
ev.Graphics.DrawImage(img, local);
}
and the final function that prints
PrintDocument printDocument = new PrintDocument();
printDocument.PrinterSettings.PrinterName = form.Printer;
printDocument.DefaultPageSettings.Landscape = form.Landscape;
printDocument.DefaultPageSettings.PrinterSettings.Copies = form.Count;
printDocument.DefaultPageSettings.PaperSize =GetPaperSize(form.Width, form.Height);
printDocument.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
Image img = ConverPdfToImage(form.PrintFile);
printDocument.PrintPage += (sender, args) => this.PrintPage(sender,args,img);
printDocument.Print();
the printDocument is from System.Drawing
It makes correct size in printer
printer are for lables and they have label papers with custom size
but the printed paper is blur and hard to read
some of it is so messed up and dirty
glad to help me make print sharp and good quality
I have successfully printed a windows form, but all the text is slightly blurry. I have concluded that this is a result of the resolution of the screen being much less than the resolution the printer uses. Is there a fundamental flaw in my approach or is there a way to reformat the text prior to printing so that it comes out crisp?
void PrintImage(object o, PrintPageEventArgs e)
{
int x = SystemInformation.WorkingArea.X;
int y = SystemInformation.WorkingArea.Y;
int width = panel1.Width;
int height = panel1.Height;
Rectangle bounds = new Rectangle(x, y, width, height);
Bitmap img = new Bitmap(width, height);
this.DrawToBitmap(img, bounds);
Point p = new Point(100, 100);
e.Graphics.DrawImage(img, p);
}
private void BtnPrint_Click(object sender, EventArgs e)
{
btnPrint.Visible = false;
btnCancel.Visible = false;
if(txtNotes.Text == "Notes:" || txtNotes.Text == "")
{
txtNotes.Visible = false;
}
PrintDocument pd = new PrintDocument();
pd.PrintPage += new PrintPageEventHandler(PrintImage);
pd.Print();
}
Is there a fundamental flaw in my approach [...] ?
Yes.
You take the size of panel1 to calculate the size of the image. Later, you let this draw to the image, but this is the form, not the panel.
What makes you think that SystemInformation.WorkingArea is related to the window you want to print?
You should take a bit more care of disposable objects.
[...] is there a way to reformat the text prior to printing so that it comes out crisp?
There's not a general way which would allow you to scale all other controls as well.
However, instead of blurry text, you can get crisp pixelated text by scaling the bitmap up by a certain factor using the NearestNeighbor mechanism.
Here's the difference in a PDF generated without scaling (left) and a factor of 3 scaling (right) at the same zoom level in Acrobat Reader (click to enlarge):
Here's the scaling code, also without fixing any disposable issues:
this.DrawToBitmap(img, bounds);
Point p = new Point(100, 100);
img = ResizeBitmap(img, 3);
e.Graphics.DrawImage(img, p);
}
private static Bitmap ResizeBitmap(Bitmap source, int factor)
{
Bitmap result = new Bitmap(source.Width*factor, source.Height*factor);
result.SetResolution(source.HorizontalResolution*factor, source.VerticalResolution*factor);
using (Graphics g = Graphics.FromImage(result))
{
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(source, 0, 0, source.Width*factor, source.Height*factor);
}
return result;
}
I am looking for a "clean" way to load rasters to my c# code. By raster I mean any (or at least some) XYZ file that QGis or ArcGis are able to load: .tif, .rrd ...
I am using NetTopologySuite. This library works perfectly for shapefiles, which makes me think there could be a raster reader. I have been trying to focus my research under the NetTopologySuite.IO namespace, which contains quite a few Readers.
I have tagged this post with NetTopologySuite hoping that some c#-savvy knows a bit more than me about this particular library.
I used LibTiff.Net for .tif, but I had no requirement for any other format. The UpperLeft and BottomRight properties are used to position the Image on a world map. I don't deal with the model transform case because it's very complicated and - again - no requirement to do so at the moment.
var imageStreamSource = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
var bitmapSource = decoder.Frames[0];
// Draw the Image
Image = bitmapSource.ToBitmap();
using (var tiff = Tiff.Open(Filename, "r"))
{
Height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
Width = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
// see http://www.remotesensing.org/geotiff/spec/geotiff2.6.html#2.6.1
var modelPixelScaleTag = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
var modelTiepointTag = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);
//var modelTransformTag = tiff.GetField(TiffTag.GEOTIFF_MODELTRANSFORMATIONTAG);
var modelPixelScale = modelPixelScaleTag[1].GetBytes();
var ScaleX = BitConverter.ToDouble(modelPixelScale, 0);
var ScaleY = BitConverter.ToDouble(modelPixelScale, 8) * -1;
if (modelTiepointTag != null)
{
var modelTransformation = modelTiepointTag[1].GetBytes();
var originLon = BitConverter.ToDouble(modelTransformation, 24);
var originLat = BitConverter.ToDouble(modelTransformation, 32);
// origin is the center of the pixel, so offset to
var startLat = originLat + (ScaleY / 2.0);
var startLon = originLon + (ScaleX / 2.0);
UpperLeft = new Position(startLat, startLon);
BottomRight = new Position(startLat + ScaleY * Height, startLon + ScaleX * Width);
}
//else if (modelTransformTag != null)
//{
// this is very complicated
//}
else
{
throw new Exception("Couldn't understand the TIFF format");
}
}
I'm trying to add a dashline for a graph but it keeps coming out as a solid line. How can I fix that?
static public NPlot.Bitmap.PlotSurface2D getDashlineGraph(int itemID, int width, int height)
{
NPlot.Bitmap.PlotSurface2D plot = new NPlot.Bitmap.PlotSurface2D(width, height);
plot.BackColor = Color.WhiteSmoke;
plot.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
LinePlot TotaldashLine = new LinePlot(straightline, timer);
float[] pattern = { 5.0f, 10.0f };
TotaldashLine.Pen = new Pen(Color.Green,0.5f);
TotaldashLine.Pen.DashPattern = pattern;
plot.Add(TotaldashLine, NPlot.PlotSurface2D.XAxisPosition.Bottom, NPlot.PlotSurface2D.YAxisPosition.Right, 100);
Grid oGrid = new Grid();
oGrid.HorizontalGridType = Grid.GridType.Coarse;
oGrid.VerticalGridType = Grid.GridType.Coarse;
plot.Add(oGrid);
plot.Refresh();
return plot;
}
You need to specify that you want your Pen to draw dashed using Pen.DashStyle:
TotaldashLine.Pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
Once you have done that, you can additionally customize the lengths of dashes and gaps using the Pen.DashPattern as you have.
I'm using DrawingContext.DrawText and DrawingContext.PushTransfrom to create rotated text on Visual Layer in WPF but as you see in the image below, the rotated text is rather blurry in some areas of the image..
Is there any option I can use to improve this? The Arial font is used for the text.
public class BeamTextDrawing : FrameworkElement
{
private readonly VisualCollection _visuals;
public BeamTextDrawing(double scale)
{
if (scale <= 0)
{
scale = 1;
}
var typeface = Settings.BeamTextTypeface;
var cultureinfo = Settings.CultureInfo;
var flowdirection = Settings.FlowDirection;
var textsize = Settings.BeamTextSize / scale;
var beamtextcolor = Settings.InPlanBeamTextColor;
_visuals = new VisualCollection(this);
foreach (var beam in Building.BeamsInTheElevation)
{
var drawingVisual = new DrawingVisual();
using (var dc = drawingVisual.RenderOpen())
{
var text = Convert.ToString(beam.Section.Id);
//text = scale.ToString();
var ft = new FormattedText(text, cultureinfo, flowdirection,
typeface, textsize, beamtextcolor)
{
TextAlignment = TextAlignment.Center
};
var x1 = beam.ConnectivityLine.I.X;
var y1 = beam.ConnectivityLine.I.Y;
var x2 = beam.ConnectivityLine.J.X;
var y2 = beam.ConnectivityLine.J.Y;
var v1 = new Point(x2, y2) - new Point(x1, y1);
var v2 = new Vector(1, 0);
var hwidth = textsize;
var l = Geometrics.GetOffset(x1, y1, x2, y2, hwidth + 5/scale);
var angle = Vector.AngleBetween(v1, v2);
var x = 0.5 * (l.X1 + l.X2);
var y = 0.5 * (l.Y1 + l.Y2);
var r = new RotateTransform(angle, x, SelectableModel.FlipYAxis(y));
dc.PushTransform(r);
dc.DrawText(ft, SelectableModel.FlipYAxis(x, y));
}
_visuals.Add(drawingVisual);
}
}
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}
}
Update:
Here is the image after using this code:
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
I'm still getting blurry results. Look at the middle beam text at the lower part of the image.
Check out this article - Pixel Snapping in WPF Applications
Since WPF uses device independent pixels it can create irregular edge rendering due to anti-aliasing when it undergoes transformation. Pixel snapping is a means to suppress these visual artifacts by applying small offsets to the geometry of the visual to align the geometry to device pixels.
Setting the SnapsToDevicePixels Property to "True" for your UI elements should be able to fix your issue.