Page 1 of 1
Texture Dynamic
Posted: Fri Nov 25, 2016 7:00 pm
by juergen
Hi,
I'm working on a new version of our software for data visualization. In one mode is a CCD camera the source for images.
I want to display the images as fast as possible. I saw some Direct3D examples where images coming from a web-cam were displayed in realtime using a dynamic TextureBuffer.
For normal sized images it's not a problem, I got a solution in the past and it worked. (
http://forum.arction.com/viewtopic.php? ... xture#p695)
Now many customers buy 5MP cameras for microscopy solutions. For this it's too slow (sometimes 1-3 frames/second).
So my question:
Is it possible or maybe possible to add a function to use a TextureBuffer directly which I can update by code?
I think that would be the fastest solution for images and also interesting for others.
Thanks and best regards,
Jürgen
Re: Texture Dynamic
Posted: Sat Nov 26, 2016 12:27 pm
by ArctionPasi
Hi Jürgen,
Currently we have almost direct approach available:
Using IntensityGridSeries with PixelRendering = true, and using SetColorsData + InvalidateColorsOnly approach
I'm creating a image data on the fly here. Using 2500 x 2000 resolution (5 MP), it runs approx 20 FPS with NVidia GTX 960.
Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading.Tasks;
using System.Windows.Threading;
using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Views;
using Arction.Wpf.Charting.Views.ViewXY;
using Arction.Wpf.Charting.SeriesXY;
using Arction.Wpf.Charting.Axes;
namespace WpfApplicationFastVideoUpdaterIntensitySeries
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
LightningChartUltimate _chart;
System.Threading.CancellationTokenSource _cancelImageUpdater = new System.Threading.CancellationTokenSource();
int _round = 0;
int[][] _pixelData;
const int ImageWidth = 2500;
const int ImageHeight = 2000;
public MainWindow()
{
InitializeComponent();
CreateChart();
Task taskImageUpdater = new Task(() => { UpdateNextImageLoop(); }, _cancelImageUpdater.Token);
taskImageUpdater.Start();
}
void CreateChart()
{
_chart = new LightningChartUltimate();
gridMain.Children.Add(_chart);
_chart.BeginUpdate();
ViewXY v = _chart.ViewXY;
IntensityGridSeries grid = new IntensityGridSeries(v, v.XAxes[0], v.YAxes[0]);
grid.PixelRendering = true;
grid.SetRangesXY(0, ImageWidth, 0, ImageHeight);
grid.Fill = IntensityFillStyle.FromSurfacePoints;
CreatePixelData();
grid.SetColorsData(_pixelData, IntensityGridValuesDataOrder.RowsColumns);
v.IntensityGridSeries.Add(grid);
v.XAxes[0].ValueType = AxisValueType.Number;
v.XAxes[0].SetRange(0, ImageWidth);
v.YAxes[0].SetRange(0, ImageHeight);
v.LegendBox.Visible = false;
_chart.EndUpdate();
}
void UpdateNextImageLoop()
{
while (!_cancelImageUpdater.IsCancellationRequested)
{
Dispatcher.Invoke((Action)delegate { UpdateNextImage(); });
System.Threading.Thread.Sleep(1);
}
}
void UpdateNextImage()
{
_chart.BeginUpdate();
//Update image data
CreatePixelData();
//Set it to series
_chart.ViewXY.IntensityGridSeries[0].InvalidateColorsOnly();
//Update chart title
_chart.Title.Text = (_round++).ToString("0");
_chart.EndUpdate();
}
void CreatePixelData()
{
if (_pixelData == null)
{
_pixelData = new int[ImageHeight][];
}
Parallel.For(0, ImageHeight, (row) =>
{
if(_pixelData[row] == null)
_pixelData[row] = new int[ImageWidth];
byte A, R, G, B;
for (int col = 0; col < ImageWidth; col++)
{
B = (byte)(col % 255);
G = (byte)(row % 255);
R = (byte)(_round * 4 % 255);
A = 255;
_pixelData[row][col] = (int)(A << 24 | R << 16 | G << 8 | B);
}
});
}
}
}
How does this fullfill your requirements?
Making it yet faster... might be difficult and require excessive changes in our API.