C # Деление матрицы на субблоки - PullRequest
0 голосов
/ 31 августа 2018

у меня матрица пришла с картинки 1600х1600. Теперь мне нужно назначить эту матрицу в 4x4 блоков. Как пример:

              00 01 02 03
      IMAGE = 04 05 06 07        BLOCK(i) =   00 01       BLOCK(i+1) = 02 03
              08 09 0A 0B                     04 05                    06 07
              0C 0D 0E 0F
                                BLOCK(i+2) = 08 09        BLOCK(i+3) = 0A 0B
                                             0C 0D                   = 0E 0F

1) Во-первых, я не знаю размеров изображения, пользователь открывает его. я получу это позже. мое тестовое изображение 1600x1600. Но размеры блоков зафиксированы на 4x4. И размеры изображения, давайте мы согласимся, можно разделить с 4 на данный момент ...

2) Я не знаю, сколько будет блоков.

3) Мне нужно получить доступ к строке и столбцу блоков позже, потому что я буду выполнять математические операции с блоками позже ... Например, операция XOR с блоком (n) [x, y] с блоком (n +1) [х, у]. Итак, эта часть объявления, эта часть программы очень и очень важна.

Я закрепил эту часть программы на 2 недели, не могу продолжить. Пожалуйста, помогите мне. Это выглядит очень простым кодом, но .......

Моя структура такая, начальная часть

 private void Form1_Load(object sender, EventArgs e)
  {
    Bitmap bmp = new Bitmap("c:\\yavanna.jpg");
    pictureBox1.Image = Image.FromFile("c:\\yavanna.jpg");

    int width = bmp.Width;
    int height = bmp.Height;
    Color p;
    int[,] alpha_map_int = new int[width, height];
    int[,] red_map_int = new int[width, height];
    int[,] green_map_int = new int[width, height];
    int[,] blue_map_int = new int[width, height];
    int[,] grayscale_map_int = new int[width, height];

    string[,] gray_scale_map = new string[width, height];

    string temp_hexValue;

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //get pixel value
            p = bmp.GetPixel(x, y);

            //extract pixel component ARGB
            int a = p.A;
            alpha_map_int[x, y] = a;

            int r = p.R;
            red_map_int[x, y] = r;

            int g = p.G;
            green_map_int[x, y] = g;

            int b = p.B;
            blue_map_int[x, y] = b;

            //convert to gryscale
            double grayscale = 0.2126 * red_map_int[x,y] + 0.7152 * green_map_int[x, y] + 0.0722 * blue_map_int[x, y];
            grayscale_map_int[x, y] = Convert.ToInt32(grayscale);
            temp_hexValue = Convert.ToString(grayscale_map_int[x, y]);
            gray_scale_map[x, y] = temp_hexValue;
      }
    }

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Вот вариант ответа jdweng, который генерирует массивы 4x4 и обрабатывает исходные массивы, которые не делятся на 4. Вы можете понять, почему он опубликовал упрощенный образец. Еще больше, и для заполнения массива 4x4 стоило бы использовать еще два цикла.

'image' - это ввод, 'bytes4x4' - это вывод.

List<List<List<byte>>> bytes4x4 = new List<List<List<byte>>>();

for (int row = 0; row<length-3 ; row += 4)
{
    for (int col = 0; col<width-3; col += 4)
    {
        bytes4x4.Add(new List<List<byte>>()  { 
            new List<byte>() { image[row, col], image[row, col + 1], image[row, col + 2], image[row, col + 3]}, 
            new List<byte>() { image[row + 1, col], image[row + 1, col + 1], image[row + 1, col + 2], image[row + 1, col + 3] }, 
            new List<byte>() { image[row + 2, col], image[row + 2, col + 1], image[row + 2, col + 2], image[row + 2, col + 3] },
            new List<byte>() { image[row + 3, col], image[row + 3, col + 1], image[row + 3, col + 2], image[row + 3, col + 3] }
    });
}

Это объявляет и заполняет 'bytes4x4', который является длинным списком двумерных блоков. Доступ к блоку, как это:

var block100 = bytes4x4[100];

И используйте это, чтобы получить пиксель:

var block100pixelrow1col3 = block100[1][3];

или

var block100pixelrow1col3 = bytes4x4[100][1][3];

Обратите внимание, что все эти индексы основаны на нулях, поэтому в блоках нет элемента [4].

Теперь я думаю об этом, вы можете быть после 2-мерного массива 2-мерных блоков. Если это так, код будет выглядеть так:

var bytes4x4 = new List<List<List<List<byte>>>>();

for (int row = 0; row<length-3 ; row += 4)
{
    var row = new List<List<List<byte>>>();
    bytes4x4.Add(row);
    for (int col = 0; col<width-3; col += 4)
    {
        row.Add(new List<List<byte>>()  { 
            new List<byte>() { image[row, col], image[row, col + 1], image[row, col + 2], image[row, col + 3]}, 
            new List<byte>() { image[row + 1, col], image[row + 1, col + 1], image[row + 1, col + 2], image[row + 1, col + 3] }, 
            new List<byte>() { image[row + 2, col], image[row + 2, col + 1], image[row + 2, col + 2], image[row + 2, col + 3] },
            new List<byte>() { image[row + 3, col], image[row + 3, col + 1], image[row + 3, col + 2], image[row + 3, col + 3] }
    });
}

Тогда вы можете получить доступ к блоку, который на 14 строк ниже и на 23 столбца такой:

var block14by23 = bytes4x4[14][23];
0 голосов
/ 31 августа 2018

Попробуйте следующее:

       const string FILENAME = @"c:\temp\test.jpg";
        public Form1()
        {
            InitializeComponent();

            Bitmap image = new Bitmap(FILENAME);


            int height = (int)image.Height ;
            int width = (int)image.Width;


            List<List<List<Color>>> bytes = new List<List<List<Color>>>();
            List<List<List<Int32>>> grayscale_map_int = new List<List<List<Int32>>>();


            for (int row = 0; row < height; row += 4)
            {
                for (int col = 0; col < width; col += 4)
                {
                    bytes.Add(new List<List<Color>>()  { 
                         new List<Color>() { image.GetPixel(col, row), image.GetPixel(col + 1, row), image.GetPixel(col + 2, row), image.GetPixel(col + 3, row)} , 
                         new List<Color>() { image.GetPixel(col, row + 1), image.GetPixel(col + 1, row + 1), image.GetPixel(col + 2, row + 1), image.GetPixel(col + 3, row + 1)} , 
                         new List<Color>() { image.GetPixel(col, row + 2), image.GetPixel(col + 1, row + 2), image.GetPixel(col + 2, row + 2), image.GetPixel(col + 3, row + 2)} , 
                         new List<Color>() { image.GetPixel(col, row + 3), image.GetPixel(col + 1, row + 3), image.GetPixel(col + 2, row + 3), image.GetPixel(col + 3, row + 3)} , 
                    });

                    grayscale_map_int.Add(new List<List<Int32>>()  { 
                         new List<Int32>() { GetGrayScale(image.GetPixel(col, row)), GetGrayScale(image.GetPixel(col + 1, row)), GetGrayScale(image.GetPixel(col + 2, row)), GetGrayScale(image.GetPixel(col + 3, row))} , 
                         new List<Int32>() { GetGrayScale(image.GetPixel(col, row + 1)), GetGrayScale(image.GetPixel(col + 1, row + 1)), GetGrayScale(image.GetPixel(col + 2, row + 1)), GetGrayScale(image.GetPixel(col + 3, row + 1))} , 
                         new List<Int32>() { GetGrayScale(image.GetPixel(col, row + 2)), GetGrayScale(image.GetPixel(col + 1, row + 2)), GetGrayScale(image.GetPixel(col + 2, row + 2)), GetGrayScale(image.GetPixel(col + 3, row + 2))} , 
                         new List<Int32>() { GetGrayScale(image.GetPixel(col, row + 3)), GetGrayScale(image.GetPixel(col + 1, row + 3)), GetGrayScale(image.GetPixel(col + 2, row + 3)), GetGrayScale(image.GetPixel(col + 3, row + 3))} , 
                    });

                }
            } 


        }
        public Int32 GetGrayScale(Color color)
        {
            return Convert.ToInt32(0.2126 * color.R + 0.7152 * color.G + 0.0722 * color.B);
        }
...