Visual Servoing Platform  version 3.6.1 under development (2025-02-18)
vpPanda3DCommonFilters.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  */
30 
31 #include <visp3/ar/vpPanda3DCommonFilters.h>
32 #include <visp3/ar/vpPanda3DRGBRenderer.h>
33 
34 #if defined(VISP_HAVE_PANDA3D)
35 
36 #include "windowFramework.h"
37 #include "graphicsOutput.h"
38 
39 
40 BEGIN_VISP_NAMESPACE
41 const std::string vpPanda3DLuminanceFilter::FRAGMENT_SHADER =
42 "#version 330\n"
43 "in vec2 texcoords;\n"
44 "uniform sampler2D p3d_Texture0;\n"
45 "out vec4 p3d_FragData;\n"
46 "void main() {\n"
47 " vec4 v = texture(p3d_Texture0, texcoords);\n"
48 " p3d_FragData.b = 0.299 * v.r + 0.587 * v.g + 0.114 * v.b;\n"
49 "}\n";
50 
51 vpPanda3DLuminanceFilter::vpPanda3DLuminanceFilter(const std::string &name, std::shared_ptr<vpPanda3DRGBRenderer> inputRenderer, bool isOutput)
52  : vpPanda3DPostProcessFilter(name, inputRenderer, isOutput, std::string(vpPanda3DLuminanceFilter::FRAGMENT_SHADER))
53 { }
54 FrameBufferProperties vpPanda3DLuminanceFilter::getBufferProperties() const
55 {
56  FrameBufferProperties fbp;
57  fbp.set_depth_bits(0);
58  fbp.set_rgba_bits(0, 0, 8, 0);
59  fbp.set_float_color(false);
60  return fbp;
61 }
63 {
65 }
66 
67 const std::string vpPanda3DGaussianBlur::FRAGMENT_SHADER =
68 "#version 330\n"
69 "in vec2 texcoords;\n"
70 "uniform sampler2D p3d_Texture0;\n"
71 "uniform vec2 dp; // 1 divided by number of pixels\n"
72 "const float kernel[25] = float[25](\n"
73 " 2, 4, 5, 4, 2,\n"
74 " 4, 9, 12, 9, 4,\n"
75 " 5, 12, 15, 12, 5,\n"
76 " 4, 9, 12, 9, 4,\n"
77 " 2, 4, 5, 4, 2\n"
78 ");\n"
79 "const float normalize = 1 / 159.0;\n"
80 "vec2 offset[25] = vec2[25](\n"
81 " vec2(-2*dp.x,-2*dp.y), vec2(-dp.x,-2*dp.y), vec2(0,-2*dp.y), vec2(dp.x,-2*dp.y), vec2(2*dp.x,-2*dp.y),\n"
82 " vec2(-2*dp.x,-dp.y), vec2(-dp.x, -dp.y), vec2(0.0, -dp.y), vec2(dp.x, -dp.y), vec2(2*dp.x,-dp.y),\n"
83 " vec2(-2*dp.x,0.0), vec2(-dp.x, 0.0), vec2(0.0, 0.0), vec2(dp.x, 0.0), vec2(2*dp.x,0.0),\n"
84 " vec2(-2*dp.x, dp.y), vec2(-dp.x, dp.y), vec2(0.0, dp.y), vec2(dp.x, dp.y), vec2(2*dp.x, dp.y),\n"
85 " vec2(-2*dp.x, 2*dp.y), vec2(-dp.x, 2*dp.y), vec2(0.0, 2*dp.y), vec2(dp.x, 2*dp.y), vec2(2*dp.x, 2*dp.y)\n"
86 ");\n"
87 "out vec4 p3d_FragData;\n"
88 "void main() {\n"
89 " float v = 0.f;\n"
90 " for(int i = 0; i < 25; ++i) {\n"
91 " v += kernel[i] * texture(p3d_Texture0, texcoords + offset[i]).b;\n"
92 " }\n"
93 " p3d_FragData.b = v * normalize;\n"
94 "}\n";
95 
96 vpPanda3DGaussianBlur::vpPanda3DGaussianBlur(const std::string &name, std::shared_ptr<vpPanda3DBaseRenderer> inputRenderer, bool isOutput)
97  : vpPanda3DPostProcessFilter(name, inputRenderer, isOutput, vpPanda3DGaussianBlur::FRAGMENT_SHADER)
98 { }
99 
100 FrameBufferProperties vpPanda3DGaussianBlur::getBufferProperties() const
101 {
102  FrameBufferProperties fbp;
103  fbp.set_depth_bits(0);
104  fbp.set_rgba_bits(0, 0, 8, 0);
105  fbp.set_float_color(false);
106  return fbp;
107 }
108 
110 {
112 }
113 
114 const std::string vpPanda3DCanny::FRAGMENT_SHADER =
115 "#version 330\n"
116 "in vec2 texcoords;\n"
117 "uniform sampler2D p3d_Texture0;\n"
118 "uniform vec2 dp; // 1 divided by number of pixels\n"
119 "uniform float edgeThreshold;\n"
120 "const float kernel[9] = float[9](\n"
121 " 0.0, 1.0, 0.0,\n"
122 " 1.0,-4.0, 1.0,\n"
123 " 0.0, 1.0, 0.0\n"
124 ");\n"
125 "const float kernel_h[9] = float[9](\n"
126 " -1.0, 0.0, 1.0,\n"
127 " -2.0, 0.0, 2.0,\n"
128 " -1.0, 0.0, 1.0\n"
129 ");\n"
130 "const float kernel_v[9] = float[9](\n"
131 " -1.0, -2.0, -1.0,\n"
132 " 0.0, 0.0, 0.0,\n"
133 " 1.0, 2.0, 1.0\n"
134 ");\n"
135 "vec2 offset[9] = vec2[9](\n"
136 " vec2(-dp.x, -dp.y), vec2(0.0, -dp.y), vec2(dp.x, -dp.y),\n"
137 " vec2(-dp.x, 0.0), vec2(0.0, 0.0), vec2(dp.x, 0.0),\n"
138 " vec2(-dp.x, dp.y), vec2(0.0, dp.y), vec2(dp.x, dp.y)\n"
139 ");\n"
140 "out vec4 p3d_FragData;\n"
141 "void main() {\n"
142 " float sum = 0.f;\n"
143 " for(int i = 0; i < 9; ++i) {\n"
144 " float pix = texture(p3d_Texture0, texcoords + offset[i]).b;\n"
145 " sum += pix * kernel[i];\n"
146 " }\n"
147 " if(abs(sum * 255.f) > edgeThreshold) {\n"
148 " float sum_h = 0.f;\n"
149 " float sum_v = 0.f;\n"
150 " for(int i = 0; i < 9; ++i) {\n"
151 " float pix = texture(p3d_Texture0, texcoords + offset[i]).b;\n"
152 " sum_h += pix * kernel_h[i];\n"
153 " sum_v += pix * kernel_v[i];\n"
154 " }\n"
155 " vec2 orientationAndValid = sum_h * sum_h + sum_v * sum_v > 0 ? vec2(-atan(sum_v/sum_h), 1.f) : vec2(0.f, 0.f);\n"
156 " p3d_FragData = vec4(sum_h, sum_v, orientationAndValid.x, orientationAndValid.y);\n"
157 " } else {\n"
158 " p3d_FragData = vec4(0.f, 0.f, 0.f, 0.f);\n"
159 " }\n"
160 "}\n";
161 
162 vpPanda3DCanny::vpPanda3DCanny(const std::string &name, std::shared_ptr<vpPanda3DBaseRenderer> inputRenderer, bool isOutput, float edgeThreshold)
163  : vpPanda3DPostProcessFilter(name, inputRenderer, isOutput, vpPanda3DCanny::FRAGMENT_SHADER), m_edgeThreshold(edgeThreshold)
164 { }
165 
167 {
169  m_renderRoot.set_shader_input("edgeThreshold", LVector2f(m_edgeThreshold));
170 }
171 
172 void vpPanda3DCanny::setEdgeThreshold(float edgeThreshold)
173 {
174  m_edgeThreshold = edgeThreshold;
175  m_renderRoot.set_shader_input("edgeThreshold", LVector2f(m_edgeThreshold));
176 }
177 
178 FrameBufferProperties vpPanda3DCanny::getBufferProperties() const
179 {
180  FrameBufferProperties fbp;
181  fbp.set_depth_bits(0);
182  fbp.set_rgba_bits(32, 32, 32, 32);
183  fbp.set_float_color(true);
184  return fbp;
185 }
186 
188 {
190 }
191 
192 END_VISP_NAMESPACE
193 
194 #elif !defined(VISP_BUILD_SHARED_LIBS)
195 // Work around to avoid warning: libvisp_ar.a(vpPanda3DCanny.cpp.o) has no symbols
196 void dummy_vpPanda3DCanny() { };
197 
198 #endif
NodePath m_renderRoot
Rendering parameters.
Implementation of canny filtering, using Sobel kernels.
void setupScene() VP_OVERRIDE
Initialize the scene for this specific renderer.
void getRender(vpImage< vpRGBf > &I) const
void setEdgeThreshold(float edgeThreshold)
FrameBufferProperties getBufferProperties() const VP_OVERRIDE
vpPanda3DCanny(const std::string &name, std::shared_ptr< vpPanda3DBaseRenderer > inputRenderer, bool isOutput, float edgeThreshold)
Class that implements a gaussian filter on a grayscale image. The grayscale image should be contained...
FrameBufferProperties getBufferProperties() const VP_OVERRIDE
void getRender(vpImage< unsigned char > &I) const
vpPanda3DGaussianBlur(const std::string &name, std::shared_ptr< vpPanda3DBaseRenderer > inputRenderer, bool isOutput)
Class that implements an RGB to grayscale conversion.
FrameBufferProperties getBufferProperties() const VP_OVERRIDE
void getRender(vpImage< unsigned char > &I) const
vpPanda3DLuminanceFilter(const std::string &name, std::shared_ptr< vpPanda3DRGBRenderer > inputRenderer, bool isOutput)
Base class for postprocessing filters that map the result of a vpPanda3DBaseRenderer to a new image.
void getRenderBasic(vpImage< unsigned char > &I) const
virtual void setupScene() VP_OVERRIDE
Initialize the scene for this specific renderer.