Displaying .ply Point Cloud in C# using Helix-Toolkit - c#

I'm trying to create a Point Cloud from a .ply File which holds vertices
(v x y z r g b) and their color recorded from a Kinect v2. What I've tried so far:
At first I used MeshLab to check whether my .ply File is correct. It is. So I tried to export the .ply file as .obj to use Helix-Toolkits
HelixToolkit.Wpf.ModelImporter
However, this gives me a blank screen, both when using my own code and the ModelViewer in the Helix-Toolkit Examples. This is probably due to the fact that the ply file holds no information about the faces.
1. Is there a simple way to create an obj file from ply, adding faces in the process?
2. Is there another - possibly better way - to create Points from the ply file and displaying them on screen using Helix?

I'll tackle your second question, as I have no knowledge with regards to your first question.
Assuming you can read in the vertex data,
Read the cloud data into a collection structure like a Point3D list.
Point3DCollection dataList = new Point3DCollection();
//read from ply file and append the positions to the dataList. i.e. dataList.Add(new Point3D(x,y,x));
PointsVisual3D cloudPoints = new PointsVisual3D { Color = Colors.Red, Size = 5 };
cloudPoints.Points = dataList;
In your XAML give the helix viewport a name so it can be refenced in C#
<h:HelixViewport3D x:Name="HViewPort">
<h:DefaultLights/>
</h:HelixViewport3D>
In c#
HViewPort.Children.Add(cloudPoints);
NB: This will display all the points with the same colour that was specified on initialisation. So it maybe worth retaining the rgb values of your data in a seperate list.
To date I have no idea of how to assign the colour to individual PointVisual3D. If you figure it out please share.
An alternative would be to create individual 3D spheres centered around the dataPoints and then assign them the recorded rgb vals. I would be mindfull of this approach as its performance heavy and dependent on the data size.
Good luck :)

Just to build upon the other answer, you can set the Points property of PointsVisual3D in XAML via binding, MVVM-style:
<helix:HelixViewport3D>
<helix:DefaultLights/>
<helix:PointsVisual3D Color="Black" Size="2" Points="{Binding dataList}"/>
</helix:HelixViewport3D>

It is necessary to create an instance of the importer class, and in the XAML file the compiler asks you to place the model declaration before the camera is declared.
cpp file:
ModelImporter importer = new ModelImporter();
Model3DGroup model=importer.Load("model_file.ply");
MyModel.Content = model;
XAML:
<helix:HelixViewport3D x:Name="viewPort3d">
<ModelVisual3D x:Name="MyModel"/>
<helix:HelixViewport3D.Camera>
<PerspectiveCamera UpDirection="-0.00794080933244957, 0.909926622339627, 0.414693242656239"
LookDirection="49.636719684, -2387.8047, -29918.6652549283"
Position="-48.6367196, 5688.80470553634, 29917.665254"/>
</helix:HelixViewport3D.Camera>
</helix:HelixViewport3D>

Related

SharpMap - display an overlay image synchronized with the map (georeferencing functionality)

Using SharpMap (Windows Forms) how can I display an overlay image over the map tile background so that the image scales and moves accordingly with the map zoom and pan? I want to implement a georeferencing like functionality.
I tried using SharpMap.Layers.GdiImageLayer but I didn't find a way to position it to a custom position (real world coordinate) - it is getting placed by default at origin [0,0] (the background tile coordinates). Is there a way to define a relation (transformation) to place it in a particular position?
I managed to get closer to a solution using VectorLayer with RasterPointSymbolizer but the symbol (image loaded for symbol) would need to be transformed on map scaling/zoom (so that corners remain in the same real world coordinates) - the math calculation behind looks a little complicated for a solution that seems more like a workaround than a natural one. As a note - I don't need precise calculation using projection/real geoid as I am doing this only at building level.
Using GDAL - GeoTIFF might be a choice here by generating a GeoTIFF based on the original image and making the georeferencing metadata dynamic based on UI controls? The original image is in raster format (JPG) with no geographic metadata.
Is there a better solution?
If VectorLayer - RasterPointSymbolizer is the best choice, do you have an example for symbol(image) synchronization with the map view?
As far as i can tell the GdiImageLayer calculates the position based on a world-file (GdiImageLayer.SetEnvelope()). Here is the link to the method. This meta file has to have the same name in the same location but the filetype must be of type *.wld. There you set the position (top left corner) and the skew in x and y axis. So rotation will be perserved. I never tried this but i would suggest correct zooming would work
(The wiki article offers also some good understanding for world files)
There might be another way if no world file is present and the information rests in the header. There is a GDalSample loading a GeoTiff Image onto an existing map. The example can be found in the WinFormSamples and the Different kind of layers supported by [MapBox] Example. The map is showing the overlay only while magnifying and not fully function but maybe a good hint

Save a list of elements inside an image in c#

Is there anyway to save a list of elements/linked list inside an
image?
I need to save information like a relationship between neighborhood pixel values in an image. So i will be using a List<> containing (pixel value, relative coordinate of next pixel)
List<Dictionary<int, int[]>> globalList = new List<Dictionary<int, int[]>>();
// list contains a map for [water mark pixel, {matching cover image pixel, best match value}] for each watermark
Please suggest some ways to save it inside my image as a secret information which is hard to remove except methods like :
Increasing bit-depth
save into image properties as header info
I know these can be removed easily. I need a non-removable way ( in C#).
Your question was kind of unclear, but I assume you're trying to add a hidden watermark?
The easiest way would probably be to convert your data to a BitArray and then increase the value of each pixel's color by 1 or 0 bits as you iterate through the array. You would then retrieve your data by comparing the resulting photo to your original.
Edit:
If you want to store the data outside of the header/properties and without modifying colors, then I don't have a solution for you. As far as I know, those are your only options. You could always do what I mentioned and then include the watermarked portion of your image as a static BitArray within your application for comparison.

Translucency issue using SharpDX on WinRT

I'm having a translucency issue using sharpdx for winrt.
First of all, my code:
On the Mainpage.xaml, I've add a swapchainPanel like this:
<Grid>
<SwapChainPanel x:Name="Panel" />
</Grid>
// There is nothing else...
I've used the same class as the sample from github, for the 3D models rendering:
// Initialisation part
graphicsDeviceManager = new GraphicsDeviceManager(this);
graphicsDeviceManager.PreferredGraphicsProfile = new FeatureLevel[] { FeatureLevel.Level_11_0, };
graphicsDeviceManager.DepthBufferShaderResource = true;
Still in the same class, when loading contents:
models = new List<Model>();
foreach (var modelName in new[] {"dude"})
{
model = Content.Load<Model>(modelName);
BasicEffect.EnableDefaultLighting(model, true);
models.Add(model);
}
model = models[0];
// Instantiate a SpriteBatch
spriteBatch = ToDisposeContent(new SpriteBatch(GraphicsDevice));
base.LoadContent();
And finally, the draw part:
// Clears the screen with the Color.CornflowerBlue
GraphicsDevice.Clear(Color.CornflowerBlue);
model.Draw(GraphicsDevice, world, view, projection);
base.Draw(gameTime);
Everything render fine, but this is what I got for a textured model (It's a bit tricky to notice the translucency on a screenshot...)
Here is what I have with a non-textured model...
I think it comes from rendering in Alpha mode. I've tried to set the BlendState but I get some Exceptions since I'm not using the right parameters.
Ok after some several gradual checks as suggested by #xoofx (thanks :) )
I found that there are some issues using SharpDx.
The ModelRendering sample come with .dae models. When I launch this sample, Everything workes fine and there is no issue.
When I load my model, exported on .dae, .fbx and .obj, transluncency appears with .dae, .fbx, but the toolkit compiler can't compile .obj files that have .mtl associated since some primitives and files tag aren't in the correct format. (even if I check the XNA compatibility in Blender when Exporting)
So what have I done to solve my problem ?
1 - Decrease or make sure my graphic profil is the right profil since I'm on a Intel graphic 4000 that doesn't support directX 11.1 yet...
graphicsDeviceManager.PreferredGraphicsProfile = new FeatureLevel[] { FeatureLevel.Level_11_0, };
2 - Delete everything that the toolkit compiler generated in the Debug directory. I think the compiler doesn't generate twice a file when it already exists/compiled.
3 - Finally, I've noticed that all the part in white/transparent on the pictures in my question are all textured. That kind of color comes from this combination:
I've apply a texture on a model or model part.
Unfortunatly, the Toolkit compiler can't find the texture or the texture value is void.
But when you apply a Texture on a model, surface Specular highlight will be activated, especially the MaterialSpecular (that you can see on a model's part property in VisualStudio. MaterialSpecular takes 4 values : R, G, B and A for Alpha always set the Alpha to 1. My aplha was 0 sometimes :( ).
So the light is freakily reflected and tadaaa we got a beautiful translucent model :)
Also, I Export my model into .fbx and make sure to display the default gray plain color on part that are not textured.
4 - Last but not least, Enable default lightning on the Model.
BasicEffect.EnableDefaultLighting(model, true);

Inserting a striped line onto an Excel chart through COM Interop

How can we add a striped line to an Excel chart using C#?
I am able to create the chart using c# but I didn't get any clue how to add a striped line.
Please make some suggestions.
Thanks
Try this:
- add a data series with a steady value ( of 50 in your case )
- move the new data series to the secondary Y axis
- synchronize the maximum for both Y axes
- set Chart Type for the new data series to Line
- set the Line Style for the new data series to a dash type
I know this is not C#, but it is C# as much as you question is :)
When I have things like this, what I'm usually doing is I "manually" do all I have to do in Excel recording a macro with all the stuff. Then I just analyze the macro. You will find a lot of useful information there.
Good luck!

Drawing a map based on an array, and applying run time changes

I am writing a program to control a mobile robot. One of the things it has to do is to draw a map of the "world" as the robot senses it and apply changes in the map as it senses them.
It also has to highlight in some way the location of the robot and (ideally) the direction it points to.
I currently have an auto-updating array (100 x150) representing the map, using the following representations: 0 represents a clear path, 1 represents an obstacle.
I also have a variable containing the robot's location and next location.
What I need is to visualize it. I thought about using labels, but it is way too tedious using them, and the end result is not so pretty. My other possibility is to write all that data into an Excel spreadsheet, but then I will be back to square one: visualizing the data in an attractive way. Is there a drawing package of some sort that can do the job?
To sum it up:
Using:
- int[] MapArray //100 x 150 array representing the robot's world, and the data there is changing.
- Point[] Locations //Locations[0] is the current location, Locations[1] is the next step.
And I want to draw a map on a Windows Forms application that updates itself in a nice visual manner.
I hope my question is clear enough, don't hesitate to contact me if not!
Try Code: Drawing a Filled Rectangle on a Form (Visual C#) or something similar.
Graphics Programming Example Topics
Just write a couple of cycles which accesses every cell of an array and draws a rectangle on a form according to coords - that's the simplest way.
for(int i=0; i<100; i++)
{
for(int j=0;j<150;j++)
{
<access[i,j] and draw a rectangle with color accordingly to your contents.>
}
}
The same for the drawing location.
If you don't find any nice controls, you can always use a DataGridView with the column width = row height so that it always displays square cells. After that, just change the background color of the obstacles.
You could also look into observable collections for the map array so that the grid updates based on events rather than on timers. Make sure that you overwrite the observable collection to send the CollectionChanged event even when a cell changes its value, not only when adding/removing cells.

Categories

Resources