(4)blur function
- 简单画图熟悉一下要做什么
- 可以看到
3种情况
,顶格,边界,里面 - 如果分开算的话,是真的麻烦;但是当时还真的没有想到更好的,就先写一写
(此处摘取3处)
- 外部都是
for (int i = 0; i < height; i++) { 下边省去不写 for (int j = 0; j < width; j++) { } }
里面
int sumRed = 0,sumGreen = 0,sumBlue = 0;
//set 3 conditions by the limit
//!前面1部分
//计算9个格子
if (i > 0 && i < height - 1 && j > 0 && j < width - 1) {
for (int k = -1; k <= 1; k++) {
for (int m = -1; m <= 1; m++) {
sumRed += copy[i + k][j + m].rgbtRed;
sumGreen += copy[i + k][j + m].rgbtGreen;
sumBlue += copy[i + k][j + m].rgbtBlue;
}
}
//after sum it all and give that value to image
image[i][j].rgbtRed = round(sumRed / 9.0);
image[i][j].rgbtGreen = round(sumGreen / 9.0);
image[i][j].rgbtBlue = round(sumBlue / 9.0);
}
顶格
//1.1 左上角 i + j +
sumRed = 0, sumGreen = 0, sumBlue = 0;
if (j == 0 && i == 0) {
for (int k = 0; k <= 1; k++) {
for (int m = 0; m <= 1; m++) {
sumRed += copy[i + k][j + m].rgbtRed;
sumGreen += copy[i + k][j + m].rgbtGreen;
sumBlue += copy[i + k][j + m].rgbtBlue;
}
}
//after sum it all and give that value to image
image[i][j].rgbtRed = round(sumRed / 4.0);
image[i][j].rgbtGreen = round(sumGreen / 4.0);
image[i][j].rgbtBlue = round(sumBlue / 4.0);
}
边界
//2.1上边界:移动的方向只有下(高度-1)k +,左边m -,右边m+
sumRed = 0, sumGreen = 0, sumBlue = 0;
if (i == 0) {
//计算RGB利用双循环(k,m)
for (int k = 0; k <= 1; k++) {
for (int m = -1; m <= 1; m++) {
sumRed += copy[i + k][j + m].rgbtRed;
sumGreen += copy[i + k][j + m].rgbtGreen;
sumBlue += copy[i + k][j + m].rgbtBlue;
}
}
image[i][j].rgbtRed = round(sumRed / 6.0);
image[i][j].rgbtGreen = round(sumGreen / 6.0);
image[i][j].rgbtBlue = round(sumBlue / 6.0);
}
简化
- 然后可以看到很多重复的地方,需要开始统一,找到不同的地方
4,6,9
,然后里层的双循环k,m其实也可以合并, - 只要移动之后的
index
在范围里面就可以了,里层循环的次数加上限定的条件计算count
,然后一步步开始删减…
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// copy the image[height][width]
RGBTRIPLE copy[height][width];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
copy[i][j] = image[i][j];
}
}
int sumRed = 0, sumGreen = 0, sumBlue = 0, count = 0;
// set 3 conditions by the limit
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
for (int k = -1; k <= 1; k++)
{
for (int m = -1; m <= 1; m++)
{
// condition limit boundary
if (i + k >= 0 && i + k <= height - 1 && j + m >= 0 && j + m <= width - 1)
{
sumRed += copy[i + k][j + m].rgbtRed;
sumGreen += copy[i + k][j + m].rgbtGreen;
sumBlue += copy[i + k][j + m].rgbtBlue;
count++;
}
}
}
// after sum it all and give that value to image
//before calculating the results,first convert it to float!
image[i][j].rgbtRed = round((float) sumRed / count);
image[i][j].rgbtGreen = round((float) sumGreen / count);
image[i][j].rgbtBlue = round((float) sumBlue / count);
// clear it and for next round
sumRed = 0, sumGreen = 0, sumBlue = 0, count = 0;
}
}
}
问题
这里要在计算之前,把int sumRGB值
转化成float
类型
image[i][j].rgbtRed = round((float) sumRed / count);
而不是float(计算之后的值)
,这样就把小数点之后的都丢了
image[i][j].rgbtRed = round((float)( sumRed / count));
总结
刚开始的时候想不到简洁的方法或者不太理解,先慢慢写出来,能运行就可以。
后面再去优化,一步一步来,不需要太大压力
check
:) helpers.c exists
:) filter compiles
:) grayscale correctly filters single pixel with whole number average
:) grayscale correctly filters single pixel without whole number average
:) grayscale leaves alone pixels that are already gray
:) grayscale correctly filters simple 3x3 image
:) grayscale correctly filters more complex 3x3 image
:) grayscale correctly filters 4x4 image
:) sepia correctly filters single pixel
:) sepia correctly filters simple 3x3 image
:) sepia correctly filters more complex 3x3 image
:) sepia correctly filters 4x4 image
:) reflect correctly filters 1x2 image
:) reflect correctly filters 1x3 image
:) reflect correctly filters image that is its own mirror image
:) reflect correctly filters 3x3 image
:) reflect correctly filters 4x4 image
:) blur correctly filters middle pixel
:) blur correctly filters pixel on edge
:) blur correctly filters pixel in corner
:) blur correctly filters 3x3 image
:) blur correctly filters 4x4 image