Adding single dimension float array values - c#

I have two questions regarding the Evil Dicom library.
I know with the floats function, all of the pixel data is contained as float elements in a one dimensional array. My question here is how can I add up the individual elements to get one value?
After I have multiplied a black and white mask with the original image, how can I then add up the non-zero values in the image? Do I also use the floats function to get the data as an array and then add up the array elements? If not, how can I add up the pixels in the image from top left corner to bottom right corner?

As far as I know there is no special functionality in the Evil DICOM library for these operations, but there is always LINQ.
If you are looking for the sum of all pixel elements:
var imgMtx = new ImageMatrix("image.dcm");
var sum = imgMtx.Image.Sum();
If you are looking for the sum of the non-zero values:
var nonZeroSum = imgMtx.Image.Where(val => val != 0.0f).Sum();
If you are looking for the average value, simply replace Sum with Average.

Related

How do I find group areas in a 2D int Array

I have an int[,] filled with "0" and "1" values. I'm using this to draw a new bitmap and that's working good.
What I'm having problem with, is finding "Empty areas" in that array.
Now, let's take this array as an example:
000000000
011101110
010101010
011101110
000000000
000000000
000000111
000000101
000000111
How can I find all "rectangles" possible in the empty space (0s Block)?
What I need is to check for blocks of Zeros and find all blocks bigger than X Width and Y Height.
Let's say I'm looking for blocks bigger than 3x3.
222000000
222000000
222222
000222
000222
This is one of the results possible.
My goal is to find how many empty "Spaces" I have in an image.

C# MS Charts get Y value from a generic X

I have a chart with 3 lines, all of them dynamics (the points series varies any time).
For two lines I have few points, up to 20, and for the other one, that is a Spline, up to 500. (always in the same x range)
I have to verify if the Spline is between the two other lines.
In other words, for each point of the Spline get the Y value of all the lines and verify if it's in the range.
How I could achieve that?
I've already tried the follow code, but when I call an X point that is not defined in the other two Line I'll have only the Y value for the Spline:
var a = chart1.Series.Select(series => series.Points.Where(point => point.XValue == 7).ToList()).ToList();
Follow an image of the graph-like:
The blue and the yellow line are the ones "less defined", and I have to verify if the red one stays between them
It's rather a math problem than a chart problem.
To determine the mid line is in between the upper and lower bounds, it comes down to the linear interpolation of the bounds.
Suppose your upper bound (ub) is defined on five points: 1,2,5,6,9.
The easy way to do the linear interpolation is to find the two closest neighbors and do the weighted average. e.g. ub(5.5) = ub(5)/2 + ub(6)/2
There are many ways to do the 1D linear interpolation and if you search it on stackoverflow you should be able to find existing solutions.

How to extract a rectangular and non-rectangular area from a video?

I am developing a face tracking application using Kinect, and I have output like the following.
What I want to do is the extract the exact face area, either the yellow-lined area or the red rectangular, it would be great if you can tell me how to do both. Basically, I am expecting an output with only the interested area with black otherwise.
Right now I have all the point coordinates that I need, but I am not sure which class and method to use.
Please note that I am working with video frames, if it makes any difference.
Thank you,
I haven't done this in C#, but in c++, running something like this generates an array of RGB values:
const XnRGB24Pixel *pImage = imageMD->RGB24Data(); // generate array
XnRGB24Pixel pixelRGB = *pImage; // get the first element of array
byte red = pixelRGB.nRed // read the RED value
The array is 1-dimensional and elements are stored in it row wise from the bottom (last row, then the row before last row, ...). Going through them with a nested for loop like this would give you the rectangular area you want:
for(int y = RECTANGLE_Y1; y < RECTANGLE_Y2; y++)
{
for(int x = RECTANGLE_X1; x < RECTANGLE_x2; x++)
{
pixelRGB = pImage[y*RESOLUTION_WIDTH + x]; // get the element
// work with pixelRGB
}
}
Replace RECTANGLE_X1 and RECTANGLE_Y1 with the coordinates of the lower left edge coordinates of your rectangle and RECTANGLE_X2 and RECTANGLE_Y2 with the upper right edge coordinates.
For getting the values of pixels inside the non-rectangular area, a similar approach would work if you can figure out the geometric calculations necessary to recognize when a given [x,y] are inside the area; but even after that, I don't have any clue on how to store it in conventional data structures.
Hope this helps.

Single dimension peak fitting

I have a single dimensional array of floating point values (c# doubles FYI) and I need to find the "peak" of the values ... as if graphed.
I can't just take the highest value, as the peak is actually a plateau that has small fluctuations. This plateau is in the middle of a bunch of noise. I'm looking find a solution that would give me the center of this plateau.
An example array might look like this:
1,2,1,1,2,1,3,2,4,4,4,5,6,8,8,8,8,7,8,7,9,7,5,4,4,3,3,2,2,1,1,1,1,1,2,1,1,1,1
where the peak is somewhere in the bolded section.
Any ideas?
You can apply a low-pass filter to your input array, to smooth out the small fluctuations,
then find the peak in the filtered data. The simplest example is probably a "boxcar"
filter, where the output value is the sum of the input values within a certain distance
from the current array position. In pseudocode, it would look something like this:
for i = 0, samplecount-1
if (i < boxcar_radius) or (i >= (samplecount - boxcar_radius)) then
filtered_data[i] = 0 // boxcar runs off edge of input array, don't use
else
filtered_data[i] = 0
for j = i-boxcar_radius, i+boxcar_radius
filtered_data[i] = filtered_data[i] + input_data[j]
endfor
endif
endfor
If you have some idea how wide the "plateau" will be, you can choose the boxcar radius (approximately half the expected plateau width) to detect features at the appropriate scale.
You need to first define what you mean by 'small'. Say, 'small' fluctuation around the maximum is defined as any value that is within ± ϵ of the maximum. Then, it is straightforward to identify the plateau.
Pass through the data to identify the maximum and then do a second pass to identify all values that are within ± ϵ of the maximum.
Peak detection is one of the stages in Phase Correlation and other motion estimation algorithms used in places like video compression. One approach is this: consider a candidate for a peak and a window of a certain number of neighbours. Now fit a quadratic function using standard regression. The peak, with subpixel accuracy, is at the maximum of the fitted quadratic.
Obviously exact solution depends on details. If your distribution is always nice as in your example you could have:
def GetPeak(l):
large = max(l) * 0.8
above_large = [i for i in xrange(len(l)) if l[i] > large]
left_peak = min(above_large)
right_peak = max(above_large)
return (left_peak, right_peak)

How to fill a square with smaller squares/rectangles?

In my office at work, we are not allowed to paint the walls, so I have decided to frame out squares and rectangles, attach some nice fabric to them, and arrange them on the wall.
I am trying to write a method which will take my input dimensions (9' x 8' 8") and min/max size (1' x 3', 2', 4', etc..) and generate a random pattern of squares and rectangles to fill the wall. I tried doing this by hand, but I'm just not happy with the layout that I got, and it takes about 35 minutes each time I want to 'randomize' the layout.
One solution is to start with x*y squares and randomly merge squares together to form rectangles. You'll want to give differing weights to different size squares to keep the algorithm from just ending up with loads of tiny rectangles (i.e. large rectangles should probably have a higher chance of being picked for merging until they get too big).
Sounds like a Treemap
Another idea:
1. Randomly generate points on the wall
Use as many points as the number of rectangles you want
Introduce sampling bias to get cooler patterns
2. Build the kd-tree of these points
The kd-tree will split the space in a number of rectangles. There might be too much structure for what you want, but its still a neat geeky algorithm.
(see: http://en.wikipedia.org/wiki/Kd-tree)
Edit: Just looked at JTreeMap, looks a bit like this is what its doing.
If you're talking on a pure programing problem ;) There is a technique called Bin Packing that tries to pack a number of bins into the smallest area possible. There's loads of material out there:
http://en.wikipedia.org/wiki/Bin_packing_problem
http://mathworld.wolfram.com/Bin-PackingProblem.html
http://www.cs.sunysb.edu/~algorith/files/bin-packing.shtml
So you 'could' create a load of random squares and run it through a bin packer to generate your pattern.
I've not implemented a bin packing algorithm myself but I've seen it done by a colleague for a Nike website. Best of luck
Since you can pick the size of the rectangles, this is not a hard problem.
I'd say you can do something as simple as:
Pick an (x,y) coordinate that is not currently inside a rectangle.
Pick a second (x,y) coordinate so that when you draw a rectangle between
the two coordinates, it won't overlap anything. The bounding box of
valid points is just bounded by the nearest rectangles' walls.
Draw that rectangle.
Repeat until, say, you have 90% of the area covered. At that point you
can either stop, or fill in the remaining holes with as big rectangles
as possible.
It might be interesting to parametrize the generation of points, and then make a genetic algorithm. The fitness function will be how much you like the arrangement - it would draw hundreds of arrangements for you, and you would rate them on a scale of 1-10. It would then take the best ones and tweak those, and repeat until you get an arrangement you really like.
Bin packing or square packing?
Bin packing:
http://www.cs.sunysb.edu/~algorith/files/bin-packing.shtml
Square packing:
http://www.maa.org/editorial/mathgames/mathgames_12_01_03.html
This actually sounds more like an old school random square painting demo, circa 8-bit computing days, especially if you don't mind overlaps. But if you want to be especially geeky, create random squares and solve for the packing problem.
Building off Philippe Beaudoin answer.
There are treemap implementations in other languages that you can also use. In Ruby with RubyTreeMap you could do
require 'Treemap'
require 'Treemap/image_output.rb'
root = Treemap::Node.new 0.upto(100){|i| root.new_child(:size => rand) }
output = Treemap::ImageOutput.new do |o|
o.width = 800
o.height = 600
end
output.to_png(root, "C:/output/test.png")
However it sorts the rectangles, so it doesn't look very random, but it could be a start. See rubytreemap.rubyforge.org/docs/index.html for more info
I would generate everything in a spiral slowly going in. If at any point you reach a point where your solution is proven to be 'unsolvable' (IE, can't put any squares in the remaining middle to satisfy the constraints), go to an earlier draft and change some square until you find a happy solution.
Pseudocode would look something like:
public Board GenerateSquares(direction, board, prevSquare)
{
Rectangle[] rs = generateAllPossibleNextRectangles(direction, prevSquare, board);
for(/*all possible next rectangles in some random order*/)){
if(board.add(rs[x]){
//see if you need to change direction)
Board nBoard = GenerateSquares(direction, board, rs[x]);
if(nBoard != null) return nBoard; //done
else board.remove(rs[x]);
}
}
//all possibilities tried, none worked
return null;
}
}
I suggest:
Start by setting up a polygon with four vertices to be eaten in varying size (up to maxside) rectangle lumps:
public double[] fillBoard(double width, double height, double maxside) {
double[] dest = new int[0];
double[] poly = new int[10];
poly[0] = 0; poly[1] = 0; poly[2] = width; poly[3] = 0;
poly[4] = width; poly[5] = height; poly[6] = 0; poly[7] = height;
poly[8] = 0; poly[9] = 0;
...
return dest; /* x,y pairs */
}
Then choose a random vertex, find polygon lines within (inclusive) 2 X maxside of the line.
Find x values of all vertical lines and y values of all horizontal lines. Create ratings for the "goodness" of choosing each x and y value, and equations to generate ratings for values in between the values. Goodness is measured as reducing number of lines in remaining polygon. Generate three options for each range of values between two x coordinates or two y coordinates, using pseudo-random generator. Rate and choose pairs of x and pair of y values on weighted average basis leaning towards good options. Apply new rectangle to list by cutting its shape from the poly array and adding rectangle coordinates to the dest array.
Question does not state a minimum side parameter. But if one is needed, algorithm should (upon hitting a hitch with a gap being too small) not include too small candidates in selection lists (whic will occasionally make them empty) and deselect a number of the surrounding rectangles in a certain radius of the problem with size and perform new regeneration attempts of that area, and hopefully the problem area, until the criteria are met. Recursion can remove progressively larger areas if a smaller relaying of tiles fails.
EDIT
Do some hit testing to eliminate potential overlaps. And eat some spinach before starting the typing. ;)
Define input area;
Draw vertical lines at several random horizontal locations through the entire height;
Draw horizontal lines at several vertical positions through the entire width;
Shift some "columns" up or down by arbitrary amounts;
Shift some "rows" left or right by arbitrary amounts (it may be required to subdivide some cells to obtain full horizontal seams;
Remove seams as aesthetically required.
This graphical method has similarities to Brian's answer.

Categories