How to reduce the noise in a cloud points in dataset? - c#

I'm reading data from a sensor. The sensor give an array of points (x,y). But as you can see in the image, there is a lot of noise:
.
I need to clean the data in a way that the data filtered, give a few points . Using something like Median,adjacent averaging, mean of the xy points or an algorithm that removes the noise. I know that there are a bunch of libraries in Python that make the work automatically. All the auto libraries that I found are base on image analysis and I think they do not work for this case because this is different, these are points (x,y) in a dataset.
point-cloud noise cleaned:
PD: I wanted to do the median of the points but i got confused when i tried with an bidimensional array (this mean ListOfPoints[[x,y],[x,y],[x,y],[x,y],[x,y],[x,y]]) I didn't know how to make that calculation with for or while to iterate and make the calc. I prefer C#, but if there is a solution in other language without libraries, I would be open to it.

One of the methods you can use is k_means algorithm. This picture briefly explains this algorithm k_means
This link fully explains the k_means algorithm. Also, how to create a loop on the input data. I don't think any additional explanation is needed k_means algorithm
K_menans algorithm is very simple and you will understand it with the first Google search

You could try doing a weighted average of the Y-value at sampled X-positions. Something like this:
List<Point2> filtered_points = new List<Point2>();
for (int x = xmin; x <= xmax; x++)
{
double weight_sum = 0;
List<double> weights = new List<double>();
foreach (Point2 p in point_list)
{
double w = 1.0/((p.x - x)*(p.x - x) + 1e-3);
weights.Add(w);
weight_sum += w;
}
double y = 0;
for (int i = 0; i < point_list.Count; i++)
{
y += weights[i]*point_list[i].y / weight_sum;
}
filtered_points.Add(new Point2(x, y));
}
You would probably need to tune the weights to get nice results. Also, in the example I am using a quadratic decay, but other weighting functions can be used (linear decay, gaussian function...)

Related

Getting Number of Cubes with Integer Coordinates with Certain Distance from Origin

I am working on a voxel system for my game that uses dynamic loading of chunks. To optimize it, I have a pool of chunks and a render distance, and what I want to do is fill the pool with a proper amount of chunks. So, I need a way to find that amount. I have tried the following but it seems very inefficient.
private void CreatePool()
{
int poolSize = 0;
for (int x = -m_RenderDistance; x <= m_RenderDistance; x++) {
for (int y = -m_RenderDistance; y <= m_RenderDistance; y++) {
for (int z = -m_RenderDistance; z <= m_RenderDistance; z++) {
if (Position3Int.DistanceFromOrigin(new Position3Int(x, y, z)) <= m_RenderDistance)
poolSize++;
}
}
}
}
More formally, the question involes finding the amount of unique cubes with integer coorindates with a certain distance from the origin.
If you think there is a better way to approach this or I am doing something fundamentally wrong, let me know.
Thanks,
Quintin
I assume its the distance check that you think is inefficient? What you've got shouldn't be too bad if you're just getting the count on Start() or Awake().
Draco18s solution is fine if you are okay with a cubed result. If you want a spherical result without a distance check, you can try some formulation of the volume of a sphere: 4/3*PI*r^3
checkout Bresenham's circle.
Here's a approximation algorithm for a filled 3d Bresenham Circle that I have. It is very similar to what you have already, just with a more effecient squared dist check and a minor adjustment to get a more attractive bresenham-looking circle):
public static List<Vector3> Get3DCircleKeys(int radius){
List<Vector3> keys = new List<Vector3>();
for(int y=-radius; y<=radius; y++){
for(int x=-radius; x<=radius; x++){
for(int z =-radius; z<=radius; z++){
// (+ radius*.08f) = minor modification to match Bresenham result
if(x*x+y*y+z*z <= radius*radius + radius*.08f){
keys.Add(new Vector3(x,y,z));
}
}
}
}
return keys;
}
This, however, will deliver a different count than the volume of sphere would give you, but with some tweaking to it or to the sphere volume calculation, it could be good enough, or at least, more efficient than instantiating a full volume of a cube, where many of the voxels will be outside of the bounds of the render distance.

Could someone describe a 2d interpolation method that is better than bilinear interpolation?

I have a grid of data points that I currently use Bilinear interpolation on to find the missing points in the grid. I was pointed in the directions of Kriging aka thee best linear unbiased estimator, but I was unable to find good source code or an algebraic explanation. Does anyone know of any other interpolation methods I could use?
--Update
#Sam Greenhalgh
I have considered Bicubic Interpolation but the results I received using the code example I found seemed off.
Here is the code example for Bicubic
Note I am coding in C# but I welcome examples from other languages as well.
//array 4
double cubicInterpolate(double[] p, double x)
{
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
}
//array 4 4
public double bicubicInterpolate(double[][] p, double x, double y)
{
double[] arr = new double[4];
arr[0] = cubicInterpolate(p[0], y);
arr[1] = cubicInterpolate(p[1], y);
arr[2] = cubicInterpolate(p[2], y);
arr[3] = cubicInterpolate(p[3], y);
return cubicInterpolate(arr, x);
}
double[][] p = {
new double[4]{2.728562594,2.30599759,1.907579158,1.739559264},
new double[4]{3.254756633,2.760758022,2.210417411,1.979012766},
new double[4]{4.075740069,3.366434527,2.816093916,2.481060234},
new double[4]{5.430966401,4.896723504,4.219613391,4.004306461}
};
Console.WriteLine(CI.bicubicInterpolate(p, 2, 2));
One widely-used interpolation method is kriging (or Gaussian process regression).
However, the use of kriging is not advised when your data points are on a regular grid. The euclidian distances between data points are used to adjust the parameters of the model. But in a grid, there are much fewer values of distance than in, say, a randomly simulated set of points.
Nevertheless, even if your data points are regularly placed, it could be interesting to give it a try. If you are interested, you can use the following softwares:
DiceKriging package in R language (there exist others like kriging, gstat...)
DACE toolbox in Matlab
STK in Matlab/Octave
And many others (in python for example)...
NOTE: It can be interesting to note (I do not exactly in what context you want to apply kriging) that the kriging interpolation property can very easily be relaxed in order to take into account, for example, possible measurement errors.
If your data points are on a regular grid, I would recommend using a piecewise linear spline in two dimensions. You could fill the data for the rows (x-values) first, then fill the data for the columns (y-values.)
Math.NET Numerics has the piecewise linear spline function that you would need:
MathNet.Numerics.Interpolation.LinearSpline.InterpolateSorted

Algorithm for find polygons on a 2d grid

I'm not really good in maths, so I'm having really hard times to find an algorithm do this:
i have a grid like this: (8x8) GRID 8x8
I'm trying to find an alghorithm that help me to find the red polygon and after that, all the cell inside this polygon will be red.
At this moment i'm using C# and i have a multi-dimensional array with the grid colour map, so i have to work on it; but i don't know what i can do.
private Color[,] mapColor;
mapColor= new Color[8, 8];
Thanks in advance
The question is not too clear, and I couldn't see the image (blocked by my firewall). What I understand is that you want to follow all possible paths starting from a red cell and trying to find a polygon.
If it is the question, sounds like a Graph problem. You'll problably solve it using a BFS (Breadth First Search) algorithm, thinking in the Grid as a Graph (each cell can have like 8 edges - if you want to consider diagonal ways - or 4 edges if you want to consider only up/down and left/right directions).
BFS will return the shortest path. If you want all possible paths, you should use DFS (Depth First Search) algorithm.
Just iterate over the bitmap every 64 pixels and then call a function that checks nearby pixels to confirm it has found a red square. As long as there's high contrast in the image like you have, it shouldn't be too hard to find the places inordinately biased towards red.
e.g.
List<KeyValuePair<int, int>> PossibleCoords = new List<KeyValuePair<int,int>();
for(int i = 0; i < Bitmap.Width/64; i++)
{
for(int j = 0; j < Bitmap.Height/64)
{
if(Bitmap.GetPixel(i*64, j*64).R > 200)
{
KeyValuePair<int, int> temp = new KeyValuePair<int, int>();
KeyValuePair.Key = i*64;
KeyValuePair.Value = j*64;
PossibleCoords.Add(temp);
}
}
}
for(int i = 0; i < PossibleCoords.Count; i++)
{
SampleAdjacentPixelsToConfirm(PossibleCoords[i]);
}
To take a sample, I'd check if the ratio of red to the other colors is high if I were after high precision.

How to find Black Pixel locations

I'm working on a strange project. I have access to a laser cutter that I am using to make stencils (from metal). I can use coordinates to program the machine to cut a certain image, but what I was wondering was: how can I write a program that would take a scanned image that was black and white, and give me the coordinates of the black areas? I don't mind if it gives every pixel even though I need only the outer lines, I can do that part.
I've searched for this for a while, but the question has so many words with lots of results such as colors and pixels, that I find tons of information that isn't relevant. I would like to use C++ or C#, but I can use any language including scripting.
I used GetPixel in C#:
public List<String> GetBlackDots()
{
Color pixelColor;
var list = new st<String>();
for (int y = 0; y < bitmapImage.Height; y++)
{
for (int x = 0; x < bitmapImage.Width; x++)
{
pixelColor = bitmapImage.GetPixel(x, y);
if (pixelColor.R == 0 && pixelColor.G == 0 && pixelColor.B == 0)
list.Add(String.Format("x:{0} y:{1}", x, y));
}
}
return list;
}
If we assume that the scanned image is perfectly white and perfectly black with no in-between colors, then we can just take the image as an array of rgb values and simply scan for 0 values. If the value is 0, it must be black right? However, the image probably won't be perfectly black, so you'll want some wiggle room.
What you do then would look something like this:
for(int i = 0; i < img.width; i++){
for(int j = 0; j < img.height; j++){
// 20 is an arbitrary value and subject to your opinion and need.
if(img[i][j].color <= 20)
//store i and j, those are your pixel location
}
}
Now if you use C#, it'll be easy to import most image formats, stick em in an array, and get your results. But if you want faster results, you'd be better off with C++.
This shortcut relies completely on the image values being very extreme. If large areas of your images are really grey, then the accuracy of this approach is terrible.
While there are many solutions in many languages, I'll outline a simple solution that I would probably use myself. There is a imaging great library for Python called PIL (Python Imaging Library - http://www.pythonware.com/products/pil/) which could accomplish what you need very easily.
Here's an example of something that might help you get started.
image = Image.open("image.png")
datas = image.getdata()
for item in datas:
if item[0] < 255 and item[1] < 255 and item[2] < 255 :
// THIS PIXEL IS NOT WHITE
Of course that will count any pixel that is not completely white, you might want to add some padding so pixels which are not EXACTLY white also get picked up as being white. You'll also have to keep track of which pixel you are currently looking at.

Eigenvector and Eigenvalue of 8 X 8 matrix

I have a 8 x 8 matrix of floating point numbers and need to calculate eigenvector and eigenvalue from it. This is for feature reduction using PCA (Principal Component Analysis) and is one hell of a time consuming job if done by traditional methods. I tried to use power method as, Y = C*X where X is my 8 X 8 matrix.
float[,] XMatrix = new float[8, 1];
float[,] YMatrix = new float[8, 1];
float max = 0;
XMatrix[0, 0] = 1;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 1; j++)
{
for (int k = 0; k < 8; k++)
{
YMatrix[i, j] += C[i, k] * XMatrix[k, j];
if (YMatrix[i, j] > max)
max = YMatrix[i, j];
}
}
}
I know it is incorrect but cannot figure it out. I need help for using a power method or perhaps more effective way of calculating it.
Thanks in advance.
To retrieve the eigenvalues/eigenvectors in an efficent manner (i.e. fast!) for any size (dense) matrix, is not entirely trivial. I would suggest you use something like the QR algorithm (although this maybe overkill for a one-off calculation of a single 8x8 matrix).
The QR algorithm computes a Schur decomposition of a matrix. It is certainly one of the
most important algorithm in eigenvalue computations. However, it is applied to dense matrices only (as stated above).
The QR algorithm consists of two separate stages. First, by means of a similarity
transformation, the original matrix is transformed in a finite number of steps to Hessenberg
form or – in the Hermitian/symmetric case – to real tridiagonal form. This first stage of
the algorithm prepares its second stage, the actual QR iterations that are applied to the
Hessenberg or tridiagonal matrix.
The overall complexity (number of floating points) of the algorithm is O(n3). For a good explanation of this algorithm see here. Or searches for eigenvalue algorithm in Google should provide you with many alternative ways of calculating your required eigenvalues/vectors.
Also, I have not looked into this in detail, but Math.NET a free library may help you here...

Categories