(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 imageimage[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 imageimage[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 limitfor (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 boundaryif (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 roundsumRed = 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