C-rgb值-计算模糊过滤器rgb值的平均值

C-rgb值-计算模糊过滤器rgb值的平均值,c,loops,average,rgb,blur,C,Loops,Average,Rgb,Blur,前两个没那么难,但第三个让我抓狂。 模糊滤波器必须计算特定像素组的rgb值的平均值,以便替换居中像素的值。 想象一个3x3网格,其中中心的像素必须使用周围八个像素的平均值和中心像素本身的rgb值进行操作 到目前为止,我所做的工作如下: // Blur image void blur(int height, int width, RGBTRIPLE image[height][width]) { int n; int m; int averageRed; int a

前两个没那么难,但第三个让我抓狂。 模糊滤波器必须计算特定像素组的rgb值的平均值,以便替换居中像素的值。 想象一个3x3网格,其中中心的像素必须使用周围八个像素的平均值和中心像素本身的rgb值进行操作

到目前为止,我所做的工作如下:

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    int n;
    int m;
    int averageRed;
    int averageBlue;
    int averageGreen;

    //For each row..
    for (int i = 0; i < height; i++)
    {
        //..and then for each pixel in that row...
        for (int j = 0; j < width; j++)
        {

            //...if i and j equal 0...         
            if (i == 0 && j == 0)
            {
                for (m = i; m <= 1; m++)
                {
                    for (n = j; n <= 1; n++)
                    {
                        averageRed = averageRed + image[m][n].rgbtRed;
                        averageBlue = averageBlue + image[m][n].rgbtBlue;
                        averageGreen = averageGreen + image[m][n].rgbtGreen;

                        printf("%i\n", averageRed);
                        printf("%i\n", averageBlue);
                        printf("%i\n", averageGreen); 
                    }
                }

                image[i][j].rgbtRed = round((float)averageRed / 4);
                image[i][j].rgbtBlue = round((float)averageBlue / 4);
                image[i][j].rgbtGreen = round((float)averageGreen / 4);

                printf("%i\n", image[i][j].rgbtRed);
                printf("%i\n", image[i][j].rgbtBlue);
                printf("%i\n", image[i][j].rgbtGreen);
            }


            //If i equals 0 and j is greater than 0...
            else if (i == 0 && j > 0)
            {
                //..take the line that equals i..
                for (m = i; m <= 1; m++)
                {
                    //..and take from each pixel ot that line...
                    for (n = j - 1; n <= 1; n++)
                    {
                        //..the color values and add them to the average-variables
                        averageRed = averageRed + image[m][n].rgbtRed;
                        averageBlue = averageBlue + image[m][n].rgbtBlue;
                        averageGreen = averageGreen + image[m][n].rgbtGreen;
                    }
                }

                //Set the current pixel values to the averages
                image[i][j].rgbtRed = round((float)averageRed / 6);
                image[i][j].rgbtBlue = round((float)averageBlue / 6);
                image[i][j].rgbtGreen = round((float)averageGreen / 6);

                printf("%i\n", image[i][j].rgbtRed);
                printf("%i\n", image[i][j].rgbtBlue);
                printf("%i\n", image[i][j].rgbtGreen);
            }


            else if (i > 0 && j == 0)
            {
                for (m = i - 1; m <= 1; m++)
                {
                    for (n = j; n <= 1; n++)
                    {
                        averageRed = averageRed + image[m][n].rgbtRed;
                        averageBlue = averageBlue + image[m][n].rgbtBlue;
                        averageGreen = averageGreen + image[m][n].rgbtGreen;
                    }
                }

                image[i][j].rgbtRed = round((float)averageRed / 6);
                image[i][j].rgbtBlue = round((float)averageBlue / 6);
                image[i][j].rgbtGreen = round((float)averageGreen / 6);
            }


            else if (i > 0 && j > 0 )
            {

                // ..take every line from i - 1 to i + 1...
                for (m = i - 1; m <= 1; m++)
                {

                    //...and in each line take every pixel from j - 1 to j + 1...
                    for (n = j - 1; n <= 1; n++)
                    {

                        //...and add the RGB value to average-variables
                        averageRed = averageRed + image[m][n].rgbtRed;
                        averageBlue = averageBlue + image[m][n].rgbtBlue;
                        averageGreen = averageGreen + image[m][n].rgbtGreen;
                    }
                }

                //Set current value to the rounded average
                image[i][j].rgbtRed = ((float)averageRed / 9);
                image[i][j].rgbtBlue = ((float)averageBlue / 9);
                image[i][j].rgbtGreen = ((float)averageGreen / 9);
            }  


        }

    }
    return;

}
非常感谢您的建议


Greetz

注意,
平均值*
变量是未初始化的,所以当你对它们求和时,你有UB。它们需要预设为0,当然是在开始时,但可能在每个主循环之前


此外,除了你的其他问题,其他人已经注意到,你可能需要做饱和数学

这是因为for
rgbt*
(例如
rgbtRed
)是一个字节,因此值可能被错误地剪裁

你正在做:

image[i][j].rgbtRed = round((float)averageRed / 6);
这可以改写为:

averageRed = round((float)averageRed / 6);
image[i][j].rgbtRed = averageRed;
但是,如果(例如)
平均值
为256,则
rgbtRed
将最终为1[因为
图像
的赋值是[有效的]:

image[i][j].rgbtRed = averageRed & 0xFF;
因此,不是存储鲜红色,而是存储接近黑色的颜色。最终值需要是255,即“饱和”最大颜色值

因此,为了解决这个问题[或者仅仅是为了防范它],我们应该:

averageRed = round((float)averageRed / 6);
if (averageRed > 255)
    averageRed = 255;
image[i][j].rgbtRed = averageRed;
编辑:进一步思考后,您只需要在右侧可以超过255的情况下执行此操作,但我[现在]不确定它是否可以。要检查此情况,您可以添加(例如):

您可以将其包装在一个
#ifdef
中,进行测试,如果它没有触发,您可以稍后删除它


更新:


这个问题听起来可能很愚蠢,但这个值怎么可能达到256?即使每个像素都是白色的,也没有一个值能达到256,或者我的错误在哪里?(1白色像素:255 255 255->10白色像素:2550 2550/10-->

是的,根据我上面的“编辑:”可能不是。我最近回答了一个类似的问题,该值可能超过255

但是,运行时错误显示该值确实超过了字节的容量(即
无符号字符

这可能是由于未初始化的总和变量

但是,这也是因为总和/平均值变量在循环开始时没有被重置。你从来没有重置它们,所以它们只是不断地增长

完成每个3x3卷积内核后(即存储每个输出像素后),需要重置它们


而且,我不认为你的
for(n=j;n注意
average*
变量是未初始化的,所以当你对它们求和时,你有UB。它们需要被预设为0,当然是在开始时,但可能在每个主循环之前


此外,除了你的其他问题,其他人已经注意到,你可能需要做饱和数学

这是因为for
rgbt*
(例如
rgbtRed
)是一个字节,因此值可能被错误地剪裁

你正在做:

image[i][j].rgbtRed = round((float)averageRed / 6);
这可以改写为:

averageRed = round((float)averageRed / 6);
image[i][j].rgbtRed = averageRed;
但是,如果(例如)
平均值
为256,则
rgbtRed
将最终为1[因为
图像
的赋值是[有效的]:

image[i][j].rgbtRed = averageRed & 0xFF;
因此,不是存储鲜红色,而是存储接近黑色的颜色。最终值需要是255,即“饱和”最大颜色值

因此,为了解决这个问题[或者仅仅是为了防范它],我们应该:

averageRed = round((float)averageRed / 6);
if (averageRed > 255)
    averageRed = 255;
image[i][j].rgbtRed = averageRed;
编辑:进一步思考后,您只需要在右侧可以超过255的情况下执行此操作,但我[现在]不确定它是否可以。要检查此情况,您可以添加(例如):

您可以将其包装在一个
#ifdef
中,进行测试,如果它没有触发,您可以稍后删除它


更新:


这个问题听起来可能很愚蠢,但这个值怎么可能达到256?即使每个像素都是白色的,也没有一个值能达到256,或者我的错误在哪里?(1白色像素:255 255 255->10白色像素:2550 2550/10-->

是的,根据我上面的“编辑:”可能不是。我最近回答了一个类似的问题,该值可能超过255

但是,运行时错误显示该值确实超过了字节的容量(即
无符号字符

这可能是由于未初始化的总和变量

但是,这也是因为总和/平均值变量在循环开始时没有被重置。你从来没有重置它们,所以它们只是不断地增长

完成每个3x3卷积内核后(即存储每个输出像素后),需要重置它们


而且,我不认为你的
(n=j;n的正确性需要保留原始值

为了提高速度,您只需保留原始值,直到不再需要它们;并且水平总和可以循环使用,以最大限度地减少添加

更具体地说,对于每一行像素,忽略上/下/左/右边缘(需要特别注意)并假装它是单色的(对于RGB,您只需执行全部3次):

  • 对于行中的每个像素,执行
    buffer[next\u buffer\u row][x]=image[y+2][x-1]+image[y+2][x]+image[y+2][x+1]
    以将水平和存储在缓冲区中

  • 对于行中的每个像素,计算模糊值,如
    image[y][x]=(buffer[previous\u buffer\u row][x]+buffer[current\u buffer\u row][x]+buffer[next\u buffer\u row][x])/9

  • 前进到图像中的下一行(
    y++
    ),并旋转缓冲区(
    previous\u buffer\u row++);如果(previous\u buffer\u row>=3)previous\u buffer\u row=0;
    current\u buffer\u row++;如果(current\u buffer\u row>=3)current\u buffer\u row=0;

要处理左/右边缘,您需要“剥离”第一次迭代的“for each pixel in row”循环,然后
| 1 2 1 |
| 2 4 2 |
| 1 2 1 |