#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <conio.h>
#include <malloc.h>
#include "time.h"
#define SQRT_2PI 2.506628274631
#pragma pack(push,2)
typedef struct
{
uint16_t bfType;
uint32_t bfileSize;
uint32_t bfReserved;
uint32_t bOffBits;
uint32_t biSize;
uint32_t biWidth;
uint32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
uint32_t biXPelsPerMeter;
uint32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} bmp_header_t;
#pragma pack(pop)
typedef struct
{
bmp_header_t header;
char *data;
} bmp_t;
int win_size(double);
double Gauss(double, double);
double *GaussAlgorithm(int, double);
void bmp_free(bmp_t *);
bmp_t *bmp_open(FILE *);
int bmp_write(bmp_t*, FILE*);
bmp_t *GaussBlur(bmp_t*, double);
int main(int argc, char** argv)
{
char *InputName, *OutputName;
FILE *InputFile, *OutputFile;
bmp_t *bmp = NULL, *blur = NULL;
clock_t start, finish;
double duration;
InputName = "input.bmp"; OutputName = "output.bmp";
if (0 != fopen_s(&InputFile, InputName, "rb"))
{
printf("File not found\n");
_getch();
return 1;
}
bmp = bmp_open(InputFile);
fclose(InputFile);
OutputFile = fopen(OutputName, "wb");
if (OutputFile == NULL) {
fprintf(stderr, "Can't open %s\n", OutputName);
return EXIT_FAILURE;
}
start = clock();
blur = GaussBlur(bmp, 4.0);
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration );
bmp_write(blur, OutputFile);
fclose(OutputFile);
bmp_free(bmp);
free(blur);
getchar();
return 0;
}
bmp_t *GaussBlur(bmp_t *src, double sigma)
{
int row, col, col_r, col_g, col_b, winsize, halfsize, k, count, rows, count1, count2, count3;
int width, height;
double row_g, row_b, row_r, col_all;
unsigned char r_r, r_b, r_g, c_all;
char *tmp;
double *algorithm;
count=0;
width = 3*src->header.biWidth; height = src->header.biHeight;
if ((width % 4) != 0) width += (4 - (width % 4));
bmp_t *blur;
blur = (bmp_t*)malloc(sizeof(bmp_t));
blur->header = src->header;
blur->header.biWidth = src->header.biWidth;
blur->header.biHeight = src->header.biHeight;
blur->header.biSizeImage = width * blur->header.biHeight;
blur->data = (char*)malloc(blur->header.biSizeImage);
winsize = win_size(sigma);
algorithm = GaussAlgorithm(winsize, sigma);
winsize *= 3;
halfsize = winsize / 2;
tmp = (char*)calloc(width * height, sizeof(char));
for (row = 0; row < height; row++)
{
col_r = 0;
col_g = 1;
col_b = 2;
for (rows = 0; rows < width; rows += 3)
{
row_r = row_g = row_b = 0.0;
count1 = count2 = count3 = 0;
for (k = 1; k < winsize; k += 3)
{
if ((k + col_r - halfsize >= 0) && (k + col_r - halfsize < width))
{
r_r = *(src->data + row * width + col_r + k - halfsize);
row_r += (int)(r_r)* algorithm[count1];
count1++;
}
if ((k + col_g - halfsize >= 0) && (k + col_g - halfsize < width))
{
r_g = *(src->data + row * width + col_g + k - halfsize);
row_g += (int)(r_g)* algorithm[count2];
count2++;
}
if ((k + col_b - halfsize >= 0) && (k + col_b - halfsize < width))
{
r_b = *(src->data + row * width + col_b + k - halfsize);
row_b += (int)(r_b)* algorithm[count3];
count3++;
}
}
*(tmp + row * width + col_r) = (unsigned char)(ceil(row_r));
*(tmp + row * width + col_g) = (unsigned char)(ceil(row_g));
*(tmp + row * width + col_b) = (unsigned char)(ceil(row_b));
col_r += 3;
col_g += 3;
col_b += 3;
}
}
winsize /= 3;
halfsize = winsize / 2;
for (col = 0; col < width; col++)
for (row = 0; row < height; row++)
{
col_all = 0.0;
for (k = 0; k < winsize; k++)
if ((k + row - halfsize >= 0) && (k + row - halfsize < height))
{
c_all = *(tmp + (row + k - halfsize) * width + col);
col_all += ((int)c_all) * algorithm[k];
}
*(blur->data + row * width + col) = (unsigned char)(ceil(col_all));
}
free(tmp);
free(algorithm);
return blur;
}
double* GaussAlgorithm(int win_size, double sigma)
{
int wincenter, x;
double *kern, sum = 0.0;
wincenter = win_size / 2;
kern = (double*)calloc(win_size, sizeof(double));
for (x = 0; x < wincenter + 1; x++)
{
kern[wincenter - x] = kern[wincenter + x] = Gauss(sigma, x);
sum += kern[wincenter - x] + ((x != 0) ? kern[wincenter + x] : 0.0);
}
for (x = 0; x < win_size; x++)
kern[x] /= sum;
return kern;
}
double Gauss(double sigma, double x)
{
return exp(-(x * x) / (2.0 * sigma * sigma)) / (sigma * SQRT_2PI);
}
int win_size(double sigma)
{
return (1 + (((int)ceil(3 * sigma)) * 2));
}
bmp_t *bmp_open(FILE *f) {
bmp_t *bmp;
bmp = (bmp_t *)malloc(sizeof(bmp_t));
bmp->data = NULL;
if (fread(&(bmp->header), sizeof(bmp_header_t), 1, f)) {
bmp->data = (char*)malloc(bmp->header.biSizeImage);
if (fread(bmp->data, bmp->header.biSizeImage, 1, f))
return bmp;
}
fprintf(stderr, "Error reading file");
bmp_free(bmp);
return NULL;
}
int bmp_write(bmp_t *bmp, FILE *out) {
return fwrite(&(bmp->header), sizeof(bmp_header_t), 1, out)
&& fwrite(bmp->data, bmp->header.biSizeImage, 1, out);
}
void bmp_free(bmp_t *bmp)
{
if (bmp == NULL) return;
if (bmp->data != NULL) free(bmp->data);
free(bmp);
}
电脑配置(开发环境VS2010):
原图像:
模糊后:
图像大小(5000*3000bmp图像),模糊半径sigma=4.0(≈12*12的模糊核),从处理效果上看,模糊并没有自己想想的严重,主要是图片比较大,细节分布距离比较大的缘故。所以大图像使用大的模糊核,小图像使用小的模糊核是有道理的。
处理时间:
图像大小(1024*681)模糊半径同上
图像大小(1024*685)模糊半径同上
我一开始练习,开始慢慢练习,ㄟ(⊙ω⊙ㄟ)哈!!
可见同样的模糊半径处理较小的图片,模糊的效果会更加的明显!
本文介绍了一种基于C语言实现的高斯模糊算法,通过定义结构体和编写关键函数完成图像处理任务。该算法适用于不同尺寸的位图文件,并展示了在不同图像大小下模糊效果的变化。
7万+

被折叠的 条评论
为什么被折叠?



