I am really new in programming and EemguCV and I am struggling with really basics and I hope you guys can help me out. I am writting a little program for my school to show differnt filters and Imageconverting methods.
I am trying to grab images from a USB webcam and illustrate them in Imageboxes. e.g convertign it into Greyscale(Binary, changing resolutiona and Framerate etc. . I think I am doing something wrong because I am receiveing frame rates less then 1 FPS in from the camera. Also with low resolution (640/300px). My question isyou can help me out to encrease my frame rate. Also it was not possible to grab Image with the QuereFrame() metho, so I went with the Mat Obgect and retreive it to the Images.
Here is my code:
private void Capture_ImageGrabbed(object sender, EventArgs e) \\capure function
{
capture.Retrieve(m);
capture.SetCaptureProperty(CapProp.FrameHeight, resolution_X);
capture.SetCaptureProperty(CapProp.FrameWidth, resolution_Y);
ImgInput = m.ToImage<Bgr, byte>();
ImgGrayInput = m.ToImage<Gray, byte>();
iB_colour_Image.Image = ImgInput;
iB_Grey.Image = ImgGrayInput;
if (imgchange)
{
ImgReference = ImgInput;
ImgGrayReference = ImgReference.Convert<Gray , byte>();
imgchange = false;
}
ImgBinarizedInput = new Image<Gray, byte>(ImgGrayInput.Width, ImgGrayInput.Height);
double thresholdInput = CvInvoke.Threshold(ImgGrayInput, ImgBinarizedInput, tb_value, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
ImgBinarizedReference = new Image<Gray, byte>(ImgGrayReference.Width, ImgGrayReference.Height);
double thresholdReference = CvInvoke.Threshold(ImgGrayReference, ImgBinarizedReference, tb_value, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
iB_Binary.Image = ImgBinarizedInput;
}
private void bt_play_stop_Click(object sender, EventArgs e) \\Buton to start stop the capture
{
if (buttonstate == false)
{
if (capture == null)
{
capture = new VideoCapture(selectedcamera, VideoCapture.API.DShow);
}
capture.Start();
capture.ImageGrabbed += Capture_ImageGrabbed;
buttonstate = true;
bt_play_stop.Text = "Stop";
}
else
{
capture.Stop();
buttonstate = false;
bt_play_stop.Text = "Play";
}
}
Related
I am developing a new UWP app which should monitor sound and fire a event for each sudden sound blow (something like gun fire or clap).
It needs to enable default Audio Input and monitor live audio.
Set audio sensitivity for identifying environment noise and recognizing clap/gun-fire
When there is a high frequency sound like a clap/gun-fire sound (Ideally it should be like configured frequency like +/-40 then it is a gun-fire/clap) then it should call a event.
No need to save Audio
I tried to implement this
SoundMonitoringPage:
public sealed partial class MyPage : Page
{
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
string deviceId = Windows.Media.Devices.MediaDevice.GetDefaultAudioCaptureId(Windows.Media.Devices.AudioDeviceRole.Communications);
gameChatAudioStateMonitor = AudioStateMonitor.CreateForCaptureMonitoringWithCategoryAndDeviceId(MediaCategory.GameChat, deviceId);
gameChatAudioStateMonitor.SoundLevelChanged += GameChatSoundLevelChanged;
//other logic
}
}
Sound Level Change:
private void GameChatSoundLevelChanged(AudioStateMonitor sender, object args)
{
switch (sender.SoundLevel)
{
case SoundLevel.Full:
LevelChangeEvent();
break;
case SoundLevel.Muted:
LevelChangeEvent();
break;
case SoundLevel.Low:
// Audio capture should never be "ducked", only muted or full volume.
Debug.WriteLine("Unexpected audio state change.");
break;
}
}
ENV: windows 10 (v1809) IDE: VS 2017
Not sure if this is the right approach. This is not enabling audio and not hitting the level change event.
I see other options in WinForms & NAudio tutorial here. Probably with Sampling frequency I can check events... Doesn't have must tutorial on using NAudio with UWP to plot the graph and identify the frequency.
Update:
Followed suggestion from #Rob Caplan - MSFT, here is what I ended up with
IMemoryBufferByteAccess.cs
// We are initializing a COM interface for use within the namespace
// This interface allows access to memory at the byte level which we need to populate audio data that is generated
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
void GetBuffer(out byte* buffer, out uint capacity);
}
GunFireMonitorPage.xaml.cs
public sealed partial class GunFireMonitorPage : Page
{
private MainPage _rootPage;
public static GunFireMonitorPage Current;
private AudioGraph _graph;
private AudioDeviceOutputNode _deviceOutputNode;
private AudioFrameInputNode _frameInputNode;
public double Theta;
public DrivePage()
{
InitializeComponent();
Current = this;
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
_rootPage = MainPage.Current;
await CreateAudioGraph();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
_graph?.Dispose();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
}
private unsafe AudioFrame GenerateAudioData(uint samples)
{
// Buffer size is (number of samples) * (size of each sample)
// We choose to generate single channel (mono) audio. For multi-channel, multiply by number of channels
uint bufferSize = samples * sizeof(float);
AudioFrame audioFrame = new AudioFrame(bufferSize);
using (AudioBuffer buffer = audioFrame.LockBuffer(AudioBufferAccessMode.Write))
using (IMemoryBufferReference reference = buffer.CreateReference())
{
// Get the buffer from the AudioFrame
// ReSharper disable once SuspiciousTypeConversion.Global
// ReSharper disable once UnusedVariable
((IMemoryBufferByteAccess) reference).GetBuffer(out var dataInBytes, out var capacityInBytes);
// Cast to float since the data we are generating is float
var dataInFloat = (float*)dataInBytes;
float freq = 1000; // choosing to generate frequency of 1kHz
float amplitude = 0.3f;
int sampleRate = (int)_graph.EncodingProperties.SampleRate;
double sampleIncrement = (freq * (Math.PI * 2)) / sampleRate;
// Generate a 1kHz sine wave and populate the values in the memory buffer
for (int i = 0; i < samples; i++)
{
double sinValue = amplitude * Math.Sin(Theta);
dataInFloat[i] = (float)sinValue;
Theta += sampleIncrement;
}
}
return audioFrame;
}
private void node_QuantumStarted(AudioFrameInputNode sender, FrameInputNodeQuantumStartedEventArgs args)
{
// GenerateAudioData can provide PCM audio data by directly synthesizing it or reading from a file.
// Need to know how many samples are required. In this case, the node is running at the same rate as the rest of the graph
// For minimum latency, only provide the required amount of samples. Extra samples will introduce additional latency.
uint numSamplesNeeded = (uint)args.RequiredSamples;
if (numSamplesNeeded != 0)
{
AudioFrame audioData = GenerateAudioData(numSamplesNeeded);
_frameInputNode.AddFrame(audioData);
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (generateButton.Content != null && generateButton.Content.Equals("Generate Audio"))
{
_frameInputNode.Start();
generateButton.Content = "Stop";
audioPipe.Fill = new SolidColorBrush(Colors.Blue);
}
else if (generateButton.Content != null && generateButton.Content.Equals("Stop"))
{
_frameInputNode.Stop();
generateButton.Content = "Generate Audio";
audioPipe.Fill = new SolidColorBrush(Color.FromArgb(255, 49, 49, 49));
}
}
private async Task CreateAudioGraph()
{
// Create an AudioGraph with default settings
AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
if (result.Status != AudioGraphCreationStatus.Success)
{
// Cannot create graph
_rootPage.NotifyUser($"AudioGraph Creation Error because {result.Status.ToString()}", NotifyType.ErrorMessage);
return;
}
_graph = result.Graph;
// Create a device output node
CreateAudioDeviceOutputNodeResult deviceOutputNodeResult = await _graph.CreateDeviceOutputNodeAsync();
if (deviceOutputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// Cannot create device output node
_rootPage.NotifyUser(
$"Audio Device Output unavailable because {deviceOutputNodeResult.Status.ToString()}", NotifyType.ErrorMessage);
speakerContainer.Background = new SolidColorBrush(Colors.Red);
}
_deviceOutputNode = deviceOutputNodeResult.DeviceOutputNode;
_rootPage.NotifyUser("Device Output Node successfully created", NotifyType.StatusMessage);
speakerContainer.Background = new SolidColorBrush(Colors.Green);
// Create the FrameInputNode at the same format as the graph, except explicitly set mono.
AudioEncodingProperties nodeEncodingProperties = _graph.EncodingProperties;
nodeEncodingProperties.ChannelCount = 1;
_frameInputNode = _graph.CreateFrameInputNode(nodeEncodingProperties);
_frameInputNode.AddOutgoingConnection(_deviceOutputNode);
frameContainer.Background = new SolidColorBrush(Colors.Green);
// Initialize the Frame Input Node in the stopped state
_frameInputNode.Stop();
// Hook up an event handler so we can start generating samples when needed
// This event is triggered when the node is required to provide data
_frameInputNode.QuantumStarted += node_QuantumStarted;
// Start the graph since we will only start/stop the frame input node
_graph.Start();
}
}
GunFireMonitorPage.xaml
<Page
x:Class="SmartPileInspector.xLite.GunFireMonitorPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded"
HorizontalAlignment="Center"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer HorizontalAlignment="Center">
<StackPanel HorizontalAlignment="Center">
<!-- more page content -->
<Grid HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="55"></RowDefinition>
</Grid.RowDefinitions>
</Grid>
<AppBarButton x:Name="generateButton" Content="Generate Audio" Click="Button_Click" MinWidth="120" MinHeight="45" Margin="0,50,0,0"/>
<Border x:Name="frameContainer" BorderThickness="0" Background="#4A4A4A" MinWidth="120" MinHeight="45" Margin="0,20,0,0">
<TextBlock x:Name="frame" Text="Frame Input" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<StackPanel>
<Rectangle x:Name="audioPipe" Margin="0,20,0,0" Height="10" MinWidth="160" Fill="#313131" HorizontalAlignment="Stretch"/>
</StackPanel>
<Border x:Name="speakerContainer" BorderThickness="0" Background="#4A4A4A" MinWidth="120" MinHeight="45" Margin="0,20,0,0">
<TextBlock x:Name="speaker" Text="Output Device" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<!--</AppBar>-->
</StackPanel>
</ScrollViewer>
</Page>
There is no graph generated. And there is continuous beep sound with blue line.
Any help is greatly appreciated
Update: Implemented AudioVisualizer
With the help of AudioVisualizer, I was able to plot the lice audio graph.
AudioGraph _graph;
AudioDeviceInputNode _inputNode;
PlaybackSource _source;
SourceConverter _converter;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_rootPage = MainPage.Current;
_rootPage.SetDimensions(700, 600);
base.OnNavigatedTo(e);
CreateAudioGraphAsync();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
_graph?.Stop();
_graph?.Dispose();
_graph = null;
}
async void CreateAudioGraphAsync()
{
var graphResult = await AudioGraph.CreateAsync(new AudioGraphSettings(Windows.Media.Render.AudioRenderCategory.Media));
if (graphResult.Status != AudioGraphCreationStatus.Success)
throw new InvalidOperationException($"Graph creation failed {graphResult.Status}");
_graph = graphResult.Graph;
var inputNodeResult = await _graph.CreateDeviceInputNodeAsync(MediaCategory.Media);
if (inputNodeResult.Status == AudioDeviceNodeCreationStatus.Success)
{
_inputNode = inputNodeResult.DeviceInputNode;
_source = PlaybackSource.CreateFromAudioNode(_inputNode);
_converter = new SourceConverter
{
Source = _source.Source,
MinFrequency = 110.0f,
MaxFrequency = 3520.0f,
FrequencyCount = 12 * 5 * 5,
FrequencyScale = ScaleType.Linear,
SpectrumRiseTime = TimeSpan.FromMilliseconds(20),
SpectrumFallTime = TimeSpan.FromMilliseconds(200),
RmsRiseTime = TimeSpan.FromMilliseconds(20),
RmsFallTime = TimeSpan.FromMilliseconds(500),
ChannelCount = 1
};
// Note A2
// Note A7
// 5 octaves, 5 bars per note
// Use RMS to gate noise, fast rise slow fall
NotesSpectrum.Source = _converter;
_graph.Start();
}
else
{
_rootPage.NotifyUser("Cannot access microphone", NotifyType.ErrorMessage);
}
}
Now the challenge is how do I wire an event when wave frequency is above a threshold? In that event I would like to count number of shots, timestamp and it's intensity.
Example Sound
Here is my Recording of live sound, as you can here, when there is that big hammer strike (every second or less), I would like to call a event.
You can find the decibels of a frame by finding the average amplitude of all the pcm data from that frame.I believe you want create a graph that handles the input so that looks like this
private static event LoudNoise<double>;
private static int quantum = 0;
static AudioGraph ingraph;
private static AudioDeviceInputNode deviceInputNode;
private static AudioFrameOutputNode frameOutputNode;
public static async Task<bool> CreateInputDeviceNode(string deviceId)
{
Console.WriteLine("Creating AudioGraphs");
// Create an AudioGraph with default settings
AudioGraphSettings graphsettings = new AudioGraphSettings(AudioRenderCategory.Media);
graphsettings.EncodingProperties = new AudioEncodingProperties();
graphsettings.EncodingProperties.Subtype = "Float";
graphsettings.EncodingProperties.SampleRate = 48000;
graphsettings.EncodingProperties.ChannelCount = 2;
graphsettings.EncodingProperties.BitsPerSample = 32;
graphsettings.EncodingProperties.Bitrate = 3072000;
//settings.DesiredSamplesPerQuantum = 960;
//settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.ClosestToDesired;
CreateAudioGraphResult graphresult = await AudioGraph.CreateAsync(graphsettings);
if (graphresult.Status != AudioGraphCreationStatus.Success)
{
// Cannot create graph
return false;
}
ingraph = graphresult.Graph;AudioGraphSettings nodesettings = new AudioGraphSettings(AudioRenderCategory.GameChat);
nodesettings.EncodingProperties = AudioEncodingProperties.CreatePcm(48000, 2, 32);
nodesettings.DesiredSamplesPerQuantum = 960;
nodesettings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.ClosestToDesired;
frameOutputNode = ingraph.CreateFrameOutputNode(ingraph.EncodingProperties);
quantum = 0;
ingraph.QuantumStarted += Graph_QuantumStarted;
DeviceInformation selectedDevice;
string device = Windows.Media.Devices.MediaDevice.GetDefaultAudioCaptureId(Windows.Media.Devices.AudioDeviceRole.Default);
if (!string.IsNullOrEmpty(device))
{
selectedDevice = await DeviceInformation.CreateFromIdAsync(device);
} else
{
return false;
}
CreateAudioDeviceInputNodeResult result =
await ingraph.CreateDeviceInputNodeAsync(MediaCategory.Media, nodesettings.EncodingProperties, selectedDevice);
if (result.Status != AudioDeviceNodeCreationStatus.Success)
{
// Cannot create device output node
return false;
}
deviceInputNode = result.DeviceInputNode;
deviceInputNode.AddOutgoingConnection(frameOutputNode);
frameOutputNode.Start();
ingraph.Start();
return true;
}
private static void Graph_QuantumStarted(AudioGraph sender, object args)
{
if (++quantum % 2 == 0)
{
AudioFrame frame = frameOutputNode.GetFrame();
float[] dataInFloats;
using (AudioBuffer buffer = frame.LockBuffer(AudioBufferAccessMode.Write))
using (IMemoryBufferReference reference = buffer.CreateReference())
{
// Get the buffer from the AudioFrame
((IMemoryBufferByteAccess)reference).GetBuffer(out byte* dataInBytes, out uint capacityInBytes);
float* dataInFloat = (float*)dataInBytes;
dataInFloats = new float[capacityInBytes / sizeof(float)];
for (int i = 0; i < capacityInBytes / sizeof(float); i++)
{
dataInFloats[i] = dataInFloat[i];
}
}
double decibels = 0f;
foreach (var sample in dataInFloats)
{
decibels += Math.Abs(sample);
}
decibels = 20 * Math.Log10(decibels / dataInFloats.Length);
// You can pass the decibel value where ever you'd like from here
if (decibels > 10)
{
LoudNoise?.Invoke(this, decibels);
}
}
}
P.S. I did all of this static but naturally it'll work if it's all in the same instance
I also copied this partially from my own project so it may have some parts I forgot to trim. Hope it helps
Answering the "is this the right approach" question: no, the AudioStateMonitor will not help with the problem.
AudioStateMonitor.SoundLevelChanged tells you if the system is ducking your sound so it doesn't interfere with something else. For example, it may mute music in favour of the telephone ringer. SoundLevelChanged doesn't tell you anything about the volume or frequency of recorded sound, which is what you'll need to detect your handclap.
The right approach will be along the lines of using an AudioGraph (or WASAPI, but not from C#) to capture the raw audio into an AudioFrameOutputNode to process the signal and then run that through an FFT to detect sounds in your target frequencies and volumes. The AudioCreation sample demonstrates using an AudioGraph, but not specifically AudioFrameOutputNode.
Per https://home.howstuffworks.com/clapper1.htm clapping will be in a frequency range of 2200Hz to 2800Hz.
Recognizing gunshots looks like it's significantly more complicated, with different guns having very different signatures. A quick search found several research papers on this rather than trivial algorithms. I suspect you'll want some sort of Machine Learning to classify these. Here's a previous thread discussing using ML to differ between gunshots and non-gunshots: SVM for one Vs all acoustic signal classification
I have this application in C# on VS2012, in which I need to generate Crystal Report 13.0.x. This application has been running fine for last 2 years or so . Recently did some addons and after that its giving error
Load Report Fail
However strange thing is that , in a day around 100 times this Crystal report is generated and in between it gives out that error. After the whole application has to be exited and then it works fine too. Because of this I am not abel to replicate the error at me end.
Here my code:
public partial class ChangeOrderList : Form
{
ConnectionClass connectionclass = new ConnectionClass();
NewOrderBL NObl = new NewOrderBL();
DailySalesReportBL DSRbl = new DailySalesReportBL();
public ChangeOrderList()
{
InitializeComponent();
}
private void ChangeOrderList_Load(object sender, EventArgs e)
{
/////////////////////////To count Lunch Buffet///////////////////
DataTable dtlb = DSRbl.selectBuffet(DateTime.Today.Date.ToString(), DateTime.Today.Date.ToString());
string date = dtlb.Rows[0][0].ToString();
////////////////////////////////////////////////////////////////
try
{
string sqlqry = "Select KOTNo,TableNo,WaiterName,ItemCode,ItemName,Quantity,Status,Foodtype from tblOrderChange where KOTNo=#kotno and Quantity>'0.00' and (Category!='Appetizer' and Category!='Indian Breads' and Category!='Desserts' and Category!='Beverages' and Category!='Tandoori')";
SqlCommand cmd = new SqlCommand(sqlqry, connectionclass.con);
cmd.Parameters.AddWithValue("#kotno", NewOrderBL.KOTNo);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet1 ds = new DataSet1();
adapter.Fill(ds, "tblOrderChange");
if (ds.Tables["tblOrderChange"].Rows.Count == 0)
{
MessageBox.Show("No Data Found", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
if (deliverybl.order == "Delivery")
{
//PrintDelivery printorder = new PrintDelivery();
ChangeOrderdelivery printorder = new ChangeOrderdelivery();
printorder.SetDataSource(ds);
crystalReportViewer1.ReportSource = printorder;
System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
printorder.PrintOptions.PrinterName = printDocument.PrinterSettings.PrinterName;
printorder.PrintOptions.PrinterName = "EPSON TM-U220 Receipt";
printorder.PrintToPrinter(1, false, 0, 0);
}
else
{
crystalReportViewer1.RefreshReport();
ParameterFields paramFields = new ParameterFields();
ParameterField paramField = new ParameterField();
ParameterDiscreteValue paramDiscreteValue = new ParameterDiscreteValue();
paramField.Name = "LBqty";
paramDiscreteValue.Value = date;
paramField.CurrentValues.Add(paramDiscreteValue);
paramFields.Add(paramField);
PrintChangeOrderList printchangeorder = new PrintChangeOrderList();
printchangeorder.SetDataSource(ds);
printchangeorder.SetParameterValue("LBqty", date);
crystalReportViewer1.ReportSource = printchangeorder;
System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
printchangeorder.PrintOptions.PrinterName = printDocument.PrinterSettings.PrinterName;
printchangeorder.PrintOptions.PrinterName = "EPSON TM-U220 Receipt";
printchangeorder.PrintToPrinter(1, false, 0, 0);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally { connectionclass.disconnect(); }
onlinebl.crystalreport = "";
this.DialogResult = DialogResult.OK;
}
private void btnExit_Click(object sender, EventArgs e)
{
onlinebl.crystalreport = "";
this.DialogResult = DialogResult.OK;
}
I have been banging my head for long . Every where I search it says about the path and I am not using the path anywhere so not able to understand where the fault is.
If you need any more info or the code please let me know. Thanks
Check your class:
<pre>
ChangeOrderdelivery printorder = new ChangeOrderdelivery();
printorder.SetDataSource(ds);
crystalReportViewer1.ReportSource = printorder;
this one has a report Path hidding i guess
ChangeOrderdelivery printorder = new ChangeOrderdelivery();
</pre>
I just deleted internet temp files and after that client has not yet complained about the error. So I am keeping an eye on it if it resolved the issue
Testing this to incorporate into Win 10 UWP app to scan 1D barcodes (format 39 & 128). I have updated latest through nuget 2.0.4.46. Referenced post at http://www.yortondotnet.com/2015/07/mobile-barcode-scanning-with-zxingnet.html regarding some options setting prior to scan() with no luck. The scanner (camera) opens but never recognizes a barcode scan successfully - or failure for that matter. It seems nothing is happening whatsoever. I have included straight, pertinent sample code with some options modifications for review. I have gotten Scandit API to work and was going to try Manateeworks but both are really costly and not an option. I am developing on Surface Pro 3 (Win 10) and that build will also be target machines when complete.
public sealed partial class MainPage : Page
{
UIElement customOverlayElement = null;
MobileBarcodeScanner scanner;
public MainPage()
{
this.InitializeComponent();
//Create a new instance of our scanner
scanner = new MobileBarcodeScanner(this.Dispatcher);
scanner.Dispatcher = this.Dispatcher;
}
private void buttonScanDefault_Click(object sender, RoutedEventArgs e)
{
//Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of our default overlay
scanner.TopText = "Hold camera up to barcode";
scanner.BottomText = "Camera will automatically scan barcode\r\n\r\nPress the 'Back' button to Cancel";
// GWS Set Options
var options = new MobileBarcodeScanningOptions();
options.PossibleFormats = new List<ZXing.BarcodeFormat>() {
ZXing.BarcodeFormat.CODE_39, ZXing.BarcodeFormat.CODE_128
};
options.AutoRotate = false;
options.TryHarder = false;
options.TryInverted = false;
//Start scanning
scanner.Scan(options).ContinueWith(t =>
{
if (t.Result != null)
HandleScanResult(t.Result);
});
}
private void buttonScanContinuously_Click(object sender, RoutedEventArgs e)
{
//Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of our default overlay
scanner.TopText = "Hold camera up to barcode";
scanner.BottomText = "Camera will automatically scan barcode\r\n\r\nPress the 'Back' button to Cancel";
// GWS Set Options
var options = new MobileBarcodeScanningOptions();
options.PossibleFormats = new List<ZXing.BarcodeFormat>() {
ZXing.BarcodeFormat.CODE_39, ZXing.BarcodeFormat.CODE_128
};
options.AutoRotate = false;
options.TryHarder = false;
options.TryInverted = false;
//Start scanning
scanner.ScanContinuously(options, async (result) =>
{
var msg = "Found Barcode: " + result.Text;
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
await MessageBox(msg);
});
});
}
async void HandleScanResult(ZXing.Result result)
{
string msg = "";
if (result != null && !string.IsNullOrEmpty(result.Text))
msg = "Found Barcode: " + result.Text;
else
msg = "Scanning Canceled!";
await MessageBox(msg);
}
}
Simon,
I have the exact same problem. I tested your code with the latest nuget 2.1.47, the problem still exists.
You need to download the latest from Github and add the following projects (or DLLs) to your project:
ZXing.Net (project: zxing.portable.csproj)
ZXing.Net.Mobile.Core
ZXing.Net.Mobile.WindowsUniversal
I have tested your code and it works fine. I hope this help.
Cheers,
Sam
I think that the problem in the hardware you are testing with. Surface Pro 3 (Win 10) does not have an auto focus camera. I've never succeed to scan with ZXing using my Surface Pro 3, while the same application is working fine with my other windows 10 device.
I am making a top notification animation, but I don't know how to make the animation synchronous until the animation finishes. Here is the code I have:
public Storyboard prepareShowStory(int count, NotificationControl notifyControl)
{
notifyControl.textBlock1.Text = "Got" + count.ToString() + "Message";
notifyControl.RenderTransform = new CompositeTransform();
Storyboard story = new Storyboard();
//From here until the annimation finish and remove LayoutRoot.Resources.Clear();
LayoutRoot.Resources.Add("unique_id", story);
story.Completed += (object sender, EventArgs e) =>
{
story.Stop();
story.Children.Clear();
App.ViewModel.myAction -= CompletedRefresh;
LayoutRoot.Resources.Clear();
//To here.
};
story.Begin();
DoubleAnimation animation;
animation = new DoubleAnimation();
animation.AutoReverse = true;
animation.From = -64;
animation.To = 60;
animation.Duration = new Duration(TimeSpan.FromMilliseconds(1600));
animation.EasingFunction = _EasingFunction;
Storyboard.SetTargetName(animation, notifyControl.Name);
Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateY)"));
story.Children.Add(animation);
return story;
}
You could check the ResourceDictionary before adding to it.
if(!LayoutRoot.Resources.Contains("unique_id"))
LayoutRoot.Resources.Add("unique_id", story);
I try to get the high qulity antialiasing from a tuturial I found on the internet (http://www.rkoenig.eu/index.php?option=com_content&view=article&id=21:chapter-3-das-erste-echte-3d-objekt&catid=6:directx10-basics&Itemid=3). But did not achieve a very good solution.
I already set the multisampling to the maximum:
m_swapChainDesc.SampleDescription = new DXGI.SampleDescription(8,0);
To me it appears as the pixel size of the rendered image is larger than the actual pixel size of my screen.
Thank you very much in advance for your valuable inputs
here is the complete code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SlimDX;
using DX10 = SlimDX.Direct3D10;
using DXGI = SlimDX.DXGI;
namespace TutorialSeries.DirectX10.Chapter3
{
public partial class MainWindow : Form
{
private DX10.Device m_device;
private DXGI.SwapChainDescription m_swapChainDesc;
private DXGI.SwapChain m_swapChain;
private DXGI.Factory m_factory;
private DX10.RenderTargetView m_renderTarget;
private bool m_initialized;
private SimpleBox m_simpleBox;
private Matrix m_viewMatrix;
private Matrix m_projMatrix;
private Matrix m_worldMatrix;
private Matrix m_viewProjMatrix;
public MainWindow()
{
InitializeComponent();
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.Opaque, true);
}
/// <summary>
/// Initializes device and other resources needed for rendering. Returns true, if successful.
/// </summary>
private bool Initialize3D()
{
try
{
m_device = new DX10.Device(DX10.DriverType.Warp, DX10.DeviceCreationFlags.SingleThreaded);
m_factory = new DXGI.Factory();
m_swapChainDesc = new DXGI.SwapChainDescription();
m_swapChainDesc.OutputHandle = this.Handle;
m_swapChainDesc.IsWindowed = true;
m_swapChainDesc.BufferCount = 1;
m_swapChainDesc.Flags = DXGI.SwapChainFlags.AllowModeSwitch;
m_swapChainDesc.ModeDescription = new DXGI.ModeDescription(
this.Width,
this.Height,
new Rational(60, 1),
DXGI.Format.R8G8B8A8_UNorm);
m_swapChainDesc.SampleDescription = new DXGI.SampleDescription(8,0);
m_swapChainDesc.SwapEffect = DXGI.SwapEffect.Discard;
m_swapChainDesc.Usage = DXGI.Usage.RenderTargetOutput;
m_swapChain = new DXGI.SwapChain(m_factory, m_device, m_swapChainDesc);
DX10.Viewport viewPort = new DX10.Viewport();
viewPort.X = 0;
viewPort.Y = 0;
viewPort.Width = this.Width;
viewPort.Height = this.Height;
viewPort.MinZ = 0f;
viewPort.MaxZ = 1f;
//DX10.Texture2D backBuffer = m_swapChain.GetBuffer<DX10.Texture2D>(0);
DX10.Texture2D Texture = DX10.Texture2D.FromSwapChain<DX10.Texture2D>(m_swapChain,0);
//m_renderTarget = new DX10.RenderTargetView(m_device, backBuffer);
//DX10.RenderTargetViewDescription renderDesc = new DX10.RenderTargetViewDescription();
//renderDesc.FirstArraySlice = 0;
//renderDesc.MipSlice = 0;
m_renderTarget = new DX10.RenderTargetView(m_device, Texture);
Texture.Dispose();
DX10.RasterizerStateDescription rsd = new DX10.RasterizerStateDescription();
rsd.CullMode = DX10.CullMode.Back;
rsd.FillMode = DX10.FillMode.Wireframe;
rsd.IsMultisampleEnabled = true;
rsd.IsAntialiasedLineEnabled = false;
rsd.IsDepthClipEnabled = false;
rsd.IsScissorEnabled = false;
DX10.RasterizerState RasterStateWireFrame = DX10.RasterizerState.FromDescription(m_device,rsd);
DX10.BlendStateDescription blendDesc = new DX10.BlendStateDescription();
blendDesc.BlendOperation = DX10.BlendOperation.Add;
blendDesc.AlphaBlendOperation = DX10.BlendOperation.Add;
blendDesc.SourceAlphaBlend = DX10.BlendOption.Zero;
blendDesc.DestinationAlphaBlend = DX10.BlendOption.Zero;
blendDesc.SourceBlend = DX10.BlendOption.SourceColor;
blendDesc.DestinationBlend = DX10.BlendOption.Zero;
blendDesc.IsAlphaToCoverageEnabled = false;
blendDesc.SetWriteMask(0, DX10.ColorWriteMaskFlags.All);
blendDesc.SetBlendEnable(0, true);
DX10.BlendState m_blendState = DX10.BlendState.FromDescription(m_device, blendDesc);
m_device.Rasterizer.State = RasterStateWireFrame;
m_device.Rasterizer.SetViewports(viewPort);
m_device.OutputMerger.BlendState = m_blendState;
m_device.OutputMerger.SetTargets(m_renderTarget);
m_viewMatrix = Matrix.LookAtLH(
new Vector3(0f, 0f, -4f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 1f, 0f));
m_projMatrix = Matrix.PerspectiveFovLH(
(float)Math.PI * 0.5f,
this.Width / (float)this.Height,
0.1f, 100f);
m_viewProjMatrix = m_viewMatrix * m_projMatrix;
m_worldMatrix = Matrix.RotationYawPitchRoll(0.85f, 0.85f, 0f);
m_simpleBox = new SimpleBox();
m_simpleBox.LoadResources(m_device);
m_initialized = true;
}
catch (Exception ex)
{
MessageBox.Show("Error while initializing Direct3D10: \n" + ex.Message);
m_initialized = false;
}
return m_initialized;
}
/// <summary>
/// Rendering is done during the standard OnPaint event
/// </summary>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (m_initialized)
{
m_device.ClearRenderTargetView(m_renderTarget, new Color4(Color.CornflowerBlue));
m_simpleBox.Render(m_device, m_worldMatrix, m_viewProjMatrix);
m_swapChain.Present(0, DXGI.PresentFlags.None);
}
}
/// <summary>
/// Initialize 3D-Graphics within OnLoad event
/// </summary>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Initialize3D();
}
}
}
This is an old question but it's a shame it never got answered; I stumbled across it on Google so I figure answering it may help someone else in the future...
First of all, Pascal, you did NOT set MSAA to the maximum... You're using 8:0, which means 8 samples at a quality of 0 (zero)... definitely not the maximum. What the "max" is depends on the GPU installed on the local machine. So it varies from PC to PC. That's why a DirectX application needs to use DXGI to properly enumerate hardware devices and determine what settings are valid. This is no trivial topic and will require you to do some research and practice of your own. The DirectX SDK Documentation and samples/tutorials are a great starting place, and there's a lot of other materials to be found online. But on my machine, for instance, my GTX-580 GPU can support 8:16 MSAA (possibly higher, but haven't checked).
So you need to learn to use DXGI to enumerate your graphics cards and monitors and figure out what MSAA levels (and other graphics features/settings) it can support. That's the only way you'll ever figure out the "max" MSAA settings or the correct refresh rate of your monitor, for example. If you're clever you will write yourself a small library or component for your game engine that will enumerate hardware devices for you and figure out the optimal graphics settings so you won't have to re-do this over and over for future projects.
Regards,
--ATC--