在 C 中模糊图像:代码只有一半有效
Blurring an Image in C: Code only half works
我的目标是通过取所有周围像素的平均值来模糊 C(不是 C++)中的图像。
我将我的计算分开:
- 如果像素在左上角
- 如果像素在右上角
- 如果像素位于左下中心
- 如果像素在右下角
- 如果像素在上边缘(无角)
- 如果像素位于底部边缘(无角)
- 所有其他像素
我的代码有很多问题,我通过创建图像的副本修复了这个问题。但是,当我的代码到达 3x3 和 4x4 图像的底部几行时,它开始不起作用。
我需要帮助来检查我的代码有什么问题。另外,我知道我的代码非常冗长,这是我写出所有内容并加深理解的一种方式,但我也希望有人能以另一种方式提供输入来编写代码。我对此很陌生,所以我肯定需要很多解释。我已经搜索并查看了其他缩短的、写得很好的代码,但我很难理解它。
非常感谢所有帮助!
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width]){
//top left corner variables
float ravg_lcorner = 0;
float gavg_lcorner = 0;
float bavg_lcorner = 0;
//top right corner variables
float ravg_rcorner = 0;
float gavg_rcorner = 0;
float bavg_rcorner = 0;
//bottom left corner variables
float ravg_blcorner = 0;
float gavg_blcorner = 0;
float bavg_blcorner = 0;
//bottom right corner variables
float ravg_brcorner = 0;
float gavg_brcorner = 0;
float bavg_brcorner = 0;
//top row center variables
float ravg_topcenter = 0;
float gavg_topcenter = 0;
float bavg_topcenter = 0;
//top row center variables
float ravg_btmcenter = 0;
float gavg_btmcenter = 0;
float bavg_btmcenter = 0;
//left side center variables
float ravg_lscenter = 0;
float gavg_lscenter = 0;
float bavg_lscenter = 0;
//right side center variables
float ravg_rscenter = 0;
float gavg_rscenter = 0;
float bavg_rscenter = 0;
//center variaables
float ravg_center = 0;
float gavg_center = 0;
float bavg_center = 0;
RGBTRIPLE temp;
RGBTRIPLE copy_image[height][width];
//create copy of image canvas
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp = image[i][j];
image[i][j] = copy_image[i][j];
copy_image[i][j] = temp;
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//if pixel is at top row left corner
if (i == 0 && j == 0)
{
//calculate all red average
ravg_lcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j+1].rgbtRed) / 4.00);
//calculate all green average
gavg_lcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j+1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_lcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j+1].rgbtBlue) / 4.00);
//new pixel color
image[i][j].rgbtRed = ravg_lcorner;
image[i][j].rgbtGreen = gavg_lcorner;
image[i][j].rgbtBlue = bavg_lcorner;
}
//if pixel is top row right corner
if (i == 0 && j == width - 1)
{
//calculate all red average
ravg_rcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j-1].rgbtRed) / 4.00);
//calculate all green average
gavg_rcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j-1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_rcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j-1].rgbtBlue) / 4.00);
//new pixel color
image[i][j].rgbtRed = ravg_rcorner;
image[i][j].rgbtGreen = gavg_rcorner;
image[i][j].rgbtBlue = bavg_rcorner;
}
//if pixel is at bottom row left corner
if(i == height - 1 && j == 0)
{
//calculate all red average
ravg_blcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed) / 4.00);
//calculate all green average
gavg_blcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_blcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue) / 4.00);
//new pixel color
copy_image[i][j].rgbtRed = ravg_blcorner;
copy_image[i][j].rgbtGreen = gavg_blcorner;
copy_image[i][j].rgbtBlue = bavg_blcorner;
}
//if pixel is at bottom row right corner
if(i == height -1 && j == width - 1)
{
//calculate all red average
ravg_brcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j-1].rgbtRed) / 4.00);
//calculate all green average
gavg_brcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j-1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_brcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j-1].rgbtBlue) / 4.00);
//new pixel color
image[i][j].rgbtRed = ravg_rcorner;
image[i][j].rgbtGreen = gavg_rcorner;
image[i][j].rgbtBlue = bavg_rcorner;
}
//if pixel is top row center
if(i == 0 && j < width - 1 && j > 0)
{
//calculate all red average
ravg_topcenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i+1][j-1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j+1].rgbtRed) / 6.00);
//calculate all green average
gavg_topcenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i+1][j-1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j+1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_topcenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i+1][j-1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j+1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_topcenter;
image[i][j].rgbtGreen = gavg_topcenter;
image[i][j].rgbtBlue = bavg_topcenter;
}
//if pixel is bottom row center
if(i == height - 1 && j < width - 1 && j > 0)
{
//calculate all red average
ravg_topcenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i-1][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed) / 6.00);
//calculate all green average
gavg_topcenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i-1][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_topcenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i-1][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_btmcenter;
image[i][j].rgbtGreen = gavg_btmcenter;
image[i][j].rgbtBlue = bavg_btmcenter;
}
//if pixel is at left side center
if (i < height - 1 && i > 0 && j == 0)
{
//calculate all red average
ravg_lscenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j+1].rgbtRed) / 6.00);
//calculate all green average
gavg_lscenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j+1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_lscenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j+1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_lscenter;
image[i][j].rgbtGreen = gavg_lscenter;
image[i][j].rgbtBlue = bavg_lscenter;
}
//if pixel is at right side center
if (i < height - 1 && i > 0 && j == width - 1)
{
//calculate all red average
ravg_rscenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j-1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j-1].rgbtRed) / 6.00);
//calculate all green average
gavg_rscenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j-1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j-1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_rscenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j-1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j-1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_rscenter;
image[i][j].rgbtGreen = gavg_rscenter;
image[i][j].rgbtBlue = bavg_rscenter;
}
//if pixel is at center
if (i < height - 1 && i > 0 && j < width - 1 && j > 0)
{
//calculate all red average
ravg_center = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i+1][j+1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j-1].rgbtRed + copy_image[i-1][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed) / 9.00);
//calculate all green average
gavg_center = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i+1][j+1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j-1].rgbtGreen + copy_image[i-1][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen) / 9.00);
//calculate all blue average
bavg_center = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i+1][j+1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j-1].rgbtBlue + copy_image[i-1][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue) / 9.00);
//new pixel color
image[i][j].rgbtRed = ravg_center;
image[i][j].rgbtGreen = gavg_center;
image[i][j].rgbtBlue = bavg_center;
}
}
}
return;}
好的,下次把你的类型定义包含在问题中,这样人们就可以避免猜测。
我建议通过避免复制和粘贴来简化它。这应该是一个规则:“如果你复制粘贴,你就做错了”。
所以我们可以遍历图像,遍历 3x3 邻域,对值求和并计算我们有多少有效像素。然后我们除以该计数。我避免了四舍五入并坚持使用更简单的截断,但如果你真的想四舍五入,用整数来做,不要仅仅为此使用浮点数。
这三个函数是为了让代码更简洁,可以用重复的代码代替。
我的意见:不要使用带名称的 RGB 三元组,而更喜欢具有 3 个元素的数组,这样您可以更轻松地循环通道。我强烈建议避免使用 VLA。 Visual Studio 不支持它们,使用起来很痛苦。
最后,您的“复制图像”将未定义的数据无用地交换到图像中。
最后,我没有测试这段代码!
#include <stdint.h>
#include <string.h>
typedef struct tagRGBTRIPLE {
uint8_t rgbtRed, rgbtGreen, rgbtBlue;
} RGBTRIPLE;
RGBTRIPLE rgbtMake(int r, int g, int b)
{
RGBTRIPLE out = { r, g, b };
return out;
}
void rgbtIntAdd(int *r, int *g, int *b, RGBTRIPLE *t)
{
*r += t->rgbtRed;
*g += t->rgbtGreen;
*b += t->rgbtBlue;
}
void rgbtIntDiv(int *r, int *g, int *b, int div)
{
*r /= div;
*g /= div;
*b /= div;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE copy_image[height][width];
//create copy of image canvas
memcpy(copy_image, image, height * width * sizeof(RGBTRIPLE));
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int r = 0, g = 0, b = 0, count = 0;
for (int m = -1; m <= 1; ++m) {
if (i + m < 0 || i + m >= height) {
continue;
}
for (int n = -1; n <= 1; ++n) {
if (j + n < 0 || j + n >= width) {
continue;
}
rgbtIntAdd(&r, &g, &b, ©_image[i + m][j + n]);
++count;
}
}
rgbtIntDiv(&r, &g, &b, count);
image[i][j] = rgbtMake(r, g, b);
}
}
}
我的目标是通过取所有周围像素的平均值来模糊 C(不是 C++)中的图像。 我将我的计算分开:
- 如果像素在左上角
- 如果像素在右上角
- 如果像素位于左下中心
- 如果像素在右下角
- 如果像素在上边缘(无角)
- 如果像素位于底部边缘(无角)
- 所有其他像素
我的代码有很多问题,我通过创建图像的副本修复了这个问题。但是,当我的代码到达 3x3 和 4x4 图像的底部几行时,它开始不起作用。
我需要帮助来检查我的代码有什么问题。另外,我知道我的代码非常冗长,这是我写出所有内容并加深理解的一种方式,但我也希望有人能以另一种方式提供输入来编写代码。我对此很陌生,所以我肯定需要很多解释。我已经搜索并查看了其他缩短的、写得很好的代码,但我很难理解它。
非常感谢所有帮助!
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width]){
//top left corner variables
float ravg_lcorner = 0;
float gavg_lcorner = 0;
float bavg_lcorner = 0;
//top right corner variables
float ravg_rcorner = 0;
float gavg_rcorner = 0;
float bavg_rcorner = 0;
//bottom left corner variables
float ravg_blcorner = 0;
float gavg_blcorner = 0;
float bavg_blcorner = 0;
//bottom right corner variables
float ravg_brcorner = 0;
float gavg_brcorner = 0;
float bavg_brcorner = 0;
//top row center variables
float ravg_topcenter = 0;
float gavg_topcenter = 0;
float bavg_topcenter = 0;
//top row center variables
float ravg_btmcenter = 0;
float gavg_btmcenter = 0;
float bavg_btmcenter = 0;
//left side center variables
float ravg_lscenter = 0;
float gavg_lscenter = 0;
float bavg_lscenter = 0;
//right side center variables
float ravg_rscenter = 0;
float gavg_rscenter = 0;
float bavg_rscenter = 0;
//center variaables
float ravg_center = 0;
float gavg_center = 0;
float bavg_center = 0;
RGBTRIPLE temp;
RGBTRIPLE copy_image[height][width];
//create copy of image canvas
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp = image[i][j];
image[i][j] = copy_image[i][j];
copy_image[i][j] = temp;
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
//if pixel is at top row left corner
if (i == 0 && j == 0)
{
//calculate all red average
ravg_lcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j+1].rgbtRed) / 4.00);
//calculate all green average
gavg_lcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j+1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_lcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j+1].rgbtBlue) / 4.00);
//new pixel color
image[i][j].rgbtRed = ravg_lcorner;
image[i][j].rgbtGreen = gavg_lcorner;
image[i][j].rgbtBlue = bavg_lcorner;
}
//if pixel is top row right corner
if (i == 0 && j == width - 1)
{
//calculate all red average
ravg_rcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j-1].rgbtRed) / 4.00);
//calculate all green average
gavg_rcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j-1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_rcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j-1].rgbtBlue) / 4.00);
//new pixel color
image[i][j].rgbtRed = ravg_rcorner;
image[i][j].rgbtGreen = gavg_rcorner;
image[i][j].rgbtBlue = bavg_rcorner;
}
//if pixel is at bottom row left corner
if(i == height - 1 && j == 0)
{
//calculate all red average
ravg_blcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed) / 4.00);
//calculate all green average
gavg_blcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_blcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue) / 4.00);
//new pixel color
copy_image[i][j].rgbtRed = ravg_blcorner;
copy_image[i][j].rgbtGreen = gavg_blcorner;
copy_image[i][j].rgbtBlue = bavg_blcorner;
}
//if pixel is at bottom row right corner
if(i == height -1 && j == width - 1)
{
//calculate all red average
ravg_brcorner = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j-1].rgbtRed) / 4.00);
//calculate all green average
gavg_brcorner = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j-1].rgbtGreen) / 4.00);
//calculate all blue average
bavg_brcorner = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j-1].rgbtBlue) / 4.00);
//new pixel color
image[i][j].rgbtRed = ravg_rcorner;
image[i][j].rgbtGreen = gavg_rcorner;
image[i][j].rgbtBlue = bavg_rcorner;
}
//if pixel is top row center
if(i == 0 && j < width - 1 && j > 0)
{
//calculate all red average
ravg_topcenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i+1][j-1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j+1].rgbtRed) / 6.00);
//calculate all green average
gavg_topcenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i+1][j-1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j+1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_topcenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i+1][j-1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j+1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_topcenter;
image[i][j].rgbtGreen = gavg_topcenter;
image[i][j].rgbtBlue = bavg_topcenter;
}
//if pixel is bottom row center
if(i == height - 1 && j < width - 1 && j > 0)
{
//calculate all red average
ravg_topcenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i-1][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed) / 6.00);
//calculate all green average
gavg_topcenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i-1][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_topcenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i-1][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_btmcenter;
image[i][j].rgbtGreen = gavg_btmcenter;
image[i][j].rgbtBlue = bavg_btmcenter;
}
//if pixel is at left side center
if (i < height - 1 && i > 0 && j == 0)
{
//calculate all red average
ravg_lscenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j+1].rgbtRed) / 6.00);
//calculate all green average
gavg_lscenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j+1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_lscenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j+1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_lscenter;
image[i][j].rgbtGreen = gavg_lscenter;
image[i][j].rgbtBlue = bavg_lscenter;
}
//if pixel is at right side center
if (i < height - 1 && i > 0 && j == width - 1)
{
//calculate all red average
ravg_rscenter = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j-1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j-1].rgbtRed) / 6.00);
//calculate all green average
gavg_rscenter = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j-1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j-1].rgbtGreen) / 6.00);
//calculate all blue average
bavg_rscenter = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j-1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j-1].rgbtBlue) / 6.00);
//new pixel color
image[i][j].rgbtRed = ravg_rscenter;
image[i][j].rgbtGreen = gavg_rscenter;
image[i][j].rgbtBlue = bavg_rscenter;
}
//if pixel is at center
if (i < height - 1 && i > 0 && j < width - 1 && j > 0)
{
//calculate all red average
ravg_center = (int) round((copy_image[i][j].rgbtRed + copy_image[i][j-1].rgbtRed + copy_image[i][j+1].rgbtRed + copy_image[i+1][j+1].rgbtRed + copy_image[i+1][j].rgbtRed + copy_image[i+1][j-1].rgbtRed + copy_image[i-1][j-1].rgbtRed + copy_image[i-1][j].rgbtRed + copy_image[i-1][j+1].rgbtRed) / 9.00);
//calculate all green average
gavg_center = (int) round((copy_image[i][j].rgbtGreen + copy_image[i][j-1].rgbtGreen + copy_image[i][j+1].rgbtGreen + copy_image[i+1][j+1].rgbtGreen + copy_image[i+1][j].rgbtGreen + copy_image[i+1][j-1].rgbtGreen + copy_image[i-1][j-1].rgbtGreen + copy_image[i-1][j].rgbtGreen + copy_image[i-1][j+1].rgbtGreen) / 9.00);
//calculate all blue average
bavg_center = (int) round((copy_image[i][j].rgbtBlue + copy_image[i][j-1].rgbtBlue + copy_image[i][j+1].rgbtBlue + copy_image[i+1][j+1].rgbtBlue + copy_image[i+1][j].rgbtBlue + copy_image[i+1][j-1].rgbtBlue + copy_image[i-1][j-1].rgbtBlue + copy_image[i-1][j].rgbtBlue + copy_image[i-1][j+1].rgbtBlue) / 9.00);
//new pixel color
image[i][j].rgbtRed = ravg_center;
image[i][j].rgbtGreen = gavg_center;
image[i][j].rgbtBlue = bavg_center;
}
}
}
return;}
好的,下次把你的类型定义包含在问题中,这样人们就可以避免猜测。
我建议通过避免复制和粘贴来简化它。这应该是一个规则:“如果你复制粘贴,你就做错了”。
所以我们可以遍历图像,遍历 3x3 邻域,对值求和并计算我们有多少有效像素。然后我们除以该计数。我避免了四舍五入并坚持使用更简单的截断,但如果你真的想四舍五入,用整数来做,不要仅仅为此使用浮点数。
这三个函数是为了让代码更简洁,可以用重复的代码代替。
我的意见:不要使用带名称的 RGB 三元组,而更喜欢具有 3 个元素的数组,这样您可以更轻松地循环通道。我强烈建议避免使用 VLA。 Visual Studio 不支持它们,使用起来很痛苦。
最后,您的“复制图像”将未定义的数据无用地交换到图像中。
最后,我没有测试这段代码!
#include <stdint.h>
#include <string.h>
typedef struct tagRGBTRIPLE {
uint8_t rgbtRed, rgbtGreen, rgbtBlue;
} RGBTRIPLE;
RGBTRIPLE rgbtMake(int r, int g, int b)
{
RGBTRIPLE out = { r, g, b };
return out;
}
void rgbtIntAdd(int *r, int *g, int *b, RGBTRIPLE *t)
{
*r += t->rgbtRed;
*g += t->rgbtGreen;
*b += t->rgbtBlue;
}
void rgbtIntDiv(int *r, int *g, int *b, int div)
{
*r /= div;
*g /= div;
*b /= div;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE copy_image[height][width];
//create copy of image canvas
memcpy(copy_image, image, height * width * sizeof(RGBTRIPLE));
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int r = 0, g = 0, b = 0, count = 0;
for (int m = -1; m <= 1; ++m) {
if (i + m < 0 || i + m >= height) {
continue;
}
for (int n = -1; n <= 1; ++n) {
if (j + n < 0 || j + n >= width) {
continue;
}
rgbtIntAdd(&r, &g, &b, ©_image[i + m][j + n]);
++count;
}
}
rgbtIntDiv(&r, &g, &b, count);
image[i][j] = rgbtMake(r, g, b);
}
}
}