.. _gpuBasicsSimilarity:Similarity check (PNSR and SSIM) on the GPU*******************************************Goal====In the :ref:`videoInputPSNRMSSIM` tutorial I already presented the PSNR and SSIM methods forchecking the similarity between the two images. And as you could see there performing these takesquite some time, especially in the case of the SSIM. However, if the performance numbers of anOpenCV implementation for the CPU do not satisfy you and you happen to have an NVidia CUDA GPUdevice in your system all is not lost. You may try to port or write your algorithm for the videocard.This tutorial will give a good grasp on how to approach coding by using the GPU module of OpenCV. Asa prerequisite you should already know how to handle the core, highgui and imgproc modules. So, ourgoals are:..container:: enumeratevisibleitemswithsquare+ What's different compared to the CPU?+ Create the GPU code for the PSNR and SSIM+ Optimize the code for maximal performanceThe source code===============You may also find the source code and these video file in the:file:`samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity` folder of theOpenCV source library or :download:`download it from here<../../../../samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp>`. Thefull source code is quite long (due to the controlling of the application via the command linearguments and performance measurement). Therefore, to avoid cluttering up these sections with thoseyou'll find here only the functions itself.The PSNR returns a float number, that if the two inputs are similar between 30 and 50 (higher isbetter)...literalinclude:: ../../../../samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp:language:cpp:linenos::tab-width:4:lines:165-210, 18-23, 210-235The SSIM returns the MSSIM of the images. This is too a float number between zero and one (higher isbetter), however we have one for each channel. Therefore, we return a *Scalar* OpenCV datastructure:..literalinclude:: ../../../../samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp:language:cpp:linenos::tab-width:4:lines:235-355, 26-42, 357-How to do it? - The GPU=======================Now as you can see we have three types of functions for each operation. One for the CPU and two forthe GPU. The reason I made two for the GPU is too illustrate that often simple porting your CPU toGPU will actually make it slower. If you want some performance gain you will need to remember a fewrules, whose I'm going to detail later on.The development of the GPU module was made so that it resembles as much as possible its CPUcounterpart. This is to make porting easy. The first thing you need to do before writing any code isto link the GPU module to your project, and include the header file for the module. All thefunctions and data structures of the GPU are in a *gpu* sub namespace of the *cv* namespace. You mayadd this to the default one via the *use namespace* keyword, or mark it everywhere explicitly viathe cv:: to avoid confusion. I'll do the later...code-block::cpp#include<opencv2/gpu.hpp> // GPU structures and methodsGPU stands for **g**\ raphics **p**\ rocessing **u**\ nit. It was originally build to rendergraphical scenes. These scenes somehow build on a lot of data. Nevertheless, these aren't alldependent one from another in a sequential way and as it is possible a parallel processing of them.Due to this a GPU will contain multiple smaller processing units. These aren't the state of the artprocessors and on a one on one test with a CPU it will fall behind. However, its strength lies inits numbers. In the last years there has been an increasing trend to harvest these massive parallelpowers of the GPU in non-graphical scene rendering too. This gave birth to the general-purposecomputation on graphics processing units (GPGPU).The GPU has its own memory. When you read data from th