Image processing with tinySGFriends of tinySG,For almost a decade I neglected to accept the importance of 2D image processing. I felt that if it is not 3D, it cannot be cool. Objectively, almost all my attempts to improve digital images taken on holidays came out worse than the original picture (in addition to have an undetermined feeling of "cheating" when manipulating photos).Artists forced me to reconsider my position on 2D image processing by producing real nice renderings for marketing purposes: They played with light setups, added contrasts and effects like glow to create a real atmosphere in the scene, rather than just doing the plain, clean mathematics I used to do. The image to the right shows an Mercedes SLK model in a night scene, with some environment reflection. The picture feels artificial and generated.
By integration of the image processor into tinySG's utility library, tsgEdit
has access to a wide range of customisable image processing filters. The
picture comes to live, creating some additional atmosphere. The image to
the left shows the same scene, using a glow filter.
The tinySG image processor tinySG's image processor is entirely separated from the render pipeline. An application may choose to utilise it wherever needed: It may serve as a post processor after rendering a scene, just before the image is finally displayed in the window. It may serve as a video exporter, writing out renderings to image or video files. It may be used in an image processing pipeline, not related to the tinySG scene graph at all and even act as a real-time texture processor while rendering a 3D scene. The image processor implements a directed, acyclic graph of image sources, filters and sinks, each of them represented by a C++ class. Sources may be tinySGs realtime renderer, video or image files. The input images are processed by a filter to do color correction, apply special effects, etc. The filters output are either passed to another filter or consumed by image sinks like a render window or an image file. tsgEdit comes with the filter network editor shown to the left. A filter network is created by drag 'n drop, connecting available sources, sinks and filters together. Filter tweakables are edited on the right hand side of the dialog.
Filters may be implemented either in GLSL or OpenCL (yet about to come, prototype runs). GLSL filters may be described by an XML filter library, eliminating the need to use a compiler.
Filters may utilise multiple passes that calculate intermediate
results. This feature allows to go for some cheeky performance trick,
providing realtime performance even for large convolution kernels.
class csgYUVFilter: public csgImageFilter { public: csgYUVFilter () {} virtual ~csgYUVFilter () {} protected: // Provide base classes pure virtual interface: virtual char* GetShaderSource() { static char src[] = "uniform sampler2D tex; \ void main() \ { \ vec4 color = texture2D(tex,gl_TexCoord[0].st); \ float Y = dot (vec4 (0.229, 0.587, 0.114, 0.0), color); \ gl_FragColor = vec4(Y); \ }"; return src; } }; About Performance Currently, the image processor performs at least three blits: From framebuffer to an FBO texture, running a filter that renders into another FBO texture and copying the result of the filter chain back to the frame buffer. More blit operations will happen if a filter works with multiple passes (like e.g. the glow filter) or if filters are chained one after another.By rendering directly into an FBO, the 1st blit would become unnecessary. The same optimisation could be applied to the final back-copy, so that two blits could be saved easily. However, doing so would sacrifice some flexibility and code elegance, so I decided against it for now. The following charts are taken on a MacBook Pro with a Geforce 9600M, running Windows XP. Naturally, the performance of 2D operations is a function of the resolution of the input image. The benchmark has been running at 1280x768, measuring frames per second (so higher values are better). 400fps translate to 2.5ms render time per frame, if the image processor is disabled. Enabling the image processor with a YUV filter, the framerate drops to 250fps (4.0ms/frame). Thus, the cost of the YUV filter is about 1.5ms per frame at 1280x768, including blit operations. The ISS and MountaineerEngine datasets render much slower. Large glow or blur kernels are quiet expensive and will hurt for datasets like the ISS. All other filters add a 2D processing overhead of roughly 10%, which again is hardly noticeable. The following chart shows the performance of tinySGs test systems, running different processors, GPUs and operating systems. Thus, the data helps to reckon a platforms/architectures performance. It is not suitable as a fair comparison of CPUs or GPUs. The MacBook runs Windows XP/32 (!), Core i7 system runs Windows 7/64 and the AMD machine is a 64Bit Linux/X11 PC. Once again, the teapot has been used as test dataset in order to de-emphasise GL rendering and focus on the image processors performance. Acknowledgements:
Copyright by Christian Marten, 2011-2014 Last change: 22.08.2011 |