Как динамически добавить новую матрицу к изображению
Здравствуйте, я работаю над обработкой изображений(проектированием пользовательского интерфейса) с помощью C#.Net и против 2012 года. Я добавил фильтр свертки в свою форму. Я добавил матрицу ядра в бэк-конец, но теперь я хочу добавить новые матрицы(любого размера-3*3, 5*5, 7*7 и т. д.) Во время выполнения. Я не знаю, что и как делать. Кто-нибудь может мне помочь, пожалуйста.
(Когда мы нажимаем на кнопку свертки, появляется новая форма и просит ввести новую матрицу. Здесь я сталкиваюсь с проблемой, я не могу спроектировать формат для ввода матрицы в формате строки-столбца(создавая разные ячейки для ввода данных)).
Что я уже пробовал:
//Код для свертки
private static double[,] kernel { get { return new double[,] { { 0, 1, 0 }, { 1, -4, 1 }, { 0, 1, 0 } }; } } private void btnConvolution_Click(object sender, EventArgs e) { newBitmap = (Bitmap)pictureBox1.Image; int width = newBitmap.Width; int height = newBitmap.Height; BitmapData srcData = newBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int bytes = srcData.Stride * srcData.Height; byte[] buffer = new byte[bytes];//new array byte[] result = new byte[bytes]; Marshal.Copy(srcData.Scan0, buffer, 0, bytes); newBitmap.UnlockBits(srcData); int colorChannels = 3;//3 color channels double[] rgb = new double[colorChannels]; int foff = (kernel.GetLength(0) - 1) / 2; int kcenter = 0; int kpixel = 0; for (int y = foff; y < height - foff; y++) { for (int x = foff; x < width - foff; x++) { for (int c = 0; c < colorChannels; c++) { rgb[c] = 0.0; } kcenter = y * srcData.Stride + x * 4; for (int fy = -foff; fy <= foff; fy++) { for (int fx = -foff; fx <= foff; fx++) { kpixel = kcenter + fy * srcData.Stride + fx * 4; for (int c = 0; c < colorChannels; c++) { rgb[c] += (double)(buffer[kpixel + c]) * kernel[fy + foff, fx + foff]; } } } for (int c = 0; c < colorChannels; c++) { if (rgb[c] > 255) { rgb[c] = 255; } else if (rgb[c] < 0) { rgb[c] = 0; } } for (int c = 0; c < colorChannels; c++) { result[kcenter + c] = (byte)rgb[c]; } result[kcenter + 3] = 255; } } Bitmap resultImage = new Bitmap(width, height); BitmapData resultData = resultImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(result, 0, resultData.Scan0, bytes); resultImage.UnlockBits(resultData); newBitmap = (Bitmap)resultImage.Clone(); pictureBox1.Image = newBitmap; btnUndo.Enabled = true; undostack.Push(pictureBox1.Image); } }
Richard MacCutchan
Вы можете использовать DataGridView необходимого количества строк и столбцов. Просто попросите пользователя заполнить цифры и нажать кнопку, когда закончите.
Member 13341679
Как он будет меняться в зависимости от размера матрицы, здесь размер матрицы также меняется. Как принять это значение в код для дальнейших вычислений.
Richard MacCutchan
Подумайте об этом в логических терминах:
Сколько строк вам нужно?
Сколько колонок вам нужно?
Попросите пользователя предоставить вам эту информацию.
Теперь вы можете создать сетку с необходимым количеством ячеек, пользователь может ввести значения, и из этого вы можете создать свою динамическую матрицу.
Member 13341679
Это пользовательский интерфейс, и пользователь может занять до 9*9 матриц(3*3,5*5,7*7,9*9 имеются в наличии). Поэтому, если я добавляю формат матрицы 9*9, а пользователь принимает 5*5, то значение будет пустым, и код не будет выполняться. Надеюсь, вы поняли, что я пытаюсь сказать.
Richard MacCutchan
Затем либо исправьте свой код, либо сделайте то, что я предложил. Ничто из этого не является особенно трудным при использовании .Чистый контроль.
lukeer
Таким образом, вам нужно, чтобы пользователь выбрал один из четырех возможных размеров ядра.
Все в порядке, ваше свойство ядра имеет тип double[,]
Он должен быть в состоянии обрабатывать различные размеры. И код, который его использует, проверяет фактический размер ядра в int foff = (kernel.GetLength(0) - 1) / 2;
В чем именно вы видите проблему?
Member 13341679
В коде нет никаких проблем. Здесь я сам назначил матрицу в соответствии с моим использованием, но я хочу сделать ее динамической, чтобы пользователь мог вставить матрицу по своему выбору. Я не знаю, как это сделать успешно.
lukeer
Дайте пользователю пользовательский интерфейс.
Вы могли бы поставить 4 Практическое руководствоs на бланке вместе с радиокнопкаs, которые указывают, какой из них использовать.
Затем пользователь может поместить свои предпочтительные значения фильтра в одну из сеток, вы бы сделали каждый ввод, чтобы также выбрать соответствующую сетку.
Затем эта форма отвечает за предоставление
public double[,] Kernel { get { // export correct values } }собственность. И там у вас есть свои ценности.