I have a custom Metal CIKernel that displays edges on the image in red color. In the shader, I do a convolution to compute Sobel gradient and then return the color as red or original color. But I believe there should be a way to do the same using builtin CIFilters or MPS shaders. But how?
extern "C" half4 drawEdges (coreimage::sampler inputImage,
coreimage::destination dest)
{
float2 destCoord = dest.coord();
float2 srcCoord = inputImage.coord();
half4 color = half4(inputImage.sample(srcCoord));
float2 m11Coord = inputImage.transform(destCoord + float2(-1.0,+1.0));
half3 m11 = half3(inputImage.sample(m11Coord).rgb);
float2 m12Coord = inputImage.transform(destCoord + float2(0.0,+1.0));
half3 m12 = half3(inputImage.sample(m12Coord).rgb);
float2 m13Coord = inputImage.transform(destCoord + float2(+1.0,+1.0));
half3 m13 = half3(inputImage.sample(m13Coord).rgb);
float2 m21Coord = inputImage.transform(destCoord + float2(-1.0,0.0));
half3 m21 = half3(inputImage.sample(m21Coord).rgb);
float2 m23Coord = inputImage.transform(destCoord + float2(+1.0,0.0));
half3 m23 = half3(inputImage.sample(m23Coord).rgb);
float2 m31Coord = inputImage.transform(destCoord + float2(-1.0,-1.0));
half3 m31 = half3(inputImage.sample(m31Coord).rgb);
float2 m32Coord = inputImage.transform(destCoord + float2(0.0,-1.0));
half3 m32 = half3(inputImage.sample(m32Coord).rgb);
float2 m33Coord = inputImage.transform(destCoord + float2(+1.0,+1.0));
half3 m33 = half3(inputImage.sample(m33Coord).rgb);
half3 m31m13 = m31 - m13;
half3 m11m33 = m33 - m11;
half3 m32m12 = m32 - m12;
half3 m21m23 = m21 - m23;
half3 H = m32m12 + m32m12 + m11m33 + m31m13;
half3 V = m21m23 + m21m23 - m11m33 + m31m13;
half3 sobel = sqrt(H*H+V*V);
half sobelLength = length(sobel);
if (sobelLength > 0.9) {
half4 redColor = half4(0.5h, 0.h, 0.0, 1.0);
color = redColor;
}
return half4(color);
}
Maybe a filter chain like this would roughly do the same:
Note that I converted the input to grayscale using
CIPhotoEffectNoire
here becauseCIEdges
actually returns the sobel edges in color, which is harder to color in with red.