Algoholic.in.ua

Решения > Фильтрация изображений. Матрица свертки

Фильтрация изображений. Матрица свертки С++

Категория: Решения | Добавлено: 2016-02-01 | Просмотров: 1439

Матрица свертки (она же - матрица конволюции) - матрица, которая состоит из определенных коэффициентов. Она служит фильтром, через который пропускается входящее изображение. Для применения фильтра, проходимся по изображению точка за точкой. Каждый из пикселей рассматриваем вместе с матрицей, центральным элементом которой он является. Для применения фильтра, перемножаем соответствующие значения двух матриц и их сумму присваиваем рассматриваемой точке.


У некоторых матриц свертки есть коэффициент нормирования, который является делителем для каждого элемента матрицы. Обычно матрицы размером 3х3 достаточно для применения фильтра, хотя существуют и матрицы 5х5 и 10х10. В нашей программе рассматривается первый случай.


Пример воздействия матрицы свертки на точку:


Матрица свертки. Размытие


В данном примере рассматривается пиксель с значением цвета 43. Матрица, которая располагается вокруг данного элемента, умножается на матрицу размытия. Все элементы последней матрицы суммируем и получаем значение пикселя равное 56. Его и записываем вместо поточного пикселя. Данную процедуру необходимо провести для каждого из каналов изображения.


А что же делать с "крайними" пикселями, вокруг которых невозможно построить матрицу? Для таких случаев необходимо просто продублировать значения таких "крайних" рядов/столбцов изображения.


Следующий код написан под Visual studio.


Реализация на C++:


private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
	Bitmap^ inputPicture = gcnew Bitmap(pictureBox1->Image);
	Bitmap^ outputPicture = gcnew Bitmap(inputPicture->Width, inputPicture->Height);
	Byte R, G, B;
	Color^ tempColor;
	double covolutionMatrix[3][3];
    //ниже - примеры четырех матриц свертки
	if (comboBox1->SelectedItem == "Размытие") {
		float div = 9;
		covolutionMatrix[0][0] = 1 / div;
		covolutionMatrix[0][1] = 1 / div;
		covolutionMatrix[0][2] = 1 / div;

		covolutionMatrix[1][0] = 1 / div;
		covolutionMatrix[1][1] = 1 / div;
		covolutionMatrix[1][2] = 1 / div;

		covolutionMatrix[2][0] = 1 / div;
		covolutionMatrix[2][1] = 1 / div;
		covolutionMatrix[2][2] = 1 / div;
	}

	if (comboBox1->SelectedItem == "Четкость") {

		covolutionMatrix[0][0] = -1;
		covolutionMatrix[0][1] = -1;
		covolutionMatrix[0][2] = -1;

		covolutionMatrix[1][0] = -1;
		covolutionMatrix[1][1] = 9;
		covolutionMatrix[1][2] = -1;

		covolutionMatrix[2][0] = -1;
		covolutionMatrix[2][1] = -1;
		covolutionMatrix[2][2] = -1;
	}

	if (comboBox1->SelectedItem == "Выделение краев") {
		covolutionMatrix[0][0] = 0;
		covolutionMatrix[0][1] = 1;
		covolutionMatrix[0][2] = 0;

		covolutionMatrix[1][0] = 1;
		covolutionMatrix[1][1] = -4;
		covolutionMatrix[1][2] = 1;

		covolutionMatrix[2][0] = 0;
		covolutionMatrix[2][1] = 1;
		covolutionMatrix[2][2] = 0;
	}

	if (comboBox1->SelectedItem == "Рельеф") {
		covolutionMatrix[0][0] = -2;
		covolutionMatrix[0][1] = -1;
		covolutionMatrix[0][2] = 0;

		covolutionMatrix[1][0] = -1;
		covolutionMatrix[1][1] = 1;
		covolutionMatrix[1][2] = 1;

		covolutionMatrix[2][0] = 0;
		covolutionMatrix[2][1] = 1;
		covolutionMatrix[2][2] = 2;
	}

	for (int i = 0; i < inputPicture->Width; i++)
		for (int j = 0; j < inputPicture->Height; j++) {
			int koefR = 0, koefG = 0, koefB = 0;
			for (int ii = -1; ii < 2; ii++)
				for (int jj = -1; jj < 2; jj++) {
					int columnIndex = i + ii, rowIndex = j + jj;
                    //проверяем, не крайний ли пиксель
					if (columnIndex < 0) columnIndex++;
					else if (columnIndex >= inputPicture->Width) columnIndex--;
					if (rowIndex < 0)rowIndex++;
					else if (rowIndex >= inputPicture->Height) rowIndex--;
					tempColor = inputPicture->GetPixel(columnIndex, rowIndex);
                    //считаем новое значение пикселя
					R = tempColor->R;
					G = tempColor->G;
					B = tempColor->B;
					koefR += R * covolutionMatrix[1 + ii][1 + jj];
					koefG += G * covolutionMatrix[1 + ii][1 + jj];
					koefB += B * covolutionMatrix[1 + ii][1 + jj];
				}
			if (koefR < 0)koefR = 0;
			if (koefG < 0)koefG = 0;
			if (koefB < 0)koefB = 0;
			if (koefR > 255)koefR = 255;
			if (koefG > 255)koefG = 255;
			if (koefB > 255)koefB = 255;
			outputPicture->SetPixel(i, j, Color::FromArgb(koefR, koefG, koefB));
		}
		pictureBox2->Image = outputPicture;
}

Пример работы программы:


Матрица свертки. Четкость


Матрица свертки. Выделение краев


Матрица свертки. Размытие


Матрица свертки. Рельеф



Яндекс.Метрика
Украина онлайн