Я работаю над приложением, которое связано с изменением цветового эффекта в изображении. Я сделал почти все. Теперь проблема в том, что в одном из эффектов я должен дать эффект, подобный фильтру светящихся краев в фотошопе. Этот фильтр обтекает края изображения своим цветом, а остальные цвета изображения черными. Используя BradLarson GPU Image GPUImageSobelEdgeDetectionFilter или GPUImageCannyEdgeDetectionFilter, я могу найти края, но с краями белого цвета, и мне нужно найти края в цветах. Есть ли у них другой способ найти края в цвете с помощью GPUImage или openCV. Любая помощь будет очень полезна для меня. Спасибо
Как найти края изображения с его цветами в iphone?
Ответы (1)
Вы действительно обязаны поиграть с написанием пользовательских шейдеров. Это чрезвычайно доступно и может очень быстро стать мощным, если вы приложите усилия.
Тем не менее, я думаю, что вы пытаетесь получить что-то вроде этого результата:
Есть много приемлемых способов добраться сюда, но написание пользовательского шейдера для подкласса GPUImageTwoInputFilter с последующим нацеливанием на него как исходного изображения, так и изображения edgeDetection — вот как я достиг картинки, которую вы видите здесь.
Подкласс будет выглядеть примерно так:
#import "OriginalColorEdgeMixer.h"
//Assumes you have targeted this filter with the original image first, then with an edge detection filter that returns white pixels on edges
//We are setting the threshold manually here, but could just as easily be a GLint which is dynamically fed at runtime
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kOriginalColorEdgeMixer = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
lowp float threshold;
mediump float resultingRed;
mediump float resultingGreen;
mediump float resultingBlue;
void main()
{
mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
threshold = step(0.3, textureColor2.r);
resultingRed = threshold * textureColor.r;
resultingGreen = threshold * textureColor.g;
resultingBlue = threshold *textureColor.b;
gl_FragColor = vec4(resultingRed, resultingGreen, resultingBlue, textureColor.a);
}
);
#else
NSString *const kGPUImageDifferenceBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
float threshold;
float resultingRed;
float resultingGreen;
float resultingBlue;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
threshold = step(0.3,textureColor2.r);
resultingRed = threshold * textureColor.r;
resultingGreen = threshold * textureColor.g;
resultingBlue = threshold *textureColor.b;
gl_FragColor = vec4(resultingRed, resultingGreen, resultingBlue, textureColor.a);
}
);
#endif
@implementation OriginalColorEdgeMixer
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kOriginalColorEdgeMixer]))
{
return nil;
}
return self;
}
@end
Поскольку я писал это, мы ожидаем, что выход фильтра edgeDetection будет вторым входом этого пользовательского фильтра.
Я произвольно выбрал пороговое значение 0,3 для интенсивности на изображении edgeDetection, чтобы исходный цвет был виден. Это можно легко сделать динамическим, привязав его к GLint, полученному из UISlider в вашем приложении (много примеров этого в примере кода Брэда)
Для ясности для людей, которые только начинают работать с GPUImage, использовать написанный вами пользовательский фильтр очень просто. Я сделал это так:
[self configureCamera];
edgeDetection = [[GPUImageSobelEdgeDetectionFilter alloc] init];
edgeMixer = [[OriginalColorEdgeMixer alloc] init];
[camera addTarget:edgeDetection];
[camera addTarget:edgeMixer];
[edgeDetection addTarget:edgeMixer];
[edgeMixer addTarget:_previewLayer];
[camera startCameraCapture];
Подводя итог, не бойтесь начинать писать собственные шейдеры! Кривая обучения коротка, а ошибки, выдаваемые отладчиком, чрезвычайно полезны, позволяя вам точно знать, где вы испортили синтаксис.
Наконец, это отличное место для документации по синтаксису и использованию специальных функций OpenGL