1. Homepage
  2. Programming
  3. CUDA Lab 4. CUDA OpenGL Interoperability & Image processing

CUDA Lab 4. CUDA OpenGL Interoperability & Image processing

Engage in a Conversation
C++CUDAOpenGL

CUDA Lab 4. CUDA OpenGL Interoperability & Image processing CourseNana.COM

  1. Learn how to load an image using CUDA SDK
  2. Understand how to use OpenGL textures in a CUDA kernel
  3. Learn how to edit an image by writing a kernel function
  4. Understand the basic principle of smoothing an image
  5. Understand how to implement the bilinear and cubic image smoothing filters.

Exercise 1. Create an OpenGL-CUDA program based on a CUDA SDK sample CourseNana.COM

  1. Starting from the CUDA template program created in VS2019 or VS2022. Replace the default “kernel.cu” CUDA program with “ImageProcess_cuda.cpp” and “ImageProcess_cuda.cu” provided under the Week4’s module section, which are the simplified version of “bicubicTexture.cpp” and “bicubicTexture_cuda.cu” provided in the CUDA Samples folder. This simple framework provides you a framework for loading an image to GPU and processing it using CUDA. If you do not have any knowledge with OpenGL API, please following the tutorial provided from the link below to gain a basic understanding how OpenGL API interoperate with CUDA: https://www.3dgep.com/opengl-interoperability-with- cuda/#Download_the_Source
  2. Edit VS2019/VS2022 VC++ directories
    1. Go to GitHub - NVIDIA/cuda-samples: Samples for CUDA Developers which

demonstrates features in CUDA Toolkit CourseNana.COM

    1. If you have cloned the samples, you can find the folder “Common” from where you have saved the samples
    2. Open project properties and edit VC++ Directories

Add the folder name to VC++ directories. In my computer, the location is at “C:\Users\cssql\source\repos\cuda-samples\Common\lib\x64”, so it looks like CourseNana.COM

  1. Next edit Lib directories

Find the location of “\cuda-samples\Common\lib\x64” in your computer and add it to the Library Directories CourseNana.COM

  1. Edit library input libraries under the linker

nput the following filenames under the Linker folder “freeglut.lib” and “glew64.lib” CourseNana.COM

f. Copy the files “ freeglut.dll”, “glew64.dll”, “FreeImage.dll” from the bin folder of CUDA Samples to the folder containing your compiled program. CourseNana.COM

  1. Download the test image “lena_bw.pgm” to place it in your project folder.
  2. Compile and observe if the project can be compiled and run properly.

Exercise 2. Understand pixel colour CourseNana.COM

  1. An image is simply a 2D array of pixels. Each pixel has a colour value which can be digitally represented as a list of numbers, depending on the data format adopted. In the framework, the colour of each pixel is represented in RGBA format using 4 integers, each of which ranging from 0 to 255. Open ImageProcess_cuda.cu and go to the method d_render( ), modify the 4 numbers shown in make_uchar4( ..., ..., ..., ... ) in the following line:

d_output[i] = make_uchar4(c * 0xff, c * 0xff, c * 0xff, 0); CourseNana.COM

say,
d_output[i] = make_uchar4(0xff, 0, 0, 0);
CourseNana.COM

and then CourseNana.COM

d_output[i] = make_uchar4(0, 0xff, 0, 0); CourseNana.COM

d_output[i] = make_uchar4(0, 0, 0xff, 0); CourseNana.COM

  1. The original image is a grey value image, the pixel intensity at a pixel position at (u,v) is read using

float c = tex2DFastBicubic<uchar, float>(texObj, u, v); where c is in [0, 1]. CourseNana.COM

  1. Now modify the value d_output[i] using image pixel value c read from image location at (u, v) with the following colour and observe how the image colour is changed.

d_output[i] = make_uchar4(0, 0, c*0xff, 0); CourseNana.COM

Exercise 3. Image transformation CourseNana.COM

As an image is simply a 2D array of colours, it can be processed by employing a collection of threads arranged in two-dimensional manner. So, each pixel can be identified directly based on the thread indices and block indices, as well as block size. Rewrite the lines on the definition of x, y and i variables in the form you are familiar with: CourseNana.COM

uint x = blockIdx.x*blockDim.x + threadIdx.x; uint y = blockIdx.y*blockDim.y + threadIdx.y; CourseNana.COM

uint i = y* width + x; CourseNana.COM

The __umul24 ( unsigned int x, unsigned int y ) used in the original code is a function defined in math.h, which calculates the least significant 32 bits of the product of the least significant 24 bits of two unsigned integers. CourseNana.COM

  1. Translate the image.
    1. Define a translation as a 2D vector, say

float2 T={20, 10}; CourseNana.COM

    1. Translate (x, y) with vector T:

x +=T.x; CourseNana.COM

y +=T.y; CourseNana.COM

    1. Read pixel colour with translated coordinates x, y:

float c = tex2D<float>(texObj, x, y); CourseNana.COM

    1. Compile the run your program and observe if the image is translated according to

your wish. CourseNana.COM

    1. Observe how the image is transformed by defining different translation vectors.
  1. Scale the image
    1. Define a scaling transformation as a 2D vector, say

float2 S= {1.2, 0.5}; CourseNana.COM

    1. Scale (x, y) with vector S:

x *=S.x; CourseNana.COM

y *=S.y; CourseNana.COM

    1. Read pixel colour with scaled coordinates x, y:

float c = tex2D<float>(texObj, x, y); CourseNana.COM

    1. Compile the run your program and observe if the image is scaled according to your

wish. CourseNana.COM

    1. Observe how the image is scaled by defining different scaling vectors.
  1. Rotate the image
    1. Define a rotation matrix for a certain rotation angle, say

float angle = 0.5; CourseNana.COM

    1. Rotate (x, y) with rotation matrix defined below:

? = (cos⁡(?????) −sin⁡(?????)) sin⁡(?????) cos⁡(?????) CourseNana.COM

float rx =x* cos(angle) -y*sin(angle); CourseNana.COM

float ry =x*sin(angle) + y* cos(angle); CourseNana.COM

    1. Read pixel colour with scaled coordinates uv: float c = tex2D<float>(texObj, rx, ry);
    2. Compile the run your program and observe if the image is rotated according to your wish.
    3. Further observe how the image is rotated by defining different rotation angles.
  1. Scaling by position (cx, cy)
    The scaling transformation considered above is about the coordinate origin (0, 0). Scaling image by a position (cx, cy) can be done in the following way:

float u = (x - cx)*scale + cx; CourseNana.COM

float v = (y - cy)*scale + cy; Show how to scale the image by its centre. CourseNana.COM

  1. Rotate image by the image centre
    The rotation defined above is about the coordinate origin (0, 0). Modify the code given in step 3 to rotate the image by the image centre.
  2. The following lines of code shown in the original sample code is a combination of both scaling and translation. What it does is to scale the image by location (cx, cy) and then translate the image with a vector (tx, ty):

float u = (x - cx)*scale + cx + tx; float v = (y - cy)*scale + cy + ty; CourseNana.COM

Go the render( ) method and modify the values of tx, ty, scale, cx, cy and observe how the image is transformed.. CourseNana.COM

Exercise 4. Image smoothing (Optional). CourseNana.COM

A 2D image is essentially a 2D array of colours, which can be understood as a matrix of colours. For instance, for the coin image shown below, a close-up look at the area of “8” is shown below, where each pixel element can be clearly seen. CourseNana.COM

(191, 138, 94) CourseNana.COM

To smooth an image, the basic idea is for each pixel, find its neighbour colours, and use the average colour to replace the original colour. For instance, the order one squared neighbour at pixel a contains 9 pixels CourseNana.COM

As the calculation of the average colour for each neighbouring box can be done pixel by pixel independently in parallel, CUDA can be used to solve the problem. Now modify the kernel function tex2DBicubic( ) to understand the basic principle of how an image can be smoothed. CourseNana.COM

1. For a pixel at location (px, py), replace its original colour with the average of the following five pixel colour (the original pixel colour + four neighbour pixels colours): CourseNana.COM

float centre= tex2D< float >(tex, px , py); float left = tex2D< float >(tex, px - 1, py); float right = tex2D< float >(tex, px + 1, py); float up = tex2D< float >(tex, px, py + 1); float down = tex2D< float >(tex, px, py - 1); CourseNana.COM

return (centre + left + right + up + down)/5; CourseNana.COM

2.     Run your program and observe how image has been smoothed. CourseNana.COM

3.     (Optional) Smooth the image using 16 squared neighbour colours. CourseNana.COM

4.     Modify the thread configuration and observe the performance of your program. CourseNana.COM

  CourseNana.COM

Get in Touch with Our Experts

WeChat WeChat
Whatsapp WhatsApp
C++代写,CUDA代写,OpenGL代写,C++代编,CUDA代编,OpenGL代编,C++代考,CUDA代考,OpenGL代考,C++help,CUDAhelp,OpenGLhelp,C++作业代写,CUDA作业代写,OpenGL作业代写,C++编程代写,CUDA编程代写,OpenGL编程代写,C++programming help,CUDAprogramming help,OpenGLprogramming help,C++assignment help,CUDAassignment help,OpenGLassignment help,C++solution,CUDAsolution,OpenGLsolution,