首页 > 解决方案 > c# 从子矩阵创建矩阵

问题描述

你好高技能程序员

我有一个 1600x1600 的测试图像。我将它作为灰度 int 值导入到矩阵中。然后我从该矩阵创建了 4x4 子矩阵。我在这些块中进行了一些数学运算并创建了新块。现在我需要从新的 4x4 块中再次创建一个新矩阵(1600x1600)。但我无法创建循环。我总共有 (1600/4 * 1600/4 = 160 000) 个子矩阵。(当然我的程序不是静态的,输入图像可以是任何东西。这是用于测试图像)。现在这是我的结构。

Bitmap bmp = new Bitmap("c:\\test.jpg");
pictureBox1.Image = Image.FromFile("c:\\test.jpg");
int width = bmp.Width; int height = bmp.Height;

  while (y < height) {
      while (x < width) {
      pxl = bmp.GetPixel(x, y);
      int_grayscale_map[x, y] = GetGrayScale(pxl); //getgrayscale is function that returns int value
      x++;}
   y++;}

   int totalblocknumber = (width/4) * (height / 4); //160 000 in this case

现在我从这些代码中创建并填充了子块。有人在这里帮助了我。(认为我们将 1600x1600 图像困惑为 4x4 件)

Bitmap image = new Bitmap(FILENAME);

        List<List<List<Int32>>> grayscale_map_block = newList<List<List<Int32>>>();
         for (int row = 0; row < height; row += 4)
        {
            for (int col = 0; col < width; col += 4)
            {
                block.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_block.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))} ,
                });

            }
        }          // Getgrayscale is a function that input color return int value

就是这样。现在我有 160 000 块 4x4 矩阵,名为“grayscale_map_block” ,我正在使用此代码获取块 grayscale_map_block [n] [x] [y] / n'th block 的元素,x,y 元素。其中n = 0-totalblocknumber

从这些块中,我必须巧妙地创建一个将各个部分组合在一起的循环。一个新的 1600x1600 矩阵。谢谢你的帮助。。

标签: c#imageloopsmatrixsubmatrix

解决方案


您可以像这样映射 [x,y] -> [n,x_,y_]:

n = (y / 4) * (width/4) + (x/4);
x_ = x % 4;
y_ = y % 4;

想法是计算n是垂直使用子块的索引(y / 4),然后将其乘以一行中的子块数(宽度/ 4),然后加上子块的索引- 水平块(x / 4)。

然后使用模运算符 (%) 计算子块内的行、列地址。

从 [n,x_,y_] 映射到 [x,y]

x = (n % (width / 4)) * 4 + x_;
y = (n / (width / 4)) * 4 + y_;

想法是从单个索引 n 中恢复子块的水平和垂直索引。垂直索引是n除以一行中的子块数,即(宽度/4)。像素的垂直地址是垂直索引乘以 4 加上子块行。在水平方向上,您再次使用模运算符来恢复块的水平索引。n %(宽度/4)。然后类似地,乘以 4 并加上 x_ 得到水平像素索引(列索引)。

注意:我提供的数学只有在宽度和高度是 4 的偶数倍数时才有效。如果宽度和高度没有被 4 整除,那么您必须进行稍微不同的数学运算,但您还需要处理不是 4 x 4,所以我假设您现在不想这样做 - 但如果需要,我也可以帮助您。


推荐阅读