-
Notifications
You must be signed in to change notification settings - Fork 0
/
blur_image.cu
70 lines (57 loc) · 2.35 KB
/
blur_image.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <cuda_runtime.h>
#include <opencv2/opencv.hpp>
const int BLUR_SIZE = 1;
__global__ void blur_image_kernel(unsigned char* input, unsigned char* output, int width, int height) {
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if (row < height && col < width) {
int count = 0;
int sum = 0;
for (int i = -BLUR_SIZE; i <= BLUR_SIZE; ++i) {
for (int j = -BLUR_SIZE; j <= BLUR_SIZE; ++j) {
int curRow = row + i;
int curCol = col + j;
if (curRow >= 0 && curRow < height && curCol >= 0 && curCol < width) {
sum += input[curRow * width + curCol];
count++;
}
}
}
output[row * width + col] = sum / count;
}
}
void blur_image_gpu(unsigned char* input, unsigned char* output, int width, int height) {
unsigned char* d_input, *d_output;
cudaMalloc(&d_input, width * height * sizeof(unsigned char));
cudaMalloc(&d_output, width * height * sizeof(unsigned char));
cudaMemcpy(d_input, input, width * height * sizeof(unsigned char), cudaMemcpyHostToDevice);
dim3 block(32, 32);
dim3 grid((width + block.x - 1) / block.x, (height + block.y - 1) / block.y);
blur_image_kernel<<<grid, block>>>(d_input, d_output, width, height);
cudaMemcpy(output, d_output, width * height * sizeof(unsigned char), cudaMemcpyDeviceToHost);
cudaFree(d_input);
cudaFree(d_output);
}
int main() {
// Generate a random black and white image with opencv and save it to disk
int width = 400;
int height = 400;
cv::Mat toBlurImage(height, width, CV_8UC1);
cv::randu(toBlurImage, cv::Scalar(0), cv::Scalar(255));
if (cv::imwrite("to_blur.jpg", toBlurImage)) {
std::cout << "Image saved!" << std::endl;
} else {
std::cerr << "Error: Could not save image" << std::endl;
}
// Allocate image
cv::Mat blurredImage(height, width, CV_8UC1);
// Blur the image using CUDA
blur_image_gpu(toBlurImage.ptr(0), blurredImage.ptr(0), width, height);
// Save the blurred image to disk
if (cv::imwrite("blurred_image.jpg", blurredImage)) {
std::cout << "Blurred image saved!" << std::endl;
} else {
std::cerr << "Error: Could not save image" << std::endl;
}
}