OnlineBodySchemaAdaptation  2.0
likelihood.cpp
Go to the documentation of this file.
1 // CUDAdll.cpp : Defines the exported functions for the DLL application.
2 /*
3  * Copyright: (C) 2017 VisLab, Institute for Systems and Robotics,
4  * Instituto Superior Técnico, Universidade de Lisboa, Lisbon, Portugal
5  * Author: Pedro Vicente <pvicente@isr.tecnico.ulisboa.pt>
6  * CopyPolicy: Released under the terms of the GNU GPL v3.0.
7  *
8  */
9 
10 // OpenGL
11 #include <gl\glew.h>
12 #include <gl\GL.h>
13 #include <gl\GLU.h>
14 #include <gl\glext.h>
15 
16 // CUDA stuff
17 #include <cuda_runtime.h>
18 #include <cuda_gl_interop.h>
19 
20 #include <helper_cuda.h>
21 #include <helper_cuda_gl.h>
22 
23 #include <helper_functions.h>
24 #include <rendercheck_gl.h>
25 
26 // OpenCV
27 #include <opencv2/imgproc/imgproc.hpp>
28 #include <opencv2/core/core.hpp>
29 #include <opencv2/highgui/highgui.hpp>
30 #include <opencv2/gpu/gpu.hpp>
31 #include <opencv2/gpu/gpumat.hpp>
32 
33 #include <stdio.h>
34 
35 using namespace std;
36 
70 extern "C" __declspec(dllexport) int UploadImToTexture(void* fboColorTex2, int width, int height, void* image, int align, int widthStep, int channels)
71 {
72  if (glGetError())
73  return -1;
74 
75  GLuint fboColorTex = (GLuint) (size_t) fboColorTex2;
76 
77  glBindTexture(GL_TEXTURE_2D, fboColorTex);
78  glPixelStorei (GL_UNPACK_ALIGNMENT, align);
79  glPixelStorei (GL_UNPACK_ROW_LENGTH, widthStep / channels);
80  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
81  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
82 
83  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 640, 240, 0, GL_BGR, GL_UNSIGNED_BYTE, image);
84 
85  if (glGetError())
86  return -2;
87  return 0;
88 }
89 
90 extern "C" __declspec(dllexport) int* CudaEdgeLikelihood(int height,int width,void* ID [200],void* ID_real, void* image, int align, int widthStep, int channels)
91 {
92  int * likelihood = new int[200];
93  extern void BindToTexture( cudaArray *cuArr );
94  extern void BindToTextureGray( cudaArray *cuArr );
95  extern void DeviceArrayCopyFromTexture( float3* dst, int dstStep, int width, int height );
96 
97  cv::Mat MatDisp;
98  cv::Mat MatDispR;
99  cv::Mat MatDispM;
100  cv::Mat MatDispView;
101  float sum, nonZero, zero;
102 
103  /************************************************************/
104 
105  // Seg
106  GLuint gltex;
107  struct cudaGraphicsResource *cuda_tex_screen_resource;
108  cv::gpu::GpuMat gpuMat(height,width, CV_32FC3 );
109  cv::gpu::GpuMat GgpuMat(height,width, CV_32FC1 );
110  cudaArray *cuArr;
111  // Real
112  GLuint gltex_R = (GLuint)(size_t)(ID_real);
113  struct cudaGraphicsResource *cuda_tex_screen_resource_R;
114  cv::gpu::GpuMat gpuMat_R(height,width, CV_32FC3 );
115  cv::gpu::GpuMat GgpuMat_R(height,width, CV_32FC1 );
116  cudaArray *cuArr_R;
117 
118  // Process
119  cv::gpu::GpuMat GpuMatMul(height,width, CV_32FC1);
120 
121  /**** Real ****/
122 
123  glBindTexture (GL_TEXTURE_2D, gltex_R);
124  glBindTexture(GL_TEXTURE_2D, gltex_R);
125  glPixelStorei (GL_UNPACK_ALIGNMENT, align);
126  glPixelStorei (GL_UNPACK_ROW_LENGTH, widthStep / channels);
127  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
128  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
129 
130  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 640, 240, 0, GL_BGR, GL_UNSIGNED_BYTE, image);
131 
132  checkCudaErrors( cudaGraphicsGLRegisterImage( &cuda_tex_screen_resource_R, gltex_R, GL_TEXTURE_2D, cudaGraphicsMapFlagsReadOnly ) );
133 
134  // Copy color buffer
135  checkCudaErrors( cudaGraphicsMapResources( 1, &cuda_tex_screen_resource_R, 0 ) );
136  checkCudaErrors( cudaGraphicsSubResourceGetMappedArray( &cuArr_R, cuda_tex_screen_resource_R, 0, 0 ) );
137 
138  BindToTexture( cuArr_R );
139 
140  DeviceArrayCopyFromTexture( (float3*)gpuMat_R.data, gpuMat_R.step, gpuMat_R.cols, gpuMat_R.rows );
141 
142  checkCudaErrors( cudaGraphicsUnmapResources( 1, &cuda_tex_screen_resource_R, 0 ) );
143  checkCudaErrors( cudaGraphicsUnregisterResource(cuda_tex_screen_resource_R));
144 
145  cv::gpu::cvtColor(gpuMat_R,GgpuMat_R,CV_RGB2GRAY);
146 
147  float result=0;
148  int lambdaEdge = 25;
149  for(int i=0;i<200;i++)
150  {
151  gltex = (GLuint)(size_t)(ID[i]); // ID is a vector with pointers to the render textures
152  glBindTexture (GL_TEXTURE_2D, gltex);
153  GLint width,height,internalFormat;
154  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPONENTS, &internalFormat); // get internal format type of GL texture
155  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); // get width of GL texture
156  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); // get height of GL texture
157 
158  checkCudaErrors( cudaGraphicsGLRegisterImage( &cuda_tex_screen_resource, gltex, GL_TEXTURE_2D, cudaGraphicsMapFlagsReadOnly ) );
159  // Copy color buffer
160  checkCudaErrors( cudaGraphicsMapResources( 1, &cuda_tex_screen_resource, 0 ) );
161  checkCudaErrors( cudaGraphicsSubResourceGetMappedArray( &cuArr, cuda_tex_screen_resource, 0, 0 ) );
162  BindToTexture( cuArr );
163 
164  DeviceArrayCopyFromTexture( (float3*)gpuMat.data, gpuMat.step, gpuMat.cols, gpuMat.rows ); // DeviceArrayCopyFromTexture function defined on Cuda_Gl.cu
165 
166  checkCudaErrors( cudaGraphicsUnmapResources( 1, &cuda_tex_screen_resource, 0 ) );
167  checkCudaErrors( cudaGraphicsUnregisterResource(cuda_tex_screen_resource));
168  cv::gpu::cvtColor(gpuMat,GgpuMat,CV_RGB2GRAY);
169 
170  // Apply the likelihood Assessment
171  // GgpuMat - generated Image
172  // GgpuMat_R - Real Distance Transform image
173  cv::gpu::multiply(GgpuMat,GgpuMat_R,GpuMatMul);
174  cv::Scalar sumS = cv::gpu::sum(GpuMatMul);
175 
176  /*
177  Check the article:
178  Online Body Schema Adaptation Based on Internal Mental Simulation and Multisensory Feedback, Vicente et al.
179  In particular, Equation (21)
180  */
181  sum = sumS[0]*lambdaEdge; // lambdaEdge is a tuning parameter for distance sensitivity
182  nonZero = (float) cv::gpu::countNonZero(GgpuMat); //generated image
183  if(nonZero==0)
184  {
185  likelihood[i] = 0.000000001; // Almost Zero
186  }
187  else
188  {
189  result = sum/nonZero;
190  likelihood[i] = (int)((cv::exp(-result)) *1000);
191  }
192  }
193  return likelihood;
194 }