在 C 中的 24/32 位 BMP 图像上应用高斯模糊滤镜
Apply gaussian blur filter on 24/32 bits BMP images in C
我使用以下结构在内存中加载一个 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
在使索引复杂化的计算中。
- 处理颜色分量 r、g 和
b 分别.
- 变量名
variance
不合适因为variance = sigma ** 2.
- 您不需要使用
1/sqrt(2*PI)/sigma
进行乘法运算
在 gaussianModel() 中因为它在归一化中被取消了。
这是一个完全可编译的代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#define SIGMA 1.94
#define RADIUS 5
#define INFILE "0Jayx.bmp"
#define OUTFILE "blurred.bmp"
// header
typedef struct __attribute__((__packed__)) {
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 width;
uint64_t height;
uint8_t *b;
uint8_t *g;
uint8_t *r;
} BMP_Image;
double gaussianModel(double x, double y, double sigma) {
return 1. / exp(-(x * x + y * y) / (2 * sigma * sigma));
}
double *generate_coeff(int radius, double sigma) {
double *coeff = malloc(sizeof(double) * radius * radius);
double sum = 0;
for (int i = 0; i < radius; i++) {
for (int j = 0; j < radius; j++) {
coeff[i * radius + j] = gaussianModel(i - radius / 2, j - radius / 2, sigma);
sum += coeff[i * radius + j];
}
}
// normalize
for (int i = 0; i < radius * radius; i++)
coeff[i] /= sum;
return coeff;
}
BMP_Image *BMP_blur_collapsed(BMP_Image *img, int radius, double sigma) {
BMP_Image *bimg = malloc(sizeof(BMP_Image));
bimg->header = img->header;
bimg->width = img->header.width;
bimg->height = img->header.height;
bimg->b = malloc(bimg->width * bimg->height);
bimg->g = malloc(bimg->width * bimg->height);
bimg->r = malloc(bimg->width * bimg->height);
int b, g, r;
double *coeff = generate_coeff(radius, sigma);
int i, j, m, n;
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width - radius; j++) {
b = g = r = 0;
for (m = 0; m < radius; m++) {
for (n = 0; n < radius; n++) {
b += coeff[m * radius + n] * img->b[(i + m) * img->width + (j + n)];
g += coeff[m * radius + n] * img->g[(i + m) * img->width + (j + n)];
r += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
}
}
bimg->b[i * bimg->width + j] = b;
bimg->g[i * bimg->width + j] = g;
bimg->r[i * bimg->width + j] = r;
}
}
free(coeff);
return bimg;
}
void free_img(BMP_Image *img)
{
free(img->b);
free(img->g);
free(img->r);
free(img);
}
BMP_Image *read_bmp_file(char *filename)
{
FILE *fp;
int i, j, bytesperline;
BMP_Image *img;
img = malloc(sizeof(BMP_Image));
if (NULL == (fp = fopen(filename, "r"))) {
perror(filename);
exit(1);
}
fread(&img->header, sizeof(char), sizeof(BMP_Header), fp);
img->width = img->header.width;
img->height = img->header.height;
bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
img->b = malloc(img->width * img->height);
img->g = malloc(img->width * img->height);
img->r = malloc(img->width * img->height);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
img->b[i * img->width + j] = getc(fp);
img->g[i * img->width + j] = getc(fp);
img->r[i * img->width + j] = getc(fp);
}
for (j = img->width * 3; j < bytesperline; j++) {
getc(fp);
}
}
return img;
}
void write_bmp_file(BMP_Image *img, char *filename)
{
FILE *fp;
int i, j, bytesperline;
if (NULL == (fp = fopen(filename, "w"))) {
perror(filename);
exit(1);
}
bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
fwrite(&img->header, sizeof(char), sizeof(BMP_Header), fp);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
putc(img->b[i * img->width + j], fp);
putc(img->g[i * img->width + j], fp);
putc(img->r[i * img->width + j], fp);
}
for (j = img->width * 3; j < bytesperline; j++) {
putc(0, fp);
}
}
}
int main()
{
BMP_Image *img = read_bmp_file(INFILE);
BMP_Image *bimg = BMP_blur_collapsed(img, RADIUS, SIGMA);
write_bmp_file(bimg, OUTFILE);
free_img(img);
free_img(bimg);
return 0;
}
生成的图像半径=5,sigma=1.94:
[编辑]
修改代码支持32位bmp文件:
- 删除
bytesperline
相关代码。
- 将
uint8_t *a;
附加到结构 BMP_Image。
- 找到
b, g, r
像素处理代码,追加a
处理
此后(只需更改变量名称)。
如果你熟悉patch
命令,下面是补丁文件
可以应用于:
patch -u < gauss.diff
将我以前的源代码转换为 32 位版本。
(您需要修改第一行和第二行的文件名
根据您使用的源文件名。)
gauss.diff:
-- gauss.c.O 2021-12-09 08:57:36.504685533 +0900
+++ gauss.c 2021-12-09 09:49:57.342895501 +0900
@@ -36,6 +36,7 @@
uint8_t *b;
uint8_t *g;
uint8_t *r;
+ uint8_t *a;
} BMP_Image;
double gaussianModel(double x, double y, double sigma) {
@@ -67,25 +68,28 @@
bimg->b = malloc(bimg->width * bimg->height);
bimg->g = malloc(bimg->width * bimg->height);
bimg->r = malloc(bimg->width * bimg->height);
+ bimg->a = malloc(bimg->width * bimg->height);
- int b, g, r;
+ int b, g, r, a;
double *coeff = generate_coeff(radius, sigma);
int i, j, m, n;
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width - radius; j++) {
- b = g = r = 0;
+ b = g = r = a = 0;
for (m = 0; m < radius; m++) {
for (n = 0; n < radius; n++) {
b += coeff[m * radius + n] * img->b[(i + m) * img->width + (j + n)];
g += coeff[m * radius + n] * img->g[(i + m) * img->width + (j + n)];
r += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
+ a += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
}
}
bimg->b[i * bimg->width + j] = b;
bimg->g[i * bimg->width + j] = g;
bimg->r[i * bimg->width + j] = r;
+ bimg->a[i * bimg->width + j] = a;
}
}
free(coeff);
@@ -98,13 +102,15 @@
free(img->b);
free(img->g);
free(img->r);
+ free(img->a);
free(img);
}
BMP_Image *read_bmp_file(char *filename)
{
FILE *fp;
- int i, j, bytesperline;
+// int i, j, bytesperline;
+ int i, j;
BMP_Image *img;
img = malloc(sizeof(BMP_Image));
@@ -117,21 +123,25 @@
img->width = img->header.width;
img->height = img->header.height;
- bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
+// bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
img->b = malloc(img->width * img->height);
img->g = malloc(img->width * img->height);
img->r = malloc(img->width * img->height);
+ img->a = malloc(img->width * img->height);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
img->b[i * img->width + j] = getc(fp);
img->g[i * img->width + j] = getc(fp);
img->r[i * img->width + j] = getc(fp);
+ img->a[i * img->width + j] = getc(fp);
}
+/*
for (j = img->width * 3; j < bytesperline; j++) {
getc(fp);
}
+*/
}
return img;
}
@@ -139,13 +149,14 @@
void write_bmp_file(BMP_Image *img, char *filename)
{
FILE *fp;
- int i, j, bytesperline;
+// int i, j, bytesperline;
+ int i, j;
if (NULL == (fp = fopen(filename, "w"))) {
perror(filename);
exit(1);
}
- bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
+// bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
fwrite(&img->header, sizeof(char), sizeof(BMP_Header), fp);
for (i = 0; i < img->height; i++) {
@@ -153,10 +164,13 @@
putc(img->b[i * img->width + j], fp);
putc(img->g[i * img->width + j], fp);
putc(img->r[i * img->width + j], fp);
+ putc(img->a[i * img->width + j], fp);
}
+/*
for (j = img->width * 3; j < bytesperline; j++) {
putc(0, fp);
}
+*/
}
}
我使用以下结构在内存中加载一个 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
在使索引复杂化的计算中。 - 处理颜色分量 r、g 和 b 分别.
- 变量名
variance
不合适因为variance = sigma ** 2. - 您不需要使用
1/sqrt(2*PI)/sigma
进行乘法运算 在 gaussianModel() 中因为它在归一化中被取消了。
这是一个完全可编译的代码示例:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#define SIGMA 1.94
#define RADIUS 5
#define INFILE "0Jayx.bmp"
#define OUTFILE "blurred.bmp"
// header
typedef struct __attribute__((__packed__)) {
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 width;
uint64_t height;
uint8_t *b;
uint8_t *g;
uint8_t *r;
} BMP_Image;
double gaussianModel(double x, double y, double sigma) {
return 1. / exp(-(x * x + y * y) / (2 * sigma * sigma));
}
double *generate_coeff(int radius, double sigma) {
double *coeff = malloc(sizeof(double) * radius * radius);
double sum = 0;
for (int i = 0; i < radius; i++) {
for (int j = 0; j < radius; j++) {
coeff[i * radius + j] = gaussianModel(i - radius / 2, j - radius / 2, sigma);
sum += coeff[i * radius + j];
}
}
// normalize
for (int i = 0; i < radius * radius; i++)
coeff[i] /= sum;
return coeff;
}
BMP_Image *BMP_blur_collapsed(BMP_Image *img, int radius, double sigma) {
BMP_Image *bimg = malloc(sizeof(BMP_Image));
bimg->header = img->header;
bimg->width = img->header.width;
bimg->height = img->header.height;
bimg->b = malloc(bimg->width * bimg->height);
bimg->g = malloc(bimg->width * bimg->height);
bimg->r = malloc(bimg->width * bimg->height);
int b, g, r;
double *coeff = generate_coeff(radius, sigma);
int i, j, m, n;
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width - radius; j++) {
b = g = r = 0;
for (m = 0; m < radius; m++) {
for (n = 0; n < radius; n++) {
b += coeff[m * radius + n] * img->b[(i + m) * img->width + (j + n)];
g += coeff[m * radius + n] * img->g[(i + m) * img->width + (j + n)];
r += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
}
}
bimg->b[i * bimg->width + j] = b;
bimg->g[i * bimg->width + j] = g;
bimg->r[i * bimg->width + j] = r;
}
}
free(coeff);
return bimg;
}
void free_img(BMP_Image *img)
{
free(img->b);
free(img->g);
free(img->r);
free(img);
}
BMP_Image *read_bmp_file(char *filename)
{
FILE *fp;
int i, j, bytesperline;
BMP_Image *img;
img = malloc(sizeof(BMP_Image));
if (NULL == (fp = fopen(filename, "r"))) {
perror(filename);
exit(1);
}
fread(&img->header, sizeof(char), sizeof(BMP_Header), fp);
img->width = img->header.width;
img->height = img->header.height;
bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
img->b = malloc(img->width * img->height);
img->g = malloc(img->width * img->height);
img->r = malloc(img->width * img->height);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
img->b[i * img->width + j] = getc(fp);
img->g[i * img->width + j] = getc(fp);
img->r[i * img->width + j] = getc(fp);
}
for (j = img->width * 3; j < bytesperline; j++) {
getc(fp);
}
}
return img;
}
void write_bmp_file(BMP_Image *img, char *filename)
{
FILE *fp;
int i, j, bytesperline;
if (NULL == (fp = fopen(filename, "w"))) {
perror(filename);
exit(1);
}
bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
fwrite(&img->header, sizeof(char), sizeof(BMP_Header), fp);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
putc(img->b[i * img->width + j], fp);
putc(img->g[i * img->width + j], fp);
putc(img->r[i * img->width + j], fp);
}
for (j = img->width * 3; j < bytesperline; j++) {
putc(0, fp);
}
}
}
int main()
{
BMP_Image *img = read_bmp_file(INFILE);
BMP_Image *bimg = BMP_blur_collapsed(img, RADIUS, SIGMA);
write_bmp_file(bimg, OUTFILE);
free_img(img);
free_img(bimg);
return 0;
}
生成的图像半径=5,sigma=1.94:
[编辑]
修改代码支持32位bmp文件:
- 删除
bytesperline
相关代码。 - 将
uint8_t *a;
附加到结构 BMP_Image。 - 找到
b, g, r
像素处理代码,追加a
处理 此后(只需更改变量名称)。
如果你熟悉patch
命令,下面是补丁文件
可以应用于:
patch -u < gauss.diff
将我以前的源代码转换为 32 位版本。 (您需要修改第一行和第二行的文件名 根据您使用的源文件名。)
gauss.diff:
-- gauss.c.O 2021-12-09 08:57:36.504685533 +0900
+++ gauss.c 2021-12-09 09:49:57.342895501 +0900
@@ -36,6 +36,7 @@
uint8_t *b;
uint8_t *g;
uint8_t *r;
+ uint8_t *a;
} BMP_Image;
double gaussianModel(double x, double y, double sigma) {
@@ -67,25 +68,28 @@
bimg->b = malloc(bimg->width * bimg->height);
bimg->g = malloc(bimg->width * bimg->height);
bimg->r = malloc(bimg->width * bimg->height);
+ bimg->a = malloc(bimg->width * bimg->height);
- int b, g, r;
+ int b, g, r, a;
double *coeff = generate_coeff(radius, sigma);
int i, j, m, n;
for (i = 0; i < img->height - radius; i++) {
for (j = 0; j < img->width - radius; j++) {
- b = g = r = 0;
+ b = g = r = a = 0;
for (m = 0; m < radius; m++) {
for (n = 0; n < radius; n++) {
b += coeff[m * radius + n] * img->b[(i + m) * img->width + (j + n)];
g += coeff[m * radius + n] * img->g[(i + m) * img->width + (j + n)];
r += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
+ a += coeff[m * radius + n] * img->r[(i + m) * img->width + (j + n)];
}
}
bimg->b[i * bimg->width + j] = b;
bimg->g[i * bimg->width + j] = g;
bimg->r[i * bimg->width + j] = r;
+ bimg->a[i * bimg->width + j] = a;
}
}
free(coeff);
@@ -98,13 +102,15 @@
free(img->b);
free(img->g);
free(img->r);
+ free(img->a);
free(img);
}
BMP_Image *read_bmp_file(char *filename)
{
FILE *fp;
- int i, j, bytesperline;
+// int i, j, bytesperline;
+ int i, j;
BMP_Image *img;
img = malloc(sizeof(BMP_Image));
@@ -117,21 +123,25 @@
img->width = img->header.width;
img->height = img->header.height;
- bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
+// bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
img->b = malloc(img->width * img->height);
img->g = malloc(img->width * img->height);
img->r = malloc(img->width * img->height);
+ img->a = malloc(img->width * img->height);
for (i = 0; i < img->height; i++) {
for (j = 0; j < img->width; j++) {
img->b[i * img->width + j] = getc(fp);
img->g[i * img->width + j] = getc(fp);
img->r[i * img->width + j] = getc(fp);
+ img->a[i * img->width + j] = getc(fp);
}
+/*
for (j = img->width * 3; j < bytesperline; j++) {
getc(fp);
}
+*/
}
return img;
}
@@ -139,13 +149,14 @@
void write_bmp_file(BMP_Image *img, char *filename)
{
FILE *fp;
- int i, j, bytesperline;
+// int i, j, bytesperline;
+ int i, j;
if (NULL == (fp = fopen(filename, "w"))) {
perror(filename);
exit(1);
}
- bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
+// bytesperline = ((img->width * 3 + 3) / 4) * 4; // word alignment
fwrite(&img->header, sizeof(char), sizeof(BMP_Header), fp);
for (i = 0; i < img->height; i++) {
@@ -153,10 +164,13 @@
putc(img->b[i * img->width + j], fp);
putc(img->g[i * img->width + j], fp);
putc(img->r[i * img->width + j], fp);
+ putc(img->a[i * img->width + j], fp);
}
+/*
for (j = img->width * 3; j < bytesperline; j++) {
putc(0, fp);
}
+*/
}
}