高斯滤波和双边滤波

高斯滤波和双边滤波,第1张

原理:http://www.kaotop.com/file/tupian/20220430/写入gauss核进行滤波后的新图像 fp = fopen(gauss_2.bmp", "wb"); if (fp == NULL) { printf("写入失败\n"); exit(1); } fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp); fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp); for (int i = 0; i < bmpInfoHeader.biHeight; i++) { for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++) { fwrite(&grayValue[i][j], sizeof(tagRGB), 1, fp); } } fclose(fp); }

 探究了下sigma_r与双边滤波结果的关系,这里取sigma=6,sigma_r分别取10,20,100

结果如图:

 双边滤波的代码如下:

void bilateral_2_10(const char* filename)
{
    BITMAPFILEHEADER bmpFileHeader;
    BITMAPINFOHEADER bmpInfoHeader;
    FILE* fp;
    if ((fp = fopen(filename, "rb")) == NULL)
    {
        printf("打开失败\n");
        exit(1);
    }
    //读取图像信息
    fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
    fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
    RGBDATA** grayValue;
    grayValue = new RGBDATA * [bmpInfoHeader.biHeight]; //声明一个指针数组
    for (int i = 0; i < bmpInfoHeader.biHeight; i++)
    {
        grayValue[i] = new RGBDATA[(bmpInfoHeader.biWidth * 3 + 3) / 4 * 4];
    }//每个数组元素也是一个指针数组
    

    for (int i = 0; i < bmpInfoHeader.biHeight; i++)
    {
        for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
        {
            fread(&grayValue[i][j], sizeof(tagRGB), 1, fp);//存入数组
        }
    }
    fclose(fp);

    double sigma = 2.0;
    int size = 3;
    double sigma_1 = 10.0;
    double w[3][3] = { 0 };
    for (int i = 0; i < size; i++)        //高斯核
    {
        for (int j = 0; j < size; j++)
        {
            w[i][j] = exp(-(pow(i - size / 2, 2) + pow(j - size / 2, 2)) / (2 * sigma * sigma));
        }
    }
    //零填充
    double** zero_fill_blue;
    double** zero_fill_green;
    double** zero_fill_red;
    zero_fill_blue = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
    zero_fill_green = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
    zero_fill_red = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
    for (int i = 0; i < bmpInfoHeader.biHeight + (size - 1) * 2; i++)
    {
        zero_fill_blue[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
        zero_fill_green[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
        zero_fill_red[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
    }

    for (int i = 0; i < bmpInfoHeader.biHeight + 2 * (size - 1); i++)
    {
        for (int j = 0; j < ((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + 2 * (size - 1)); j++)
        {
            if (i - (size - 1) >= 0 && i < bmpInfoHeader.biHeight + (size - 1) && j - (size - 1)>0 && j < ((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1)))
            {
                zero_fill_blue[i][j] = grayValue[i - (size - 1)][j - (size - 1)].blue;
                zero_fill_green[i][j] = grayValue[i - (size - 1)][j - (size - 1)].green;
                zero_fill_red[i][j] = grayValue[i - (size - 1)][j - (size - 1)].red;
            }
            else
            {
                zero_fill_blue[i][j] = 0;
                zero_fill_green[i][j] = 0;
                zero_fill_red[i][j] = 0;
            }
        }
    }
    double** fill_blue;                              //double传BYTE会丢失数据,所以建double来存数据
    double** fill_green;
    double** fill_red;
    fill_blue = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
    fill_green = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
    fill_red = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
    for (int i = 0; i < bmpInfoHeader.biHeight + (size - 1) * 2; i++)
    {
        fill_blue[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
        fill_green[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
        fill_red[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
    }
    for (int i = 0; i < bmpInfoHeader.biHeight; i++)
    {
        for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
        {
            fill_blue[i][j] = 0;
            fill_green[i][j] = 0;
            fill_red[i][j] = 0;
        }
    }
    double sum_blue = 0;
    double sum_green = 0;
    double sum_red = 0;
    for (int i = size/2; i < bmpInfoHeader.biHeight +size / 2; i++)
    {
        for (int j = size/2; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4+size/2; j++)
        {
            for (int a = 0; a < size; a++)
            {
                for (int b = 0; b < size; b++)
                {
                    fill_blue[i - size / 2][j - size / 2] += zero_fill_blue[i + a - size / 2][j + b - size / 2] * w[a][b] * exp(-pow(zero_fill_blue[i + a - size / 2][j + b - size / 2] - zero_fill_blue[i][j], 2) / (2 * sigma_1 * sigma_1));
                    sum_blue += w[a][b] * exp(-pow(zero_fill_blue[i + a - size / 2][j + b - size / 2] - zero_fill_blue[i][j], 2) / (2 * sigma_1 * sigma_1));
                    fill_green[i - size / 2][j - size / 2] += zero_fill_green[i + a - size / 2][j + b - size / 2] * w[a][b] * exp(-pow(zero_fill_green[i + a - size / 2][j + b - size / 2] - zero_fill_green[i][j], 2) / (2 * sigma_1 * sigma_1));
                    sum_green += w[a][b] * exp(-pow(zero_fill_green[i + a - size / 2][j + b - size / 2] - zero_fill_green[i][j], 2) / (2 * sigma_1 * sigma_1));
                    fill_red[i - size / 2][j - size / 2] += zero_fill_red[i + a - size / 2][j + b - size / 2] * w[a][b] * exp(-pow(zero_fill_red[i + a - size / 2][j + b - size / 2] - zero_fill_red[i][j], 2) / (2 * sigma_1 * sigma_1));
                    sum_red += w[a][b] * exp(-pow(zero_fill_red[i + a - size / 2][j + b - size / 2] - zero_fill_red[i][j], 2) / (2 * sigma_1 * sigma_1));
                }
            }
            fill_blue[i - size / 2][j - size / 2] = fill_blue[i - size / 2][j - size / 2] / sum_blue ;
            fill_green[i - size / 2][j - size / 2] = fill_green[i - size / 2][j - size / 2] / sum_green ;
            fill_red[i - size / 2][j - size / 2] = fill_red[i - size / 2][j - size / 2] / sum_red ;
            sum_blue = 0;
            sum_green = 0;
            sum_red = 0;
        }
    }
    

    for (int i = 0; i < bmpInfoHeader.biHeight; i++)
    {
        for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
        {
            grayValue[i][j].blue = fill_blue[i][j];
            grayValue[i][j].green = fill_green[i][j];
            grayValue[i][j].red = fill_red[i][j];
        }
    }



    //写入滤波后的新图像
    fp = fopen("bilateral _2.bmp", "wb");
    if (fp == NULL)
    {
        printf("写入失败\n");
        exit(1);
    }
    fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
    for (int i = 0; i < bmpInfoHeader.biHeight; i++)
    {
        for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
        {
            fwrite(&grayValue[i][j], sizeof(tagRGB), 1, fp);
        }
    }
    fclose(fp);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/790522.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存