将常规彩色图像转换为模糊版本

时间:2019-10-04 16:11:29

标签: c

我正在尝试创建代码,以将图像转换为自身的模糊版本。下面的代码确实生成了一个模糊的版本,但是在我的作业的检查工具中,出现以下错误:

  • 模糊不过滤边缘像素 应该是“ 80 95 105 \ n”,而不是“ 40 50 60 \ n”
  • 模糊不过滤角落的像素 应该是“ 70 85 95 \ n”,而不是“ 10 20 30 \ n”
  • 模糊无法正确过滤3x3图像 应该是“ 70 85 95 \ n80 9 ...”,而不是“ 10 20 30 \ n40 5 ...
  • 模糊无法正确过滤4x4图像 应该是“ 70 85 95 \ n80 9 ...”,而不是“ 10 20 30 \ n40 5 ...

由于数字相差太大,这似乎不是一个四舍五入的问题,而是完全不同的问题。有任何想法吗?我缺少基本的东西吗?


void blur(int height, int width, RGBTRIPLE image[height][width])
{

for (int i = 1; i < height - 1; i++)
    {
        for (int j = 1; j < width - 1; j++)
        {
                int sumred = 0;
                int sumgreen = 0;
                int sumblue = 0;

                for (int a = i - 1; a <= i + 1; a++)
                {
                    for (int b = j - 1; b <= j + 1; b++)
                    {
                        sumred = image[a][b].rgbtRed + sumred;
                        sumblue = image[a][b].rgbtBlue + sumblue;
                        sumgreen = image[a][b].rgbtGreen + sumgreen;
                    }
                }

                int x = round((float)sumred / 9);
                int y = round((float)sumgreen / 9);
                int z = round((float)sumblue / 9);

                image[i][j].rgbtRed = x;
                image[i][j].rgbtGreen = y;
                image[i][j].rgbtBlue = z;
        }

}
 return;
}

2 个答案:

答案 0 :(得分:1)

缺少一些基本知识。

“不模糊边缘”是因为循环排除了所有边缘像素。取而代之的是,迭代每个像素,测试并计数相邻的像素,而忽略“不在地图上”的相邻像素。因此,在角落处,您将平均4个像素,将它们的总和除以4。

除此之外,您应该创建一个新图像,而不要修改前一个图像-通过对已经取平均值的值取平均值,将会得到不正确的结果。

例如:

public function showY(){
    $name=Auth::user()->name;
    return view('dashboard',['name'=>$name]);
}

public function showX(){
    $y= Y::all();
}

可能存在一个论点,您应该“加权”边缘的目标像素以补偿地图上的像素,这样,例如,如果地图上有3个像素,则不能考虑,您总计void blur(int height, int width, RGBTRIPLE newim[height][width], RGBTRIPLE image[height][width]) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int sumred = 0; int sumgreen = 0; int sumblue = 0; int count = 0; for (int a = i - 1; a <= i + 1; a++) { if(a >= 0 && a < height) { for (int b = j - 1; b <= j + 1; b++) { if(b >= 0 && b < width) { sumred += image[a][b].rgbtRed; sumblue += image[a][b].rgbtBlue; sumgreen += image[a][b].rgbtGreen; count++; } } } } newim[i][j].rgbtRed = round((float)sumred / count); newim[i][j].rgbtGreen = round((float)sumgreen / count); newim[i][j].rgbtBlue = round((float)sumblue / count); } } } 当前像素的成分,但仍除以4 *。但这取决于“模糊”的定义。

答案 1 :(得分:0)

发布的代码可能存在问题,即它不处理输入图像的边框像素。看一下for循环:

for (int i = 1; i < height - 1; i++)
    {
        for (int j = 1; j < width - 1; j++)
        {
        //...

i = 0或j = 0的像素怎么样?处理边界像素有不同的方法。最简单的方法是只考虑现有像素,例如,对于一个角像素,只需考虑三个相邻像素并除以4。要完成分配,您必须知道应该处理边框像素的方式。

此外,您应该创建一个新图像。在发布的代码中,您取平均值。参见下面的源代码:

void blur(int height, int width, RGBTRIPLE image[height][width])
{
    // Make a copy first
    RGBTRIPLE copy_image[height][width];
    for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                copy_image[i][j] = image[i][j];
            }
        }

    for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                    float sumred = 0;
                    float sumgreen = 0;
                    float sumblue = 0;
                    int count = 0;

                    for (int a = i - 1; a <= i + 1; a++)
                    {
                        if(a > -1 && a < height) {
                            for (int b = j - 1; b <= j + 1; b++)
                            {
                                if(b > -1 && b < width) {
                                    sumred += image[a][b].rgbtRed;
                                    sumblue += image[a][b].rgbtBlue;
                                    sumgreen += image[a][b].rgbtGreen;
                                    ++count;
                                }
                            }
                        }
                    }

                    copy_image[i][j].rgbtRed = round((sumred) / ((float) count));
                    copy_image[i][j].rgbtGreen = round((sumgreen) / ((float) count));
                    copy_image[i][j].rgbtBlue= round((sumblue) / ((float) count));
            }
    }

    // Save the result
    for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                image[i][j] = copy_image[i][j];
            }
        }
}