图像处理(三)彩图的中值滤波与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)是处理后该点的亮度值,R(x,y),B(x,y),G(x,y)是该点的RGB值
(这里说明一下,在HSV模型中亮度V选取的值是RGB的最大值);
根据得的亮度值来滤波,这时得倒的图像是彩色图像的灰度图。
通过

cucun[0] = (temp[offset - ncols - 1].x + temp[offset - ncols - 1].y + temp[offset - ncols - 1].z) / 3;

来计算像素的亮度值;

在c中是直接用两个循环遍历图像来选取该位置像素的亮度值从而决定该点的色彩的值;
在CUDA C中直接申明多线程来处理图像
完整代码:


#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>

using namespace cv;
using namespace std;

__global__ void colorkernel(uchar3 *temp, uchar3 *dirtemp, int ncols, int nrows)
{
    int x = threadIdx.x + blockIdx.x*blockDim.x;
    int y = threadIdx.y + blockIdx.y*blockDim.y;
    int offset = x + y*ncols;
    uchar cucun[9];
    uchar3* cucuny[9];
    uchar3*  t;
    uchar zs;
    cucun[0] = (temp[offset - ncols - 1].x + temp[offset - ncols - 1].y + temp[offset - ncols - 1].z) / 3;
    cucun[1] = (temp[offset - ncols].x + temp[offset - ncols].y + temp[offset - ncols].z) / 3;
    cucun[2] = (temp[offset - ncols + 1].x + temp[offset - ncols + 1].y + temp[offset - ncols + 1].z) / 3;
    cucun[3] = (temp[offset - 1].x + temp[offset - 1].y + temp[offset - 1].z) / 3;
    cucun[4] = (temp[offset].x + temp[offset].y + temp[offset].z) / 3;
    cucun[5] = (temp[offset + 1].x + temp[offset + 1].y + temp[offset + 1].z) / 3;
    cucun[6] = (temp[offset + ncols - 1].x + temp[offset + ncols - 1].y + temp[offset + ncols - 1].z) / 3;
    cucun[7] = (temp[offset + ncols].x + temp[offset + ncols].y + temp[offset + ncols].z) / 3;
    cucun[8] = (temp[offset + ncols + 1].x + temp[offset + ncols + 1].y + temp[offset + ncols + 1].z) / 3;
    cucuny[0] = &temp[offset - ncols - 1];
    cucuny[1] = &temp[offset - ncols];
    cucuny[2] = &temp[offset - ncols + 1];
    cucuny[3] = &temp[offset - 1];
    cucuny[4] = &temp[offset];
    cucuny[5] = &temp[offset + 1];
    cucuny[6] = &temp[offset + ncols - 1];
    cucuny[7] = &temp[offset + ncols];
    cucuny[8] = &temp[offset + ncols + 1];
    if (x > 1 && x < ncols&&y>1 && y < nrows)
    {
        for (int i = 8; i >= 0; i--)
        {
            for (int j = 0; j < i; j++)
            {
                if (cucun[j]>cucun[i])
                {
                    zs = cucun[j];
                    cucun[j] = cucun[i];
                    cucun[i] = zs;
                    t = cucuny[j];
                    cucuny[j] = cucuny[i];
                    cucuny[i] = t;

                }
            }
        }

    }
    dirtemp[offset] = *cucuny[8];

}

void colblur(uchar3 *temp, uchar3 *dirtemp, int ncols, int nrows)
{
    dim3 threads(16, 16);
    dim3 blocks((nrows + threads.x - 1) / threads.x, (nrows + threads.y - 1) / threads.y);

    colorkernel << <blocks, threads >> >(temp, dirtemp, ncols, nrows);
}

void main()
{
    uchar3 *temp, *dirtmep;

    Mat src = imread("1.jpg");
    Mat dir(src.rows, src.cols, CV_8UC3);
    int size = src.rows*src.cols*sizeof(uchar3);
    cudaMalloc((void **)&temp, size);
    cudaMalloc((void**)&dirtmep, size);
    cudaMemcpy(temp, src.data, size, cudaMemcpyHostToDevice);
    colblur(temp, temp, src.cols, src.cols);
    cudaMemcpy(dir.data, temp, size, cudaMemcpyDeviceToHost);
    imshow("12.jpg", dir);
    waitKey();
    cudaFree(temp);
    cudaFree(dirtmep);

}

这仅仅是按公式进行实现,效率较低。

时间: 2024-11-03 22:19:42

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

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

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

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 name

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

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

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

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

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

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

中值滤波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

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

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

c语言-C中 将指针加三,但是打印出来的值,表示地址加三,而且指向值不变

问题描述 C中 将指针加三,但是打印出来的值,表示地址加三,而且指向值不变 ```#include char * point(char *p) { printf("P: %d", &p); p += 3; printf("p :%d", &p); return p; } int main() { char b[4] = { 'a', 'b', 'c', 'd' }; char *p = b; char *q; q = point(p); printf

JScript中值类型的封箱与拆箱

js|jscript JScript中对象的expando属性是对Object,Array等引用类型增加成员的一种重要手段,但这种手段在对值类型时就不行了,比如var str = "string1";str.method1 = function(){//do something}; str.method1();//这里将出错,错误信息(我忘记了)是说str不存在该方法 这样的语句就会运行不了,而在C#编程中值类型存在装箱与拆箱操作来将其转换为引用类型,对此,JScript中也存在值类型