使用 CUDA 在 C 语言中进行 Sobel 边缘检测 [已关闭]

sobel edge detection in c using cuda [closed]

提问人:Jude Al Haroun 提问时间:11/16/2023 最后编辑:BodoJude Al Haroun 更新时间:11/16/2023 访问量:81

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将帮助其他人回答这个问题。

6天前关闭。

有谁知道这段代码有什么问题?输出与预期不符。输出中大约有 3 个对角线,并且没有检测到边缘。

下面是输出图像:here is the output image

第一张图片(右边是输入消息):the first image (the one on the right is the input message)

#include <time.h>
#include <iostream>
#include <math.h>
#include <stdlib.h>

#define width 385
#define height 513

__global__ void sobel_gpu(double* orig, double* cpu) {
    int x = threadIdx.x + blockIdx.x * blockDim.x;
    int y = threadIdx.y + blockIdx.y * blockDim.y;
    float dx, dy;
    int sum;
    if( x > 0 && y > 0 && x < width-1 && y < height-1) {
        dx = (-1* orig[(y-1)*width + (x-1)]) + (-2*orig[y*width+(x-1)]) + (-1*orig[(y+1)*width+(x-1)]) +
             (    orig[(y-1)*width + (x+1)]) + ( 2*orig[y*width+(x+1)]) + (   orig[(y+1)*width+(x+1)]);
        dy = (    orig[(y-1)*width + (x-1)]) + ( 2*orig[(y-1)*width+x]) + (   orig[(y-1)*width+(x+1)]) +
             (-1* orig[(y+1)*width + (x-1)]) + (-2*orig[(y+1)*width+x]) + (-1*orig[(y+1)*width+(x+1)]);
        sum = sqrt( (dx*dx) + (dy*dy) );
      cpu[y*width + x] = (sum > 255) ? 255 : sum;
      __syncthreads();
}}
        
int main() {
    /** Allocate memory on the device **/
    double* image;
    double* gradient_magnitude;
    int i, j;
    double cpu_time;
    clock_t begin, end;
   cudaMallocManaged(&gradient_magnitude,height * width * sizeof(double));
   cudaMallocManaged(&image,height * width * sizeof(double));
    FILE *fp, *fp2;
    fp = fopen("input.txt", "r");
    if (fp == NULL) {
        printf("Error: could not open file.\n");
        exit(1);
    }
    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {
            fscanf(fp, "%lf", &image[i * width + j]);
        }
    }
    fclose(fp);
    

   
    /** Set up the grid and block dimensions **/
    dim3 block(32, 32);
    dim3 grid((width + block.x - 1) / block.x, (height + block.y - 1) / block.y);

    begin = clock();
    // Run the Sobel filter on the GPU
    sobel_gpu<<<grid, block>>>(image, gradient_magnitude);


    end = clock();
    cpu_time = (double) (end - begin) / CLOCKS_PER_SEC;
    cudaDeviceSynchronize();
  


    fp2 = fopen("output_cuda.txt", "w");
    if (fp2 == NULL) {
        printf("Unable to open file for writing");
        return 1;
    }
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            fprintf(fp2, "%lf ", gradient_magnitude[i * width + j]);
        }
        fprintf(fp2, "\n");
    }
    fclose(fp2);
    printf("cpu time = %.8f\n", cpu_time);

    /** Free memory on the device **/
    cudaFree(image);
    cudaFree(gradient_magnitude);


    return 0;
}

我已经使用了 openmp 版本和串行版本,两者的输出相同,但我怀疑 CUDA 代码存在问题。

C 图像处理 CUDA 边缘检测 SOBEL

评论

1赞 gulpr 11/16/2023
你为什么要使用大写字母?如果你认为这将有助于更多的关注,那么你就错了。它只会激怒人们
7赞 user3386109 11/16/2023
像这样的对角线通常意味着代码错误地计算了图像步幅。
1赞 chux - Reinstate Monica 11/17/2023
@Jude Al Haroun,这真的是带有 和 的 C 代码吗?#include <iostream>sobel_gpu<<<grid, block>>>(image, gradient_magnitude);
1赞 chux - Reinstate Monica 11/17/2023
@JudeAlHaroun 在哪里定义?threadIdx, dim3
2赞 chux - Reinstate Monica 11/17/2023
看起来源数据是 3 字节的 RGB,并且是奇数宽度,被填充。代码将其读取为 1 字节/像素,未填充。

答: 暂无答案