【发布时间】:2022-01-12 20:51:42
【问题描述】:
我使用以下结构在内存中加载 bmp 图像:
// header
typedef struct {
uint16_t type; // Magic identifier
uint32_t size; // File size in bytes
uint16_t reserved1; // Not used
uint16_t reserved2; // Not used
uint32_t offset;
uint32_t header_size; // Header size in bytes
uint32_t width; // Width of the image
uint32_t height; // Height of image
uint16_t planes; // Number of color planes
uint16_t bits; // Bits per pixel
uint32_t compression;// Compression type
uint32_t imagesize; // image size in bytes
uint32_t xresol; // pixels per meter
uint32_t yresol; // pixels per meter
uint32_t ncolours; // nr of colours
uint32_t importantcolours; // important colours
} BMP_Header;
// image details
typedef struct {
BMP_Header header;
uint64_t data_size;
uint64_t width;
uint64_t height;
uint8_t *data;// allocate memory based on width and height
} BMP_Image;
然后我想在它上面应用一个高斯滤波器。 相关函数如下:
double gaussianModel(double x, double y, double variance) {
return 1 / (2 * 3.14159 * pow(variance, 2)) * exp(-(x * x + y * y) / (2 * variance * variance));
}
double *generate_weights(int radius, double variance, int bits_nr) {
double *weights = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
double sum = 0;
for (int i = 0; i < radius; i++) {
for (int j = 0; j < radius * bits_nr; j++) {
weights[i * radius * bits_nr + j] = gaussianModel(i - radius / 2, j - radius / 2, variance);
sum += weights[i * radius + j];
}
}
// normalize
for (int i = 0; i < radius * radius; i++)
weights[i] /= sum;
return weights;
}
double getWeightedColorValue(double *w, int len, unsigned int index, unsigned int bits_nr) {
double sum = 0;
for (int i = index; i < len; i+= bits_nr)
sum += w[i];
return sum;
}
BMP_Image* BMP_blur_collapsed(BMP_Image *img, unsigned int bits_nr, unsigned int radius, unsigned int th_number, FILE* f) {
BMP_Image *bluredImg = malloc(sizeof(BMP_Image));
bluredImg->header = img->header;
bluredImg->data_size = (img->header.size - sizeof(BMP_Header)) * bits_nr;
bluredImg->width = img->header.width;
bluredImg->height = img->header.height;
bluredImg->data = malloc(sizeof(uint8_t) * bluredImg->data_size);
for(uint64_t i = 0; i < bluredImg->data_size; ++i)
bluredImg->data[i] = img->data[i];
double variance = 1.94;
double* weights = generate_weights(radius, variance, bits_nr);
uint64_t i, j;
double start, end;
start = omp_get_wtime();
#pragma omp parallel for private(i, j) collapse(2) schedule(static) num_threads(th_number)
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width * bits_nr - radius - bits_nr * 2; j+= bits_nr ) {
uint64_t ofs = i * img->width * bits_nr + j;
double *distributedColorRed = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
double *distributedColorGreen = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
double *distributedColorBlue = (double*)malloc(sizeof(double) * radius * radius * bits_nr);
for (int wx = 0; wx < radius; wx++) {
for (int wy = 0; wy < radius * bits_nr; wy += bits_nr) {
uint64_t wofs = wx * img->width * bits_nr + wy;
// double currWeight = weights[wx * radius + wy];
distributedColorRed[wofs] = weights[wx * radius + wy] * img->data[ofs];
distributedColorGreen[wofs + 1] = weights[wx * radius + wy + 1] * img->data[ofs + 1];
distributedColorBlue[wofs + 2] = weights[wx * radius + wy + 2] * img->data[ofs + 2];
}
}
bluredImg->data[ofs] = getWeightedColorValue(distributedColorRed, radius * radius * bits_nr, 0, bits_nr);
bluredImg->data[ofs + 1] = getWeightedColorValue(distributedColorGreen, radius * radius * bits_nr, 1, bits_nr);
bluredImg->data[ofs + 2] = getWeightedColorValue(distributedColorBlue, radius * radius * bits_nr, 2, bits_nr);
free(distributedColorRed);
free(distributedColorBlue);
free(distributedColorGreen);
}
}
end = omp_get_wtime();
fprintf(f, "blur collapsed %f \n", end - start);
free(weights);
return bluredImg;
}
假设img是一个BMP_Image对象,那么img->data里面已经存储了所有的像素:
img->data[i] is Red
img->data[i + 1] is Green
img->data[i + 2] is Blue
【问题讨论】:
-
bits_nr的用途是什么,它的典型值是什么? -
bits_nr代表每像素位数。在我的情况下,这个值是 3 或 4,它取决于图像。该字段存在于BMP_Header结构中:uint16_t bits; -
感谢您的反馈。我在下面的回答假设组件的数量为
3。如果您还需要支持4的情况,则需要进行一些调整(不难)。 BR。
标签: c bmp gaussianblur