使用着色器可视化两个图像的交集

问题描述

我正在尝试使用着色器可视化两个图像的交集。这是图片

shadow1

shadow2

我使用认的片段着色器代码来建立基础,如here所示:

import QtQuick 2.0
import QtQuick.Controls 2.0

applicationwindow {
    width: 640
    height: 480
    title: "Finding image intersection with a shader"
    visible: true

    Column {
        Row {
            Column {
                Image {
                    id: shadow1
                    source: "https://i.stack.imgur.com/VzpV8.png"
                }
                Label {
                    text: "shadow1"
                }
            }

            Column {
                Image {
                    id: shadow2
                    source: "https://i.stack.imgur.com/z9bxx.png"
                }
                Label {
                    text: "shadow2"
                }
            }

            Column {
                Item {
                    width: 100
                    height: 100
                    Image {
                        source: shadow1.source
                    }
                    Image {
                        source: shadow2.source
                    }
                }
                Label {
                    text: "intersection"
                }
            }
        }

        Row {
            Column {
                ShaderEffect {
                    width: shadow1.width
                    height: shadow1.height

                    property var source: shadow1

                    fragmentShader: "
                        varying highp vec2 qt_TexCoord0;
                        uniform sampler2D source;
                        uniform lowp float qt_Opacity;
                        void main() {
                            gl_FragColor = texture2D(source,qt_TexCoord0) * qt_Opacity;
                        }"
                }
                Label {
                    text: "shader"
                }
            }
        }
    }
}

到目前为止的结果:

screenshot

如何将这两个图像作为输入并渲染得到的相交?

解决方法

这是一种实现方法:

import QtQuick 2.0
import QtQuick.Controls 2.0

ApplicationWindow {
    width: 640
    height: 480
    title: "Finding image intersection with a shader"
    visible: true

    Column {
        Row {
            Column {
                Image {
                    id: shadow1
                    source: "https://i.stack.imgur.com/VzpV8.png"
                }
                Label {
                    text: "shadow1"
                }
            }

            Column {
                Image {
                    id: shadow2
                    source: "https://i.stack.imgur.com/z9bxx.png"
                }
                Label {
                    text: "shadow2"
                }
            }

            Column {
                Item {
                    width: 100
                    height: 100
                    Image {
                        source: shadow1.source
                    }
                    Image {
                        source: shadow2.source
                    }
                }
                Label {
                    text: "intersection"
                }
            }
        }

        Row {
            Column {
                ShaderEffect {
                    width: shadow1.width
                    height: shadow1.height

                    property var source1: shadow1
                    property var source2: shadow2

                    fragmentShader: "
                        varying highp vec2 qt_TexCoord0;
                        uniform sampler2D source1;
                        uniform sampler2D source2;
                        uniform lowp float qt_Opacity;
                        void main() {
                            vec4 colour1 = texture2D(source1,qt_TexCoord0);
                            vec4 colour2 = texture2D(source2,qt_TexCoord0);
                            if (colour1.a > 0.0 && colour2.a > 0.0) {
                                // There is an intersection here; mark it.
                                gl_FragColor = vec4(0.4,0.0,0.5);
                            } else {
                                // There's no intersection here; make this pixel transparent.
                                gl_FragColor = vec4(0.0,0.0);
                            }
                        }"
                }
                Label {
                    text: "shader"
                }
            }
        }
    }
}

我将简要解释我所做的补充:

uniform sampler2D source1;
uniform sampler2D source2;

这两行声明了输入图像。 sampler2D是指Qt Quick的Image类型。

    vec4 colour1 = texture2D(source1,qt_TexCoord0);
    vec4 colour2 = texture2D(source2,qt_TexCoord0);

这两行声明了两个vec4变量,用于存储此坐标(qt_TextCoord0)上每个像素的颜色。

    if (colour1.a > 0.0 && colour2.a > 0.0) {
        // There is an intersection here; mark it.
        gl_FragColor = vec4(0.4,0.5);
    } else {
        // There's no intersection here; make this pixel transparent.
        gl_FragColor = vec4(0.0,0.0);
    }

if语句检查每个像素的alpha值。如果它们都不为零,则将绘制一个半透明的红色像素。

结果:

screenshot