Advertisement
UF6

Image Processing

UF6
Dec 23rd, 2024
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.46 KB | Source Code | 0 0
  1. import pyopencl as cl
  2. import numpy as np
  3. import cv2
  4. import time
  5.  
  6. # Helper function to load OpenCL kernel from file
  7. def load_kernel(filename):
  8.     with open(filename, 'r') as f:
  9.         return f.read()
  10.  
  11. # Initialize OpenCL context and queue
  12. def init_opencl():
  13.     platform = cl.get_platforms()[0]
  14.     device = platform.get_devices()[0]
  15.     context = cl.Context([device])
  16.     queue = cl.CommandQueue(context)
  17.     return context, queue
  18.  
  19. # Grayscale conversion kernel
  20. grayscale_kernel = """
  21. __kernel void grayscale(__global const uchar *input, __global uchar *output, const int width, const int height) {
  22.    int x = get_global_id(0);
  23.    int y = get_global_id(1);
  24.    int idx = y * width + x;
  25.    uchar r = input[3 * idx];
  26.    uchar g = input[3 * idx + 1];
  27.    uchar b = input[3 * idx + 2];
  28.    output[idx] = (uchar)(0.299f * r + 0.587f * g + 0.114f * b);
  29. }
  30. """
  31.  
  32. # Box blur kernel
  33. box_blur_kernel = """
  34. __kernel void box_blur(__global const uchar *input, __global uchar *output, const int width, const int height) {
  35.    int x = get_global_id(0);
  36.    int y = get_global_id(1);
  37.    int idx = y * width + x;
  38.    float sum = 0.0f;
  39.    int count = 0;
  40.    for (int i = -1; i <= 1; i++) {
  41.        for (int j = -1; j <= 1; j++) {
  42.            int xi = clamp(x + i, 0, width - 1);
  43.            int yj = clamp(y + j, 0, height - 1);
  44.            int kidx = yj * width + xi;
  45.            sum += input[kidx];
  46.            count++;
  47.        }
  48.    }
  49.    output[idx] = (uchar)(sum / count);
  50. }
  51. """
  52.  
  53. # Sobel edge detection kernel
  54. sobel_kernel = """
  55. __kernel void sobel(__global const uchar *input, __global uchar *output, const int width, const int height) {
  56.    int x = get_global_id(0);
  57.    int y = get_global_id(1);
  58.    int idx = y * width + x;
  59.    float Gx = 0.0f;
  60.    float Gy = 0.0f;
  61.    int sobel_x[3][3] = {
  62.        {-1, 0, 1},
  63.        {-2, 0, 2},
  64.        {-1, 0, 1}
  65.    };
  66.    int sobel_y[3][3] = {
  67.        {-1, -2, -1},
  68.        {0, 0, 0},
  69.        {1, 2, 1}
  70.    };
  71.    for (int i = -1; i <= 1; i++) {
  72.        for (int j = -1; j <= 1; j++) {
  73.            int xi = clamp(x + i, 0, width - 1);
  74.            int yj = clamp(y + j, 0, height - 1);
  75.            int kidx = yj * width + xi;
  76.            Gx += input[kidx] * sobel_x[i + 1][j + 1];
  77.            Gy += input[kidx] * sobel_y[i + 1][j + 1];
  78.        }
  79.    }
  80.    output[idx] = (uchar)clamp(sqrt(Gx * Gx + Gy * Gy), 0.0f, 255.0f);
  81. }
  82. """
  83.  
  84. # Function to run OpenCL kernel
  85. def run_kernel(context, queue, kernel_code, input_image, output_shape):
  86.     program = cl.Program(context, kernel_code).build()
  87.     mf = cl.mem_flags
  88.     input_buf = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=input_image)
  89.     output_buf = cl.Buffer(context, mf.WRITE_ONLY, output_shape.nbytes)
  90.     kernel = program.grayscale if 'grayscale' in kernel_code else program.box_blur if 'box_blur' in kernel_code else program.sobel
  91.     kernel.set_args(input_buf, output_buf, np.int32(input_image.shape[1]), np.int32(input_image.shape[0]))
  92.     cl.enqueue_nd_range_kernel(queue, kernel, input_image.shape[:2], None)
  93.     output_image = np.empty_like(output_shape)
  94.     cl.enqueue_copy(queue, output_image, output_buf)
  95.     return output_image
  96.  
  97. # Create synthetic images
  98. def create_gradient_image(width, height):
  99.     """Create a grayscale gradient image."""
  100.     gradient = np.linspace(0, 255, width, dtype=np.uint8)
  101.     gradient_image = np.tile(gradient, (height, 1))
  102.     return gradient_image
  103.  
  104. def create_checkerboard_image(width, height, num_squares):
  105.     """Create a checkerboard pattern image."""
  106.     checkerboard = np.zeros((height, width), dtype=np.uint8)
  107.     square_size = width // num_squares
  108.     for y in range(0, height, square_size * 2):
  109.         for x in range(0, width, square_size * 2):
  110.             checkerboard[y:y+square_size, x:x+square_size] = 255
  111.             checkerboard[y+square_size:y+square_size*2, x+square_size:x+square_size*2] = 255
  112.     return checkerboard
  113.  
  114. def create_noise_image(width, height):
  115.     """Create a random noise image."""
  116.     noise_image = np.random.randint(0, 256, (height, width), dtype=np.uint8)
  117.     return noise_image
  118.  
  119. def create_shapes_image(width, height):
  120.     """Create an image with basic geometric shapes."""
  121.     shapes_image = np.zeros((height, width), dtype=np.uint8)
  122.     cv2.circle(shapes_image, (width // 4, height // 4), 50, 255, -1)
  123.     cv2.rectangle(shapes_image, (width // 2, height // 2), (width // 2 + 100, height // 2 + 100), 255, -1)
  124.     cv2.line(shapes_image, (0, height), (width, 0), 255, 5)
  125.     return shapes_image
  126.  
  127. # Initialize OpenCL
  128. context, queue = init_opencl()
  129.  
  130. # Create and save synthetic images
  131. gradient_image = create_gradient_image(512, 512)
  132. cv2.imwrite('gradient_image.jpg', gradient_image)
  133.  
  134. checkerboard_image = create_checkerboard_image(512, 512, 8)
  135. cv2.imwrite('checkerboard_image.jpg', checkerboard_image)
  136.  
  137. noise_image = create_noise_image(512, 512)
  138. cv2.imwrite('noise_image.jpg', noise_image)
  139.  
  140. shapes_image = create_shapes_image(512, 512)
  141. cv2.imwrite('shapes_image.jpg', shapes_image)
  142.  
  143. # Grayscale conversion (using gradient image as an example)
  144. gray_image = run_kernel(context, queue, grayscale_kernel, cv2.cvtColor(gradient_image, cv2.COLOR_GRAY2BGR), np.empty((512, 512), dtype=np.uint8))
  145. cv2.imwrite('gray_image.jpg', gray_image)
  146.  
  147. # Box blur (using gradient image as an example)
  148. blur_image = run_kernel(context, queue, box_blur_kernel, gray_image, np.empty((512, 512), dtype=np.uint8))
  149. cv2.imwrite('blur_image.jpg', blur_image)
  150.  
  151. # Sobel edge detection (using gradient image as an example)
  152. edge_image = run_kernel(context, queue, sobel_kernel, gray_image, np.empty((512, 512), dtype=np.uint8))
  153. cv2.imwrite('edge_image.jpg', edge_image)
  154.  
  155. # Display results
  156. cv2.imshow('Original', gradient_image)
  157. cv2.imshow('Grayscale', gray_image)
  158. cv2.imshow('Box Blur', blur_image)
  159. cv2.imshow('Sobel Edge Detection', edge_image)
  160. cv2.waitKey(0)
  161. cv2.destroyAllWindows()
  162.  
  163. # Performance testing (using gradient image as an example)
  164. start_time = time.time()
  165. for _ in range(100):
  166.     blur_image = run_kernel(context, queue, box_blur_kernel, gray_image, np.empty((512, 512), dtype=np.uint8))
  167. end_time = time.time()
  168. print(f"Box blur average execution time: {(end_time - start_time) / 100:.4f} seconds")
  169.  
  170. start_time = time.time()
  171. for _ in range(100):
  172.     edge_image = run_kernel(context, queue, sobel_kernel, gray_image, np.empty((512, 512), dtype=np.uint8))
  173. end_time = time.time()
  174. print(f"Sobel edge detection average execution time: {(end_time - start_time) / 100:.4f} seconds")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement