【发布时间】:2020-05-11 19:57:26
【问题描述】:
以下是我的代码。当我编译它时,我的代码中没有明显的错误。但是,我未通过所有 Check50 测试。我的算法推理有什么缺陷?
基本上,我的代码旨在将所有像素复制到另一个名为“旧”的结构中,该结构将保留原始图像的内容。
接下来,我创建了一个临时像素结构数组,我称之为“temp”。该数组由 9 个元素组成,用于其自身和每个周围的像素。以下 4 个“if 语句”测试像素是否为边框像素。如果是,则为“temp”数组中相关元素的红色分配负值 -1。这本质上是在算法的后期丢弃它们。
接下来,我声明了三个整数变量,用于跟踪周围像素上的红色、绿色和蓝色的总值。然后,如果红色值是负数,我检查每个周围的像素,如果是,我将其丢弃。如果它确实是一个正数,我将添加到红色、蓝色和绿色的总数中。我同时跟踪周围像素的总数,以便最终将红色、绿色和蓝色的总值除以该计数。对每个像素重复上述操作。从理论上讲,这应该会产生模糊的图像,但显然不会。我的推理或代码有什么问题?
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE old[height][width];
RGBTRIPLE temp[9];
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
old[i][j] = image[i][j];
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
temp[0] = old[i-1][j-1];
temp[1] = old[i][j-1];
temp[2] = old[i+1][j-1];
temp[3] = old[i-1][j];
temp [4] = old[i][j];
temp [5] = old[i+1][j];
temp [6] = old[i-1][j+1];
temp [7] = old[i][j+1];
temp [8] = old[i+1][j+1];
if (i == 0)
{
temp[0].rgbtRed = -1;
temp[3].rgbtRed = -1;
temp[6].rgbtRed = -1;
}
else if (i == height-1)
{
temp[2].rgbtRed = -1;
temp[5].rgbtRed = -1;
temp[8].rgbtRed = -1;
}
if (j == 0)
{
temp[0].rgbtRed = -1;
temp[1].rgbtRed = -1;
temp[2].rgbtRed = -1;
}
else if (j == width-1)
{
temp[6].rgbtRed = -1;
temp[7].rgbtRed = -1;
temp[8].rgbtRed = -1;
}
int Red = 0;
int Green = 0;
int Blue = 0;
int c = 0;
for (int m = 0; m <= 8; m++)
{
if (temp[m].rgbtRed >= 0)
{
c++;
Red = Red + temp[m].rgbtRed;
Green = Green + temp[m].rgbtGreen;
Blue = Blue + temp[m].rgbtBlue;
}
}
image[i][j].rgbtRed = round(Red/c);
image[i][j].rgbtGreen = round(Green/c);
image[i][j].rgbtBlue = round(Blue/c);
}
}
}
[编辑]主代码:
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include "helpers.h"
int main(int argc, char *argv[])
{
// Define allowable filters
char *filters = "bgrs";
// Get filter flag and check validity
char filter = getopt(argc, argv, filters);
if (filter == '?')
{
fprintf(stderr, "Invalid filter.\n");
return 1;
}
// Ensure only one filter
if (getopt(argc, argv, filters) != -1)
{
fprintf(stderr, "Only one filter allowed.\n");
return 2;
}
// Ensure proper usage
if (argc != optind + 2)
{
fprintf(stderr, "Usage: filter [flag] infile outfile\n");
return 3;
}
// Remember filenames
char *infile = argv[optind];
char *outfile = argv[optind + 1];
// Open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", infile);
return 4;
}
// Open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// Read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// Read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
// Ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
bi.biBitCount != 24 || bi.biCompression != 0)
{
fclose(outptr);
fclose(inptr);
fprintf(stderr, "Unsupported file format.\n");
return 6;
}
int height = abs(bi.biHeight);
int width = bi.biWidth;
// Allocate memory for image
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
if (image == NULL)
{
fprintf(stderr, "Not enough memory to store image.\n");
fclose(outptr);
fclose(inptr);
return 7;
}
// Determine padding for scanlines
int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;
// Iterate over infile's scanlines
for (int i = 0; i < height; i++)
{
// Read row into pixel array
fread(image[i], sizeof(RGBTRIPLE), width, inptr);
// Skip over padding
fseek(inptr, padding, SEEK_CUR);
}
// Filter image
switch (filter)
{
// Blur
case 'b':
blur(height, width, image);
break;
// Grayscale
case 'g':
grayscale(height, width, image);
break;
// Reflection
case 'r':
reflect(height, width, image);
break;
// Sepia
case 's':
sepia(height, width, image);
break;
}
// Write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// Write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// Write new pixels to outfile
for (int i = 0; i < height; i++)
{
// Write row to outfile
fwrite(image[i], sizeof(RGBTRIPLE), width, outptr);
// Write padding at end of row
for (int k = 0; k < padding; k++)
{
fputc(0x00, outptr);
}
}
// Free memory for image
free(image);
// Close infile
fclose(inptr);
// Close outfile
fclose(outptr);
return 0;
}
[RGB 三重清晰度]
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
【问题讨论】:
-
把这里用到的
RGBTRIPLE的定义贴出来。 -
RGBTRIPLE 基本上包括三个整数,一个像素值代表红色、绿色和蓝色的数量,范围从 0 到 155。我正在寻找 C 答案。
-
temp[0] = old[i-1][j-1];访问越界。 -
我能做些什么呢?
-
与其用文字描述
RGBTRIPLE,不如贴出code。
标签: c computer-science cs50