【问题标题】:Why are these two filter functions not operating accordingly? cs50为什么这两个过滤器功能没有相应地运行? cs50
【发布时间】:2020-07-01 15:47:30
【问题描述】:

我正在尝试创建一个函数,该函数将获取图像并编辑其属性以产生灰度和蓝色效果。

灰度函数的目的只是通过找到 rbg 的平均值然后分配它来将像素转换为灰度,但是每当运行检查 50 以查看它是否工作时,它似乎正在转换单一和简单的像素图像,但无法处理更复杂的图像。

check50 结果在这里:

> :) grayscale correctly filters single pixel with whole number average
> Log testing with pixel (20, 40, 90) running ./testing 0 0... checking
> for output "50 50 50\n"... :( grayscale correctly filters single pixel
> without whole number average expected "28 28 28\n", not "27 27 27\n"
> Log testing with pixel (27, 28, 28) running ./testing 0 1... checking
> for output "28 28 28\n"...
> 
> Expected Output: 28 28 28 Actual Output: 27 27 27 :) grayscale leaves
> alone pixels that are already gray Log testing with pixel (50, 50, 50)
> running ./testing 0 2... checking for output "50 50 50\n"... :)
> grayscale correctly filters simple 3x3 image Log testing with sample
> 3x3 image first row: (255, 0, 0), (255, 0, 0), (255, 0, 0) second row:
> (0, 255, 0), (0, 255, 0), (0, 0, 255) third row: (0, 0, 255), (0, 0,
> 255), (0, 0, 255) running ./testing 0 3... checking for output "85 85
> 85\n85 85 85\n85 85 85\n85 85 85\n85 85 85\n85 85 85\n85 85 85\n85 85
> 85\n85 85 85\n"... :( grayscale correctly filters more complex 3x3
> image expected "20 20 20\n50 5...", not "20 20 20\n50 5..." Log
> testing with sample 3x3 image first row: (10, 20, 30), (40, 50, 60),
> (70, 80, 90) second row: (110, 130, 140), (120, 140, 150), (130, 150,
> 160) third row: (200, 210, 220), (220, 230, 240), (240, 250, 255)
> running ./testing 0 4... checking for output "20 20 20\n50 50 50\n80
> 80 80\n127 127 127\n137 137 137\n147 147 147\n210 210 210\n230 230
> 230\n248 248 248\n"...
> 
> Expected Output: 20 20 20 50 50 50 80 80 80 127 127 127 137 137 137
> 147 147 147 210 210 210 230 230 230 248 248 248 Actual Output: 20 20
> 20 50 50 50 80 80 80 126 126 126 136 136 136 146 146 146 210 210 210
> 230 230 230 248 248 248 :( grayscale correctly filters 4x4 image
> expected "20 20 20\n50 5...", not "20 20 20\n50 5..." Log testing with
> sample 4x4 image first row: (10, 20, 30), (40, 50, 60), (70, 80, 90),
> (100, 110, 120) second row: (110, 130, 140), (120, 140, 150), (130,
> 150, 160), (140, 160, 170) third row: (195, 204, 213), (205, 214,
> 223), (225, 234, 243), (245, 254, 253) fourth row: (50, 28, 90), (0,
> 0, 0), (255, 255, 255), (85, 85, 85) running ./testing 0 5... checking
> for output "20 20 20\n50 50 50\n80 80 80\n110 110 110\n127 127
> 127\n137 137 137\n147 147 147\n157 157 157\n204 204 204\n214 214
> 214\n234 234 234\n251 251 251\n56 56 56\n0 0 0\n255 255 255\n85 85
> 85\n"...
> 
> Expected Output: 20 20 20 50 50 50 80 80 80 110 110 110 127 127 127
> 137 137 137 147 147 147 157 157 157 204 204 204 214 214 214 234 234
> 234 251 251 251 56 56 56 0 0 0 255 255 255 85 85 85 Actual Output: 20
> 20 20 50 50 50 80 80 80 110 110 110 126 126 126 136 136 136 146 146
> 146 156 156 156 204 204 204 214 214 214 234 234 234 250 250 250 56 56
> 56 0 0 0 255 255 255 85 85 85

我将使用框模糊来执行此操作,并尝试确定单元与所有周围项目的总和,然后获得平均值。

首先我尝试单独分配值:

image[i][j].rbgtRed = round((image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 4)

然后我意识到它正在采用新值,因此基本上只是重置了整个图像。我想用一个数组来切换类似于反射的值并使用:

        int tmpR[height][width];
        int tmpG[height][width];
        int tmpB[height][width];

它不起作用,所以我开始计算单元数并重置数组值以响应。完成此操作后,我一直在尝试慢慢浏览代码,但尚未确定因素。下面是代码。

```C
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
    int gscale;
    //loop for all pixels in rows
    for (int i = 0; i < height; i++)
    {
        //loop for pixels in columns
        for (int j = 0; j < width; j++)
        {
            //get the average of all the variables
            gscale = round((image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3);

            image[i][j].rgbtRed = gscale;
            image[i][j].rgbtGreen = gscale;
            image[i][j].rgbtBlue = gscale;

        }

    }

    return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
    //set sepia float
    float sRed;
    float sGreen;
    float sBlue;
    // loop through pixels:rows
    for (int i = 0; i <= height; i++)
    {
        // loop through pixels:columns
        for (int j = 0; j < width; j++)
        {
            // change pixels to float
            float r = image[i][j].rgbtRed;
            float g = image[i][j].rgbtGreen;
            float b = image[i][j].rgbtBlue;

            //calculations
            sRed = ((.393 * r) + (.769 * g) + (.189 * b));
            sGreen = ((.349 * r) + (.686 * g) + (.168 * b));
            sBlue = ((.272 * r) + (.534 * g) + (.131 * b));

            //Limits
            if (sRed > 255)
            {
                sRed = 255;
            }
            if (sGreen > 255)
            {
                sGreen = 255;
            }
            if (sBlue > 255)
            {
                sBlue = 255;
            }

            //Reset pixels
            image[i][j].rgbtRed = round(sRed);
            image[i][j].rgbtGreen = round(sGreen);
            image[i][j].rgbtBlue = round(sBlue);
        }
    }
    return;
}

// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{

    for (int i = 0; i <= height; i++)
    {
        for (int j = 0; j < width / 2; j++)
        {
            
            //temp variables
            int tmpR = image[i][j].rgbtRed;
            int tmpG = image[i][j].rgbtGreen;
            int tmpB = image[i][j].rgbtBlue;
            // opposite end is = width - unit
            //Swap
            image[i][j].rgbtRed = image[i][(width - 1) - j].rgbtRed;
            image[i][j].rgbtGreen = image[i][(width - 1) - j].rgbtGreen;
            image[i][j].rgbtBlue = image[i][(width - 1) - j].rgbtBlue;

            image[i][(width - 1) - j].rgbtRed = tmpR;
            image[i][(width - 1) - j].rgbtGreen = tmpG;
            image[i][(width - 1) - j].rgbtBlue = tmpB;
            
        }
    }
    return;
}

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    //count total pixels
    int counth = 0;
    int countw = 0;
    for (int a = 0; a <= height; a++)
    {
        for (int b = 0; b < width; b++)
        {
            countw++;
        }
        counth++;
    }
    //Temp arrays
    int tmpR[counth][countw];
    int tmpG[counth][countw];
    int tmpB[counth][countw];
    
    for (int i = 0; i <= height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            
            
            if(i == 0 && j == 0)
            {
                //build box for calculation for left top of box
                tmpR[i][j] = round((image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 4);
                tmpG[i][j] = round((image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 4);

            }
            else if (i == 0 && j == (width - 1))
            {
                //build box for calculation for right top corner of box
                tmpR[i][j] = round((image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed) / 4);
                tmpG[i][j] = round((image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue) / 4);

            }
            else if (i == height  && j == 0)
            {
                //build box for calculation for left bottom corner of box
                tmpR[i][j] = round((image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed) / 4);
                tmpG[i][j] = round((image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue) / 4);
            ;

            }
            else if (i == height && j ==  (width - 1))
            {
                //build box for calculation for right bottom corner of box
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed) / 4);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen) / 4);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue) / 4);

            }
            else if (i == 0)
            {
                //build box for calculation for top of box
                tmpR[i][j] = round((image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 6);
                tmpG[i][j] = round((image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 6);

            }
            else if (i == (height - 1))
            {
                //build box for calculation for bottom of box
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed) / 6);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue) / 6);

            }
            else if (j == 0)
            {
                //build box for calculation for left of box
                tmpR[i][j] = round((image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 6);
                tmpG[i][j] = round((image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 6);

            }
            else if (j == (width - 1))
            {
                //build box for calculation for right of box
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed) / 6);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen) / 6);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue) / 6);

            }
            else
            {
                //build box for calculation for center digits
                tmpR[i][j] = round((image[i - 1][j - 1].rgbtRed + image[i - 1][j].rgbtRed + image[i - 1][j + 1].rgbtRed + image[i][j - 1].rgbtRed + image[i][j].rgbtRed + image[i][j + 1].rgbtRed + image[i + 1][j - 1].rgbtRed + image[i + 1][j].rgbtRed + image[i + 1][j + 1].rgbtRed) / 9);
                tmpG[i][j] = round((image[i - 1][j - 1].rgbtGreen + image[i - 1][j].rgbtGreen + image[i - 1][j + 1].rgbtGreen + image[i][j - 1].rgbtGreen + image[i][j].rgbtGreen + image[i][j + 1].rgbtGreen + image[i + 1][j - 1].rgbtGreen + image[i + 1][j].rgbtGreen + image[i + 1][j + 1].rgbtGreen) / 9);
                tmpB[i][j] = round((image[i - 1][j - 1].rgbtBlue + image[i - 1][j].rgbtBlue + image[i - 1][j + 1].rgbtBlue + image[i][j - 1].rgbtBlue + image[i][j].rgbtBlue + image[i][j + 1].rgbtBlue + image[i + 1][j - 1].rgbtBlue + image[i + 1][j].rgbtBlue + image[i + 1][j + 1].rgbtBlue) / 9);

            }
        }
    }
    
    // Reset new values
    for (int i = 0; i <= height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            image[i][j].rgbtRed = tmpR[i][j];
            image[i][j].rgbtGreen = tmpG[i][j];
            image[i][j].rgbtBlue = tmpB[i][j];
        }
    }
    return;
}

我知道代码并不像它可以的那样优雅,但是我正在寻找指导,如果我能以任何方式改进,我将不胜感激建议并帮助找出为什么这不是工作。

【问题讨论】:

    标签: c cs50


    【解决方案1】:

    关于灰度问题

    如果我们仔细阅读了您的错误;

    :( 灰度正确过滤没有整数的单个像素 平均预期“28 28 28\n”,而不是“27 27 27\n”。

    这意味着您的灰度计算不正确。对 RGB 值的平均值进行四舍五入的方式似乎不正确。当您将三个整数除以 3 时,结果将是整数。这带来了精度问题。

    例如2/3 将导致0。 round(0) => 0。

    如果你这样做 2/3.0 = 0.6666..(双精度),round(0.6666..) 将是 1。

    首先计算double 中的所有内容,然后在最后一步将它们四舍五入 到integer。

    【讨论】:

    • 这很有意义,我会继续努力的。当我在考虑我的模糊计算时,如果我创建一个循环来运行该框而不是手动编写它会更好吗?
    • 感谢您对灰度的帮助,因为得到了模糊,我已经编辑了代码以将其反映到一个循环中,并将分割单位更改为浮点数,并复制了要使用的图像用于计算及其工作。
    猜你喜欢
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2017-09-21
    • 2013-03-22
    • 1970-01-01
    • 2017-01-13
    相关资源
    最近更新 更多