cuda c-CUDA-GPU加速-中值滤波-黑屏+显卡程序崩溃

问题描述

CUDA-GPU加速-中值滤波-黑屏+显卡程序崩溃

新手刚接触CUDA C,这段中值滤波的代码一直跑不通,如果读取一张小图片(2790,2560)没有问题,如果读取一张大图片(5580,5120),就会导致黑屏+没有结果。
我的显卡是NVIDIA Geforce 820M

#include <iostream>
#include "ImMedFilter.h"

#define DIM_GRID  128
#define DIM_BLOCK 16
using namespace std;

__device__ void mid(unsigned char* data, int size, int midIndex)
{
    unsigned char temp = 0;
    for (int i = 0; i <= midIndex; i++)
    {
        for (int j = i+1; j < size; j++)
        {
            if (data[j] > data[i])
            {
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
            }
        }
    }
}

__global__ void global_ZhongSmooth(unsigned char *dev_src, unsigned char *dev_dst, int width , int height, int bytesPerLine, int size, int markSize)
{
    int x = threadIdx.x + blockIdx.x*blockDim.x;
    int y = threadIdx.y + blockIdx.y*blockDim.y;

    int step_x = blockDim.x * gridDim.x;
    int step_y = blockDim.y * gridDim.y;

    for (int t_y = y; t_y < height - markSize; t_y = t_y + step_y)
    {
        if (t_y < markSize || t_y > height-markSize-1)
        {
            continue;
        }
        for (int t_x = x; t_x < width - markSize; t_x = t_x + step_x)
        {
            if (t_x < markSize || t_x > width-markSize-1)
            {
                continue;
            }
            unsigned int index = t_x + t_y*width;
            if( index < size )
            {
                unsigned char len = (markSize*2+1)*(markSize*2+1);
                unsigned char midIndex = len/2;
                // 创建保存中值区域的数组
                // size = (marksize * 2 + 1) ^ 2;
                // 滤波大小:3、5、7、9、...、29、31
                unsigned char*a = NULL;
                switch (markSize)
               {
                case 1:
                    unsigned char c[9];
                    a = c;
                    break;
                case 2:
                    unsigned char d[25];
                    a = d;
                    break;
                case 3:
                    unsigned char e[49];
                    a = e;
                    break;
                case 4:
                    unsigned char f[81];
                    a = f;
                    break;
                case 5:
                    unsigned char g[121];
                    a = g;
                    break;
                case 6:
                    unsigned char h[169];
                    a = h;
                    break;
                case 7:
                    unsigned char v[225];
                    a = v;
                    break;
                case 8:
                    unsigned char w[289];
                    a = w;
                    break;
                case 9:
                    unsigned char x[361];
                    a = x;
                    break;
                case 10:
                    unsigned char z[441];
                    a = z;
                    break;
                case 11:
                    unsigned char u[529];
                    a = u;
                    break;
                case 12:
                    unsigned char q[625];
                    a = q;
                    break;
                case 13:
                    unsigned char i[729];
                    a = i;
                    break;
                case 14:
                    unsigned char o[841];
                    a = o;
                    break;
                default:
                    return;
                }
                unsigned char k = 0;
                for (int i = -markSize; i <= markSize; i++)
                {
                    for (int j = -markSize; j <= markSize; j++)
                    {
                        a[k++] = dev_src[t_x+j+(t_y+i)*width];
                    }
                }

                mid(a, len, midIndex);
                dev_dst[index] = a[midIndex];
            }
        }
    }

}

extern "C" void ImMedfilter(const unsigned char *host_src, unsigned char *host_dst, int width, int height, int bytesPerLine, int markSize)
{
    int dataSize = bytesPerLine * height;   

    unsigned char *dev_src = NULL;
    unsigned char *dev_dst = NULL;

    cudaMalloc((void**) &dev_src, dataSize);
    cudaMalloc((void**) &dev_dst, dataSize);

    cudaMemset(dev_dst, 0, dataSize);
    cudaMemcpy(dev_src, host_src, dataSize, cudaMemcpyHostToDevice);

    dim3 blocks(DIM_BLOCK, DIM_BLOCK);
    dim3 grids(DIM_GRID, DIM_GRID);

    global_ZhongSmooth<<<grids, blocks>>>(dev_src, dev_dst, width, height, bytesPerLine, dataSize, markSize);

    cudaMemcpy(host_dst, dev_dst, dataSize, cudaMemcpyDeviceToHost);

    cudaFree(dev_src);
    cudaFree(dev_dst);
}

解决方案

每次程序黑屏都是ImMedfilter函数运行了:
cudaMemcpy(host_dst, dev_dst, dataSize, cudaMemcpyDeviceToHost);
这一段代码后。

解决方案二:

快1年了,基本没碰CUDA了,最近项目需要用GPU加速,又遇到这种类似情况,没人回答就自己不断补充吧。
cudaMemcpy函数不会等GPU运算结束再执行,所以GPU在操作dev_dst,CPU也在操作,两者冲突,直接死机。
我的暂时解决方法是加一句cudaThreadSynchronize(),等待GPU执行完毕CPU再继续操作。
这种方法会有问题,如果算法计算时间过长的话,你的屏幕就会卡死,要等到GPU计算完屏幕才能正常工作,这就很蛋疼。
应该是方法还没有找对,看后面继续改进吧。。。。。。。

时间: 2024-12-21 18:07:42

cuda c-CUDA-GPU加速-中值滤波-黑屏+显卡程序崩溃的相关文章

图像处理(三)彩图的中值滤波与cuda形式

灰度图像为一通道图像,如8位的灰度图的每一个像素点的数据由一个uchar类型来储存,uchar的值代表图像的亮度,灰度图像的中值滤波是根据像素值的3×3的领域内,像素值排序后的中值像素代表该点的像素值值: 而彩色图像一般为RGB图片,像素点的颜色由红绿蓝三通道决定,数据由一个uchar3型存储,如同灰度图的中值滤波一样,彩色图像的中值滤波也是根据图像的亮度来选取相应的像素点的值. RGB图像的亮度计算: F(x,y)=(R(x,y)+G(x,y)+B(x,y))/3 F(X,Y)是处理后该点的亮

轨迹系列——一种基于中值滤波的轨迹纠偏方法和几点思考

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在无路网的情况下,如何进行轨迹纠偏也是一个很多人在研究的内容,各种方案均有很多,有基于不同滤波算法的,也有基于机器学习的,等等.这里,我探讨一种实现相对简单的基于中值滤波来进行轨迹纠偏的方法. 2.中值滤波简介 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代

图片-初学小女子求问一个关于矩阵,中值滤波题目

问题描述 初学小女子求问一个关于矩阵,中值滤波题目 目前用的是VS2010,所以希望是C语言~多谢喇 望各方大神快快冒泡,解小女子一惑o(^▽^)o 解决方案 不是告诉你算法了么?就是用某个点周围8个点按照第二个矩阵的泉重求平均数,作为滤波后的值. 解决方案二: 打个比方,第二排第二个元素158,滤波以后等于多少呢? 我们看它和它四周的9个元素,是不是 160 163 167 159 158 155 153 155 157 和Mask每一项相乘相加再除以16 等于 (160*1+163*2+16

vc++-VC++MFC工程做自适应中值滤波

问题描述 VC++MFC工程做自适应中值滤波 求完整的自适应中值滤波程序,要求有源程序,可执行程序.之前在网上找的都不太好模仿,希望直接在view里做,不要各种引申函数,就在一个大括号里做完的.拜托拜托!!急啊! 解决方案 恕我直言题主,您的第二张图片中的代码完全看不清楚 解决方案二: CXXXXXDoc* pDoc = GetDocument(); int iH,iW; LPSTR lpDIB; LPSTR lpDIBBits; lpDIB = (LPSTR) ::GlobalLock((HG

中值滤波-利用中值空间滤波去除波形噪声

问题描述 利用中值空间滤波去除波形噪声 我们做的大作业,要求改进算子,去除波形噪声,我不知道从哪改,也不知道波形噪声是什么吗,百度不到,算子是在源码改么 有人有代码么

中值滤波c = box1.GetPixel(i + k1, j + k2),参数必须为正且小于高度!求大神指点!

问题描述 privatevoidbutton3_Click(objectsender,EventArgse){Colorc=newColor();Colorcc=newColor();Bitmapbox1=newBitmap(pictureBox1.Image);Bitmapbox2=newBitmap(200,200,System.Drawing.Imaging.PixelFormat.Format24bppRgb);intrr,r1,g1,b1,i1,j1,k1,k2,dm,m;int[]d

Win10系统安装过程中卡死或黑屏导致无法启动

开机后,看到Windows 10 Logo,下面有个圆圈在转的时候,数5 秒.然后直接按下电源键关机.对于台式机,如果机箱上有"重启按键",也可以直接按重启键.  如此重复2-3次,当再次开机的时候,就会进入如下图的界面: 鼠标点击"查看高级修复选项",即可进入Win10的RE 模式.Win10的RE模式,可以让你"重置此电脑"或者"回到上一个系统". 1.重置此电脑 作用:把Windows 10系统全自动的重新安装一次,可以

【OpenCV】5种图像滤波辨析:方框、均值、高斯、中值、双边

图像滤波 什么是图像滤波 图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性.(摘自网络) 图像滤波的目的 1,消除图像中混入的噪声 2,为图像识别抽取出图像特征 图像滤波的要求 1,不能损坏图像轮廓及边缘 2,图像视觉效果应当更好 滤波器的定义 滤波器,顾名思义,是对波进行过滤的器件.(摘自网络) 以上的定义是针对物理器件的,但对于图像滤波而言显然也是适用的. 大家都用过放大镜,这里就

计算机视觉标准OpenCV支持CUDA GPU加速

GTC++ 2010 GPU技术大会上,NVIDIA宣布CUDA GPU硬件加速技术已经支持开放式计算机视觉标准OpenCV,可在机器人.汽车.医疗.消费.安全.制造.科研等众多领域用来开发先进应用程序.OpenCV是由Intel.Willow Garage主导开发的开源计算机视觉库,轻量而且高效,包括一系列C函数和少量C++类,是图像处理和计算机视觉方面的通用算法,支持Windows. Linux.Mac OS三大平台,迄今已有数千名http://www.aliyun.com/zixun/ag