为什么这两个过滤器功能无法正常运行? cs50

时间:2020-04-24 18:36:47

标签: c cs50

我试图做一个可以拍摄图像并编辑其属性以产生灰度和蓝色效果的函数。

灰度功能的目的只是通过找到rbg的平均值然后将其分配来将像素转换为灰度,但是,每当运行check 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;
}

我知道代码并不尽如人意,但是我正在寻找学习过程中的指导,如果我能以任何方式进行改进,我将不胜感激这些建议,并帮助找出原因。工作。

1 个答案:

答案 0 :(得分:1)

针对灰度问题

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

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

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

例如,2/3将产生0round(0) => 0

如果您执行2/3.0 = 0.6666..(双精度),则round(0.6666..)将是1

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