Reputation: 315
I have an array declared like so:
int[,] binaryzacja = new int[bmp2.Width, bmp2.Height];
Where it's dimensions are the dimensions of a picture (usually it's gonna be 200x200). A black pixel is represented by 1. All other pixels are represented by 0.
Let's say my array looks like so:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 1 0 1 1 1 0
0 1 1 1 0 0 0
0 0 1 1 0 0 0
0 0 0 0 0 0 0
I want to remove all rows and columns that contain only 0.
So, if my example array was 7 columns, 6 rows; I want a new array that will be 5 columns, 3 rows and look like so:
1 0 1 1 1
1 1 1 0 0
0 1 1 0 0
Upvotes: 2
Views: 207
Reputation: 4742
You could transform your [,]
into a List
:
var list = new List<List<int>>();
for (var i = 0; i < binary.GetLength(0); i++ )
{
var row = new List<int>();
for(var j = 0; j < binary.GetLength(1); j++)
row.Add(binary[i, j]);
list.Add(row);
}
then remove the rows and columns which are all zero:
// Remove the rows
list = list.Where(row => row.Contains(1)).ToList();
// Reverse the matrix and apply the same procedure to remove the columns
list = Transpose(list);
list = list.Where(row => row.Contains(1)).ToList();
// Get back the original order of the rows and columns
list = Transpose(list);
static List<List<int>> Transpose(List<List<int>> input)
{
return input.ElementAt(0).Select((item, index) =>
{
var row = new List<int>{input[0][index]};
input.ForEach(el => row.Add(el.ElementAt(index)));
return row;
}).ToList();
}
}
and then transform your resulting list back into a [,]
.
int[,] binaryResult = new int[list.Count(), list.First().Count()];
for (int i = 0; i < binaryResult.GetLength(0); i++)
for (int j = 0; j < binaryResult.GetLength(1); j++)
binaryResult[i, j] = list.ElementAt(i).ElementAt(j);
You should extract these into methods, of course.
Upvotes: 3
Reputation: 11
Without fancy stuff:
int width = binaryzacja.GetLength(0);
int height = binaryzacja.GetLength(1);
int newWidth = width;
int newHeight = height;
int x, y, x2, y2;
for (y = 0; y < height; y++)
{
if (IsRowEmpty(binaryzacja, y)) newHeight--;
}
for (x = 0; x < width; x++)
{
if (IsColumnEmpty(binaryzacja, x)) newWidth--;
}
int[,] binaryzacja2 = new int[newWidth, newHeight];
// copy to new array
for (y2 = y = 0; y < height; y++)
{
if (!IsRowEmpty(binaryzacja, y))
{
for(x = x2 = 0; x < width; x++)
{
if (!IsColumnEmpty(binaryzacja, x))
{
binaryzacja2[x2, y2] = binaryzacja[x, y];
x2++;
}
}
y2++;
}
}
bool IsRowEmpty(int[,] array, int y)
{
for (int x = 0; x < array.GetLength(0); x++)
{
if (array[x, y] != 0) return false;
}
return true;
}
bool IsColumnEmpty(int[,] array, int x)
{
for (int y = 0; y < array.GetLength(1); y++)
{
if (array[x, y] != 0) return false;
}
return true;
}
----- new version:
int width = binaryzacja.GetLength(0);
int height = binaryzacja.GetLength(1);
int newWidth = width;
int newHeight = height;
int[] keepRows = new int[height];
int[] keepColumns = new int[width];
int x, y, x2, y2;
int i;
for (i = y = 0; y < height; y++)
{
if (IsRowEmpty(binaryzacja, y)) newHeight--;
else
{
keepRows[i] = y;
i++;
}
}
for (i = x = 0; x < width; x++)
{
if (IsColumnEmpty(binaryzacja, x)) newWidth--;
else
{
keepColumns[i] = x;
i++;
}
}
int[,] binaryzacja2 = new int[newWidth, newHeight];
// copy to new array
for (y2 = y = 0; y < height; y++)
{
if(y == keepRows[y2])
{
for (x2 = x = 0; x < width; x++)
{
if(x == keepColumns[x2])
{
binaryzacja2[x2, y2] = binaryzacja[x, y];
x2++;
}
}
y2++;
}
}
Upvotes: 1
Reputation: 71
Loop through the rows, and keep track of the empty ones in an array of some sort. Do the same with the columns.
Using this information, create a new array of the proper rows and columns. Loop through with a double loop. if i is equal to a row in the array, or j is equal to the row in the column, then skip over that value.
Upvotes: 0