婧Jing2005 2024-06-12 21:52 采纳率: 40%
浏览 1
已结题

高斯滤波对图像处理出现这些问题怎么改?

#高斯滤波对图像处理有一些错误不知道怎么解决!
问了AI说我有以下问题:

  1. 高斯核计算:虽然代码中尝试计算高斯核的权重,但计算方式不正确。高斯核的计算应该基于二维高斯函数,并且需要对每个像素点应用正确的权重。当前的实现没有正确计算高斯核的权重分布。
  2. 图像处理逻辑:在应用高斯核进行滤波时,代码逻辑存在错误。特别是对像素值的处理和归一化因子的计算需要修正。
  3. 边界处理:代码没有正确处理图像边界的情况,可能会导致数组越界访问。
  4. 未实现归一化:虽然代码中有归一化因子的计算,但实际上并没有进行归一化处理,这会影响滤波效果。
    代码如下:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>

typedef  unsigned char  U8;
typedef  unsigned short U16;
typedef  unsigned int   U32;

#pragma  pack(1)
typedef struct
{
    //bmp header
    U16 bfType;         // B  M
    U32 bfSize;         //文件大小
    U16 bfReserved1;
    U16 bfReserved2;
    U32 bfOffBits;      //文件头偏移量

    //DIB header
    U32 biSize;         //DIB头大小
    U32 biWidth;        //文件宽度
    U32 biHeight;       //文件高度
    U16 biPlanes;
    U16 biBitCount;     //每个相素点的位数
    U32 biCompression;
    U32 biSizeImage;    //图文件大小
    U32 biXPelsPerMeter;
    U32 biYPelsPerMeter;
    U32 biClrUsed;
    U32 biClrImportant;
} BMP_HEADER;
#pragma  pack()

int main(int argc, char **argv)
{
    int fd;
    int i,j,k;
    int width,height,bpp;
    int stride;
    char fName0[256],fName[256],sTmp[100];
    BMP_HEADER  header;
    U8 I[900*600],B[900*600];
    //I是每个点的像素值,B是处理后的平均值
    U8 clrPal[256*4];//存储颜色信息
    // parameters for filtering
    int sigma = 1;
    double pi = acos(-1);

    if(argc==1)
    {
        printf("File name of the image to be processed: \n");
        scanf("%s", fName0);
        //strcpy(fName0,"mountain.bmp");
    }
    else if(argc==2)
        strcpy(fName0,argv[1]);
    else
        perror("Please provide only the original image name or give none.");
    strcpy(fName,"");
    strncat(fName,fName0,strlen(fName0)-4);
    sprintf(sTmp,"_filterMean.bmp",sigma);
    strcat(fName,sTmp);

    fd = open(fName0, O_RDONLY | O_BINARY);
    if(-1 == fd)
        perror("open bmp file fail");
    read(fd, &header, sizeof(BMP_HEADER));
    lseek(fd, header.bfOffBits, SEEK_SET);
    read(fd, I, header.biSizeImage);
    close(fd);

    width = header.biWidth;
    height = header.biHeight;
    stride = header.biSizeImage/height;
    bpp = header.biBitCount;
    if(bpp!=8)
        return 0;

    fd = open(fName, O_WRONLY | O_CREAT | O_BINARY);
    if(fd < 0 )
        perror("open x.bmp fail");
    write(fd, &header, sizeof(BMP_HEADER));

    for(i=0; i<256; i++)
    {
        clrPal[4*i] = clrPal[4*i+1] = clrPal[4*i+2] = i;
        clrPal[4*i+3] = 0;
    }
    write(fd, clrPal, 256*4);

    // parameters for mean filtering
    int n = 4*sigma + 1;
    double W[21][21],w;
    //weights for Guass filtering
    double c,dis;
    c = 1/(sigma*sqrt(2*pi));
    for(i=-2*sigma; i<=2*sigma; i++)
        for(j=-2*sigma; j<=2*sigma; j++)
        {
            //// 窗口中心的坐标p=(0,0) 
            //// 窗口内其它像素的坐标q=(i,j)
            dis = sqrt(i*i+j*j);
            if(dis>sigma*2)
                W[i+2*sigma][j+2*sigma] = 0;
            else
                W[i+2*sigma][j+2*sigma] = c * exp(-dis*dis/2/sigma/sigma);
        }
     //Guass filtering   
    int cx=0,cy=0;
    double sum = 0.0;
    double normalization = 0.0;
    // 对每个像素应用高斯核
    for (int x = 0; x < height; ++x)
     {
        for (int y = 0; y < width; ++y) 
        {
            double pixel_value = 0.0;
            for (int i =-2*sigma; i <=2*sigma; ++i) 
            {
                for (int j = -2*sigma; j <= 2*sigma; ++j) 
                {
                     cx = x + i;
                     cy = y + j;
                    if (cx >= 0 && cy >= 0 && cx < width && cy < height) 
                    {
                        pixel_value += W[i+2*sigma][j+2*sigma] * I[cx * width + cy];
                        normalization += W[i+2*sigma][j+2*sigma];
                    }
                }
            }
             if (normalization > 0) {
                B[cx * width + cy] = pixel_value / normalization;
            } else {
                B[cx * width + cy] = I[cx * width + cy]; // 如果归一化因子为0,则保持原像素值不变
            }
            normalization = 0.0; // 重置归一化因子
        }
    }
    //细节增强
/*
    double val;
    int x0,y0;
    U8 D[900*600];
    int a=3;//表示增强强度
        for(y0=0; y0<width; y0++)
        {
            val=(I[x0*stride+y0]*a)-(B[x0*stride+y0]*(a-1));
            if(val<0) val = 0;
            else if(val>255) val = 255;
            D[x0*stride+y0] = (U8)(val+0.5);
        }
*/
    write(fd, B, header.biSizeImage);
    close(fd);
}



最后面还有细节增强的我注释掉了,也不确定是不是对的?

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-12 21:52
    关注

    引自免费微信小程序:皆我百晓生

    针对你提供的代码以及所描述的问题,我们可以逐一进行分析并提供修改方案。首先,代码中确实存在几个关键问题,包括高斯核的不正确计算、图像处理逻辑错误、边界处理不当以及缺少归一化处理。接下来,我将为你提供一个经过修正的版本,以解决这些问题。

    高斯核计算修正

    高斯核应该根据二维高斯函数计算,同时确保所有权重加起来等于1(即归一化)。这里的关键是正确地计算每个权重值并确保权重总和为1。

    图像处理逻辑修正

    在应用高斯核时,需要确保对每个像素应用正确的权重,并且在计算新像素值时考虑归一化因子。

    边界处理修正

    为了避免数组越界,当计算窗口边缘的像素时,应适当调整窗口的大小,而不是使用完整的窗口。

    归一化处理

    归一化是必要的,以确保滤波后像素值的正确范围。

    考虑到上述修正,以下是修改后的代码片段,主要关注高斯滤波部分:

    // Guass filtering
    double normalization = 0.0;
    // 对每个像素应用高斯核
    for (int x = 0; x < height; ++x)
    {
        for (int y = 0; y < width; ++y) 
        {
            double pixel_value = 0.0;
            for (int i =-2*sigma; i <=2*sigma; ++i) 
            {
                for (int j = -2*sigma; j <= 2*sigma; ++j) 
                {
                    int cx = x + i;
                    int cy = y + j;
                    // 检查边界,防止越界
                    if (cx >= 0 && cy >= 0 && cx < height && cy < width) 
                    {
                        pixel_value += W[i+2*sigma][j+2*sigma] * I[cx * stride + cy];
                        normalization += W[i+2*sigma][j+2*sigma];
                    }
                }
            }
            if (normalization > 0) {
                B[x * stride + y] = pixel_value / normalization;
            } else {
                B[x * stride + y] = I[x * stride + y]; // 如果归一化因子为0,则保持原像素值不变
            }
            normalization = 0.0; // 重置归一化因子
        }
    }
    

    关于高斯核计算的修正

    在你的原始代码中,高斯核的计算似乎没有考虑归一化,下面是一个修正后的高斯核计算方法:

    // weights for Guass filtering
    double sumWeights = 0.0;
    double c = 1.0 / (2 * M_PI * sigma * sigma);
    for(i=-2*sigma; i<=2*sigma; i++)
        for(j=-2*sigma; j<=2*sigma; j++)
        {
            double dis = sqrt(i*i+j*j);
            W[i+2*sigma][j+2*sigma] = c * exp(-dis*dis / (2 * sigma * sigma));
            sumWeights += W[i+2*sigma][j+2*sigma];
        }
    
    // 归一化权重
    for(i=0; i<21; i++)
        for(j=0; j<21; j++)
            W[i][j] /= sumWeights;
    

    这些修改应当能解决你提到的所有问题,包括高斯核的正确计算、边界处理以及归一化处理。请仔细检查并测试这些修改是否符合你的需求。如果有任何疑问或遇到其他问题,请随时询问。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月20日
  • 已采纳回答 6月12日
  • 创建了问题 6月12日

悬赏问题

  • ¥15 python怎么在已有视频文件后添加新帧
  • ¥20 虚幻UE引擎如何让多个同一个蓝图的NPC执行一样的动画,
  • ¥15 fluent里模拟降膜反应的UDF编写
  • ¥15 MYSQL 多表拼接link
  • ¥15 关于某款2.13寸墨水屏的问题
  • ¥15 obsidian的中文层级自动编号
  • ¥15 同一个网口一个电脑连接有网,另一个电脑连接没网
  • ¥15 神经网络模型一直不能上GPU
  • ¥15 pyqt怎么把滑块和输入框相互绑定,求解决!
  • ¥20 wpf datagrid单元闪烁效果失灵