我希望在iOS应用程序中将中位数过滤器应用于UIImage。 由于我的公司限制,我不能使用openGL过滤器。
任何想法或当前的实施都会受到欢迎。 感谢。
答案 0 :(得分:4)
Apple的Core Image
框架可能是您的解决方案。确切地说,您需要一个CIFilter
的子类来实现中值过滤器。 (猜猜你会对CIMedianFilter
感兴趣或者看看filter reference)
CIIImage *inputImage = //...
CIFilter *filter = [CIFilter filterWithName:@"CIMedianFilter"];
[filter setDefaults];
[filter setValue:inputImage forKey:@"inputImage"];
CIImage *outputImage = [filter outputImage];
要将CIImage
转换为UIImage
,反之亦然:
CIImage *ciImage = [UIImage imageNamed:@"test.png"].CIImage;
UIImage *uiImage = [[UIImage alloc] initWithCIImage:ciImage];
答案 1 :(得分:1)
看看github项目:
https://github.com/BradLarson/GPUImage
这些是GPU加速的许多CIFilter类型过滤器。
另一种选择:使用卷积滤波器并使用CI的内核语言滚动自己的中值滤波器。
答案 2 :(得分:0)
对于那些可以在您的iOS应用中使用OpenGL ES的人来说,这就是您计算所选像素邻域半径的中位数的方法:
kernel vec4 medianUnsharpKernel(sampler u) {
vec4 pixel = unpremultiply(sample(u, samplerCoord(u)));
vec2 xy = destCoord();
int radius = 3;
int bounds = (radius - 1) / 2;
vec4 sum = vec4(0.0);
for (int i = (0 - bounds); i <= bounds; i++)
{
for (int j = (0 - bounds); j <= bounds; j++ )
{
sum += unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j)))));
}
}
vec4 mean = vec4(sum / vec4(pow(float(radius), 2.0)));
float mean_avg = float(mean);
float comp_avg = 0.0;
vec4 comp = vec4(0.0);
vec4 median = mean;
for (int i = (0 - bounds); i <= bounds; i++)
{
for (int j = (0 - bounds); j <= bounds; j++ )
{
comp = unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j)))));
comp_avg = float(comp);
median = (comp_avg < mean_avg) ? max(median, comp) : median;
}
}
return premultiply(vec4(vec3(abs(pixel.rgb - median.rgb)), 1.0));
}
步骤的简要说明 1.计算3x3邻域中源像素周围的像素值的平均值; 2.找到同一邻域中小于均值的所有像素的最大像素值。 3. [可选]从源像素值中减去中值像素值以进行边缘检测。
如果您使用中值进行边缘检测,有几种方法可以修改上述代码以获得更好的结果,即混合中值滤波和截断媒体滤波(替代和更好的“模式”滤波) 。如果您有兴趣,请询问。
答案 3 :(得分:0)
如果有人想在Xamarin(iOS)中使用,请输入以下代码:
public static UIImage MedianFilter(UIImage image)
{
CIImage ciImage = new CIImage(image);
var medianFilter = new CIMedianFilter() { Image = ciImage };
CIImage output = medianFilter.OutputImage;
var context = CIContext.FromOptions(null);
var cgimage = context.CreateCGImage(output, output.Extent);
var uiImage = UIImage.FromImage(cgimage);
return uiImage;
}