How to set values for multichannel matrix in Emgucv - c#

I didn't find any explanations how to use a matrix with more than one channel im emgucv
var matrixa = new Matrix<float>(usablePoints.Count, 1, 2);
I tried with the Split() function but it didn't change the values of matrixa
var channels = matrixa.Split();
for (int i = 0; i < usablePoints.Count; ++i)
{
channels[0][i, 0] = usablePoints[i].X;
channels[1][i, 0] = usablePoints[i].Y;
}
What am I missing? How can i manipulate values of matrixa?

If you look at matrixa.Data, this will be a float[,] with the first dimension corresponding to rows and the second being the columns and channels merged into one dimension.
If the number of channels is N, the current channel is n and the current column is m, the index j of the second dimension is
j = m*N + n
So, for your example:
for (int i = 0; i < usablePoints.Count; ++i)
{
matrixa.Data[i, 0] = usablePoints[i].X;
matrixa.Data[i, 1] = usablePoints[i].Y;
}
should work.
A more complicated example: Say that we have 3 channels, 5 columns and want to set the value of the 2nd row, 4th column and 3rd channel to 1:
j = m*N + n = 3*3 + 2 = 11
=>
matrixa.Data[1, 11] = 1;

Related

Numbers wont follow when shifting array to the left

Numbers can shift to the left => check.
Only the first number in the array follows, the rest disappears.
Example how it is right now:
Input array: 1 2 3 4 5 6
Input how many times to shift left: 3
Output: 4 5 6 1
How the Output should be: 4 5 6 1 2 3
Can someone help met with this probably simple solution which I can't find.
var str = Console.ReadLine();
int shift = Convert.ToInt32(Console.ReadLine());
var strArray = str.Split(' ');
var x = strArray[0];
for (var i = 0; i < strArray.Length - shift; i++)
{
strArray[i] = strArray[i + shift];
}
strArray[strArray.Length - shift] = x;
for (var i = 0; i <= strArray.Length - shift; i++)
{
Console.Write(strArray[i] + ' ');
}
You can use Linq to perform your shift, here is a simple method you can use
public int[] shiftRight(int[] array, int shift)
{
var result = new List<int>();
var toTake = array.Take(shift);
var toSkip = array.Skip(shift);
result.AddRange(toSkip);
result.AddRange(toTake);
return result.ToArray();
}
Here is quick fix for you. please check following code.
I shift element to left by 1 position you can change code as par your requirement.
Input array: 1 2 3 4 5 6
Input how many times to shift left: 1
Output : 2 3 4 5 6 1
int[] nums = {1, 2, 3, 4, 5, 6};
Console.WriteLine("\nArray1: [{0}]", string.Join(", ", nums));
var temp = nums[0];
for (var i = 0; i < nums.Length - 1; i++)
{
nums[i] = nums[i + 1];
}
nums[nums.Length - 1] = temp;
Console.WriteLine("\nAfter rotating array becomes: [{0}]", string.Join(", ", nums));
If this is only for strings and the wraparound is necessary I would suggest to use str.Substring(0,shift)
and append it to str.Substring(shift) (don't try to reinvent the weel)
(some info about the substring method: String.Substring )
otherwise the reason why it did not work is because you only saved the first value of the array instead of all the values you wanted to shift.
Do not save only the first value in the array
var x = strArray[0];
use
string[] x = new string[shift];
for (int i = 0; i < shift; i++)
{
x[i] = strArray[i];
}
instead so you collect all the values you need to add to the end.
EDIT: forgot the shifting
Shift the old data to the left
for (int i = 0; i < strArray.Length-shift; i++)
{
strArray[i] = strArray[i+shift];
}
And replace
strArray[strArray.Length - shift] = x;
for
for(int i = 0; i < x.Length; i++){
int newlocation = (strArray.Length - shift)+i;
strArray[newlocation] = x[i];
}
also replace the print loop for
Console.WriteLine(string.Join(" ", strArray));
its easier and makes it one line instead of three lines of code.
(also the docs for the Join function string.Join)

Char in random position

I`m facing with the problem of putting char in random position.
I have a table full of dots and I have to replace 30% of these dots with *
Size: 10x5
I used function Random.
Random rnd = new Random();
if (rnd.Next() % 10 > 3)
Console.Write(". ");
else
Console.Write("* ");
Everything is in 2 loops which hold Length and Height of table (10x5).
But it only makes PROBABILITY of 30% to make * instead of .
It takes good position but every time I start a program there is different amount of *.
It should just have 16 of * (17 - if rounded) every time I start the program
How should I suppose to make 30% always instead of probability?
You have 50 dots. calculate 50*30/100, it becomes 15.
Then generate 15 unique random numbers within range of 0 to 50. those numbers are indexes you have to replace . with *
var indexes = Enumerable.Range(0,50).OrderBy(x => rng.Next()).Take(50*30/100).ToList();
If you are working with 2d index, its fairly easy to convert 1d index into 2d index.
var i = index % 5;
var j = index / 5;
According to what #KonradRudolph said if you don't want to use OrderBy you can check out other ways to shuffle array (or create randomized set) posted here Best way to randomize an array with .NET
Here is more efficient way using Fisher-Yates algorithm that I suggest you to use instead of using OrderBy
var indexes = Enumerable.Range(0, 50).ToArray();
RandomExtensions.Shuffle(rng, indexes);
Write code that does the following:
Declare an array with x * y elements
Populate the entire array with .
Declare a loop with 0.30 * x * y iterations
For each iteration, change a randomly selected element from . to * (you must keep looking until you find one that isn't already a *)
Output the array, x elements per line
Imagine your array to be just 50 elements and forget about the rectangular shape for now. How would you approach that? Declare X dots and 50-X stars, then randomly order them. Like you would randomly order a 1->50 list of numbers.
Now how to randomly order a list of 1->50 numbers? One simple and intuitive way is imagining shuffling cards. Go through the loop and for each position obtain a random number in 1->50. Swap elements chosen (say for i=1 we got random number 7 => swap elements 1 and 7).
Here, you simply need to map this rectangle to those 50 points, which is trivial enough for 2D.
I would randomly select 30% of the possible positions
// create char array
int arrayRows = 5;
int arrayCols = 10;
char[,] arr= new char[arrayRows ,arrayCols];
// populate array with dots
for (int i = 0; i < arrayRows; i++)
{
for (int j = 0; j < arrayCols; j++)
{
arr[i,j] = '.';
}
}
Random rnd = new Random();
int numberOfPossiblePositions = arrayRows * arrayCols;
int k = 0;
while (k < numberOfPossiblePositions * 0.3) {
int position = rnd.Next(numberOfPossiblePositions);
int colIndex = position / 10;
int rowIndex = position % 10;
// if the cell already has * try again
if (arr[rowIndex,colIndex] == '*') {
continue;
}
arr[rowIndex,colIndex] = '*';
k++;
}
Create an array that holds x*y/3 starts and the rest are dots. order by random and iterate through it.
This is the array:
Enumerable.Range(0, count).Select(i => new {Text = "*", Order = rnd.Next() })
.Concat(Enumerable.Range(0, x*y - count)
.Select(i=>new { Text = ".", Order = rnd.Next() }))
.OrderBy(i => i.Order).Select(i=>i.Text).ToList();
And this is the code for iteration:
Random rnd = new Random();
int x = 10;
int y = 5;
int count = x*y/3;
var allPlaces =
Enumerable.Range(0, count).Select(i => new {Text = "*", Order = rnd.Next() })
.Concat(Enumerable.Range(0, x*y - count)
.Select(i=>new { Text = ".", Order = rnd.Next() }))
.OrderBy(i => i.Order).Select(i=>i.Text).ToList();
for (var i = 0; i < x; x++)
{
for (var j = 0; j < y; j++) { Console.Write(allPlaces[i*j + j]); }
Console.WriteLine();
}

How do i represent a tournament tree structure in a gridview for a windows store app (tree view is not available) using XAML [duplicate]

I need to create an asp.net page that auto generate a brackets tournament tennis style.
Regarding the managing of match in database, it's not a problem.
The problem is the dynamic graphics creation of brackets.
The user will be able to create tournament by 2-4...32 players.
And i don't know ho to create the graphics bracket in html or gdi...
Using Silverlight, and a Grid, You can produce something like this:
To do it, define a regular UserControl containing a Grid. (This is the default when you build a silverlight app in VS2008 with the Silverlight 3.0 SDK).
Then, add a call to the following in the constructor for the user control:
private void SetupBracket(int n)
{
var black = new SolidColorBrush(Colors.Gray);
// number of levels, or rounds, in the single-elim tourney
int levels = (int)Math.Log(n, 2) + 1;
// number of columns in the Grid. There's a "connector"
// column between round n and round n+1.
int nColumns = levels * 2 - 1;
// add the necessary columns to the grid
var cdc = LayoutRoot.ColumnDefinitions;
for (int i = 0; i < nColumns; i++)
{
var cd = new ColumnDefinition();
// the width of the connector is half that of the regular columns
int width = ((i % 2) == 1) ? 1 : 2;
cd.Width = new GridLength(width, GridUnitType.Star);
cdc.Add(cd);
}
var rdc = LayoutRoot.RowDefinitions;
// in the grid, there is one row for each player, and
// an interleaving row between each pair of players.
int totalSlots = 2 * n - 1;
for (int i = 0; i < totalSlots; i++)
{
rdc.Add(new RowDefinition());
}
// Now we have a grid of the proper geometry.
// Next: fill it.
List<int> slots = new List<int>();
ImageBrush brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri("Bridge.png", UriKind.Relative));
// one loop for each level, or "round" in the tourney.
for (int j = 0; j < levels; j++)
{
// Figure the number of players in the current round.
// Since we insert the rounds in the reverse order,
// think of j as the "number of rounds remaining."
// Therefore, when j==0, playersThisRound=1.
// When j == 1, playersThisRound = 2. etc.
int playersThisRound = (int)Math.Pow(2, j);
int x = levels - j;
int f = (int)Math.Pow(2, x - 1);
for (int i = 0; i < playersThisRound; i++)
{
// do this in reverse order. The innermost round is
// inserted first.
var r = new TextBox();
r.Background = black;
if (j == levels - 1)
r.Text = "player " + (i + 1).ToString();
else
r.Text = "player ??";
// for j == 0, this is the last column in the grid.
// for j == levels-1, this is the first column.
// The grid column is not the same as the current
// round, because of the columns used for the
// interleaved connectors.
int k = 2 * (x - 1);
r.SetValue(Grid.ColumnProperty, k);
int m = (i * 2 + 1) * f - 1;
r.SetValue(Grid.RowProperty, m);
LayoutRoot.Children.Add(r);
// are we not on the last round?
if (j > 0)
{
slots.Add(m);
// Have we just inserted two rows? Then we need
// a connector between these two and the next
// round (the round previously added).
if (slots.Count == 2)
{
string xamlTriangle = "<Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "+
"xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' " +
"Data='M0,0 L 100 50 0 100 Z' Fill='LightBlue' Stretch='Fill'/>";
Path path = (Path)System.Windows.Markup.XamlReader.Load(xamlTriangle);
path.SetValue(Grid.ColumnProperty, 2 * (x - 1) + 1);
path.SetValue(Grid.RowProperty, slots[0]);
path.SetValue(Grid.RowSpanProperty, slots[1] - slots[0] + 1);
this.LayoutRoot.Children.Add(path);
slots.Clear();
}
}
}
}
}
In the above, the connector is just an isosceles triangle, with the apex pointing to the right. It is generated by XamlReader.Load() on a string.
You would also want to pretty it up, style it with different colors and fonts, I guess.
You can insert this silverlight "user control" into any HTML web page, something like embedding a flash app into a page. There are silverlight plugins for IE, Firefox, Opera, Safari, and Chrome.
If you don't want to use Silverlight, you could use a similar approach to construct an HTML table.

deleting a row in an array

I had a problem with deleting a row in c# .im writing a program for sky-l program and im checking the first coloumn and then i will decide which row is smaller(the first coloumn is important) plz help me how to delete the row. this the code.
for (int f = 0; f < i; f++)
{
sortedsky[f, 0] = sky[min, 0];
sortedsky[f, 1] = sky[min, 1];
sortedsky[f, 2] = sky[min, 2];
//how to delete???
for (y = 0; y < i-1; y++)
min = 0;
if (sky[y+1, 0] < sky[min, 0])
min = y;
}
return 1;
}
If you need to remove items from a list, consider using a List<T> instead of an array.
I strongly suggest using a generic List (which manages an array internally)
You can get a plain array from a list:
List<Sky> listofSky;
listofSky.Add(sky1);
listofSky.Add(sky2);
listofSky.Add(sky3);
Sky[] arr = listofSky.ToArray();
List also has simple Remove methods.

I am working with arrays and need to sort the array. This array keeps showing out of range exceptions

I have established an array and a large textbox which displays the array. Basically, you enter a name, 4 quarterly sales figures and it calculates the yearly total. I am now starting on the sort button. This would sort given columns numbers from most to least. I have gotten an if statement that looks like it should work for column five (the total column). I keep getting an out of range exception and am not sure why. Any ideas out there? I am sure this is a simple problem I am not seeing.
do {
swapFlag = false;
for (n=0; n < lastIndexUsed; n++)
{
if (quarters[n, sortCol] < quarters[n+1, sortCol])
{
//Column 5
temp = quarters[n,5];
quarters[n,5] = quarters[n +1, 3];
quarters[n +1, 3] = temp;
//swapflag
swapFlag = true;
}
}
} while (swapFlag);
This shows how I get 0-5 for sortCol:
if (rbRegion.Checked)
sortCol = 0;
if (rb1.Checked)
sortCol = 1;
if (rb2.Checked)
sortCol = 2;
if (rb3.Checked)
sortCol = 3;
if (rb4.Checked)
sortCol = 4;
if (rbTotal.Checked)
sortCol = 5;
Button Variables:
int n;
int temp;
int sortCol = 0;
string ntemp;
bool swapFlag;
Global Variables
int lastIndexUsed = -1;
int[,] quarters = new int[10, 5];
string[] Branch = new string[10];
quarters is defined as
int[,] quarters = new int[10, 5];
since arrays are zero based this gives you index 0...4 on the second dimension but you are trying to access index 5:
temp = quarters[n,5];
It seems to me, that you could have n = quaters.size - 1, and therefore n + 1 = quaters.size.
So it gets out of array's bound.
I smell the problem is with these:
quarters[n+1, sortCol]
quarters[n+1, 3]
Make sure n+1 is a valid index. What if lastIndexUsed itself is the maximum valid index? Then n+1 would cause IndexOutOfRangeException.
I'd suggest to use more instances of List<int> quartersSortCol0 and use if (rbRegion.Checked) quartersSortCol0.Sort() and avoid ineffective constructions like your "while-for" above. While you can use overload of Sort method with custom comparison.

Categories

Resources