提问人:Deepak Sharma 提问时间:11/5/2023 更新时间:11/6/2023 访问量:32
在 CIImage 的边缘上绘制线叠加
Drawing line overlays over edges of CIImage
问:
我有一个自定义的 Metal CIKernel,它以红色显示图像的边缘。在着色器中,我执行卷积以计算 Sobel 渐变,然后将颜色返回为红色或原始颜色。但我相信应该有一种方法可以使用内置的 CIFilter 或 MPS 着色器来做同样的事情。但是如何?
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);
}
答:
1赞
Frank Rupprecht
11/6/2023
#1
也许像这样的过滤器链大致可以做同样的事情:
┌───────────────────────────────────────────────────────────────────────────┐
│ ▼
input ───► CIPhotoEffectNoire ───► CIEdges ───► CIBlendWithMask ───► CISourceOverCompositing ───► output
▲
CIImage(color: .red) ────────────┘
请注意,我使用 here 将输入转换为灰度,因为实际上返回了彩色的 sobel 边缘,而红色则更难着色。CIPhotoEffectNoire
CIEdges
评论
0赞
Deepak Sharma
11/7/2023
如果我想根据边缘清晰度将边缘与红色混合来平滑输出,如何从上面的灰度图像中获得颜色强度。
0赞
Deepak Sharma
11/7/2023
也看看这个问题。
1赞
Frank Rupprecht
11/7/2023
的输出应该已经反映了边缘的锐度/陡度,即更锐利的边缘应该产生更高的“颜色”值。当将其用作在黑色背景上混合红色图像的蒙版时,您应该在较强的边缘处获得更强的红色。CIEdges
0赞
Deepak Sharma
11/7/2023
很好,但问题是如何检测RGB空间中跨色域工作的颜色(强度)值?Metal Core Image 采样器不支持一维灰度空间(与 Metal 着色器不同,Metal 着色器可以指定 .r8 等格式)。在它不存在的情况下,我依靠计算适用于 BT.709 空间的点积。我不确定同样的事情是否会为 BT.2020 产生准确的结果。(0.2126, 0.7152, 0.0722)
评论