Pull to refresh

Comments 37

Как я понимаю это размытие создано для создания такого эффекта некой краски. А вообще можно в редакторе сделать как бы нарисованный фон с человеком без размытия.
Очень жаль что вся статья по сути состоит из 6 картинок. Т.е. сама тема интересна, но статья уж больно маленькая :-(
Как-то мало информации, чем он лучше фильтра того же Гаусса? где целесообразно применять данный фильтр?
фильтр Гаусса Размывает изображение не сохраняя информации о краев. Применять можно в сегментации. Например, стоит задача обнаружение водоемов на космоснимках. Если применять фильтр Гаусса, границы будет определить сложнее
Исходное изображение:
image
Размытие Гауссом
image
Размытие Кувахара
image
Хм… да действительно, нужно попробовать сделать данное размытие перед детектором Канни.
Детектор Канни, примененный к изображениям выше соответственно




Гхм. А если правильно параметры детектора границ настроить — он их везде выделит хоть какие-то. Некорректно сравнить детектор с одинаковыми параметрами.
Не корректно само понятие «детектор Канни». В своих работах Kanny обозначил сам подход, и сделал это на столько остроумно, что программисты наплодили из него большое число «алгоритмов» :-) в то время как для большинства частных случаев выделения края, можно обойтись вообще ОДНОЙ свёрткой, без какой-либо предварительной фильтрации.
Черт, не выходит! Надо кривые подкрутить.

Для понимания алгоритма не хватает картинки после шага 1, когда маска наложена, но последний фильтр не применён
чёрт, кажется туплю. на первом шаге не фильтр, а просто разметка картинки
Вот с сегментации и надо было начинать, а то эти эффекты красок уже надоели…
UFO just landed and posted this here
Да, алгоритм применяется к каждому каналу
Только, наверное, интенсивность для дисперсии нужно общую брать (max(r, g, b)). Иначе, представим, что в по красной компоненте наибольшая дисперсия в левом верхнем квадранте, по зелёной — в правом верхнем, по синей — где нибудь ещё. В итоге будут взяты средние значения компонент из разных квадрантов и получатся абсолютно новые цвета.

Или вообще считать не по RGB, а HSL (не уверен про расчёт среднего hue).
В оригинале Кувахара применяется к каждому каналу отдельно. Хотя ваша модификация фильтра тоже интересна. Интересно будет сравнить имеющиеся результаты с вашей модификацией.
К сожалению, в статье все изображения уменьшены и повреждены jpeg-ом. Вот что получилось у меня (21x21):

Выбор по отдельным интенсивностям: при сильном увеличении видны мусорные пиксели из компонент разных квадрантов.


Выбор квадранта по значению (максимальной интенсивности): всё чисто.
По небольшой части изображения сложно судить результат, выложите изображение полностью.
Оригинал:
habrastorage.org/storage2/530/b03/638/530b036382e0a669cb1fbeb719f24220.jpg

Отдельные каналы, цветущие края:
habrastorage.org/storage2/d59/1c2/55b/d591c255bb7f9a5c6cfdb81789165aa4.png

Максимальный канал:
habrastorage.org/storage2/0c9/b65/62d/0c9b6562df0c87f15d0bb3f5f21de405.png

void KuwaharaOperation::getMeanAndVariance(int x0, int y0, int x1, int y1, float output[3], float variance[3])
{
	float color[3], mean[3];
	float var[3] = {0.0f};
	int count = (y1 - y0 + 1) * (x1 - x0 + 1);
	
	for (int y = y0; y <= y1; y++) {
		for (int x = x0; x <= x1; x++) {
			this->m_inputOperation->read(color, x, y, NULL);
			add_v3_v3(mean, color);
		}
	}
	 
	mul_v3_fl(mean, 1.0f / count);
	
	for (int y = y0; y <= y1; y++) {
		for (int x = x0; x <= x1; x++) {
			this->m_inputOperation->read(color, x, y, NULL);
			sub_v3_v3(color, mean);
			mul_v3_v3(color, color);
			add_v3_v3(var, color);
		}
	}
	
    // Код для отдельных каналов
//	if (variance[0] > var[0]) {
//		output[0] = mean[0];
//		variance[0] = var[0];
//	}
//	if (variance[1] > var[1]) {
//		output[1] = mean[1];
//		variance[1] = var[1];
//	}
//	if (variance[2] > var[2]) {
//		output[2] = mean[2];
//		variance[2] = var[2];
//	}
	
	// Код для общей интенсивности
	if (MAX3(variance[0], variance[1], variance[2]) > MAX3(var[0], var[1], var[2])) {
		copy_v3_v3(output, mean);
		copy_v3_v3(variance, var);
	}
}

void KuwaharaOperation::executePixel(float output[4], int x, int y, void *data)
{
	float color_org[4];
	float variance[4] = {FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX};
	int size = this->m_size;
	int x1 = x - size, x2 = x, x3 = x + size;
	int y1 = y - size, y2 = y, y3 = y + size;
	
	CLAMP(x1, 0, getWidth() - 1);
	CLAMP(x2, 0, getWidth() - 1);
	CLAMP(x3, 0, getWidth() - 1);
	CLAMP(y1, 0, getHeight() - 1);
	CLAMP(y2, 0, getHeight() - 1);
	CLAMP(y3, 0, getHeight() - 1);

	this->m_inputOperation->read(color_org, x, y, NULL);
	
	this->getMeanAndVariance(x1, y1, x2, y2, output, variance);
	this->getMeanAndVariance(x1, y2, x2, y3, output, variance);
	this->getMeanAndVariance(x2, y1, x3, y2, output, variance);
	this->getMeanAndVariance(x2, y2, x3, y3, output, variance);
	output[3] = color_org[3];
}
А с первого взгляда потеря цвета не заметна. Замечание очень даже хорошее, спасибо.
результат отличия от surface blur минимален.

и surface blur для поиска водоёмов, больше подошел бы. хотя при любом варианте использование в таких целях — полный бред.
Умиляют меня такие посты, с обилием картинок, сравнением чего-то с чем-то, без каких-либо попыток осмысления происходящего, вообще… Но за-то с умными словами и фамилиями людей в работы которых не разу не заглядывали.
Неплохо бы привести сравнение с медианным фильтром, т.к. результаты схожие. Более того, мне обработка медианным фильтром нравится больше, т.к. не вносит больших искажений в форму объектов.
Обратите внимание на то, как овальные объекты (сверху и ближе к центру левее) разделились на несколько фрагментов:

Это уже недопустимо для последующей обработки краев.
эти фильтры схожи тем, что они сохраняют информацию о краях и хорошо удаляют импульсный шум, но в отличие от фильтра кувахары, в медианном фильтре области изображения не становится однородными, поэтому результаты не совсем схожи.
исходное изображение
image
кувахара 21х21
image
медианный фильтр 9х9
image

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

>Обратите внимание на то, как овальные объекты (сверху и ближе к центру левее) разделились на несколько фрагментов
>Это уже недопустимо для последующей обработки краев.
Замечание хорошее. Из-за большого радиуса размытия небольшие объекты делятся на несколько (такова особенность фильтра). Но это не критично т.к. чаще всего маленькие объекты принимаются за шум.
В случае, если необходимо сохранить небольшие объекты, то необходимо уменьшить радиус размытия
кувахара 9х9
image
Сказать по правде это плохо походит на работу написанную красками. Как минимум именно потому, что края остаются слишком резкими для картины написанной красками, да ещё и как следует из описания — «грубо». Было бы грубо, края были бы ещё сильнее оборваны.
Точно так же и цветовые переходы внутри объекта — слишком резко меняются для такой техники.
Здесь есть некие сходства с картинами в стиле экспрессионизма
image
Совсем небольшое. если сравнивать с конкретной картиной то тут мазки по другому ложатся, да и края в той или иной степени очерчены.

Вообще по правде говоря мало фильтров работают и создают хорошую стилизацию определенной техники, даже в профильных программах, под это заточенных, типа Corel Painter и в фотошопе. Для того чтобы было похоже приходится вручную допиливать в любом случае.
Sign up to leave a comment.

Articles