原理:http://www.kaotop.com/file/tupian/20220430/写入gauss核进行滤波后的新图像 fp = fopen(gauss_2.bmp", "wb"); if (fp == NULL) { printf("写入失败\n"); exit(1); } fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp); fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp); for (int i = 0; i < bmpInfoHeader.biHeight; i++) { for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++) { fwrite(&grayValue[i][j], sizeof(tagRGB), 1, fp); } } fclose(fp); }
探究了下sigma_r与双边滤波结果的关系,这里取sigma=6,sigma_r分别取10,20,100
结果如图:
双边滤波的代码如下:
void bilateral_2_10(const char* filename)
{
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
FILE* fp;
if ((fp = fopen(filename, "rb")) == NULL)
{
printf("打开失败\n");
exit(1);
}
//读取图像信息
fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
RGBDATA** grayValue;
grayValue = new RGBDATA * [bmpInfoHeader.biHeight]; //声明一个指针数组
for (int i = 0; i < bmpInfoHeader.biHeight; i++)
{
grayValue[i] = new RGBDATA[(bmpInfoHeader.biWidth * 3 + 3) / 4 * 4];
}//每个数组元素也是一个指针数组
for (int i = 0; i < bmpInfoHeader.biHeight; i++)
{
for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
{
fread(&grayValue[i][j], sizeof(tagRGB), 1, fp);//存入数组
}
}
fclose(fp);
double sigma = 2.0;
int size = 3;
double sigma_1 = 10.0;
double w[3][3] = { 0 };
for (int i = 0; i < size; i++) //高斯核
{
for (int j = 0; j < size; j++)
{
w[i][j] = exp(-(pow(i - size / 2, 2) + pow(j - size / 2, 2)) / (2 * sigma * sigma));
}
}
//零填充
double** zero_fill_blue;
double** zero_fill_green;
double** zero_fill_red;
zero_fill_blue = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
zero_fill_green = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
zero_fill_red = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
for (int i = 0; i < bmpInfoHeader.biHeight + (size - 1) * 2; i++)
{
zero_fill_blue[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
zero_fill_green[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
zero_fill_red[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
}
for (int i = 0; i < bmpInfoHeader.biHeight + 2 * (size - 1); i++)
{
for (int j = 0; j < ((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + 2 * (size - 1)); j++)
{
if (i - (size - 1) >= 0 && i < bmpInfoHeader.biHeight + (size - 1) && j - (size - 1)>0 && j < ((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1)))
{
zero_fill_blue[i][j] = grayValue[i - (size - 1)][j - (size - 1)].blue;
zero_fill_green[i][j] = grayValue[i - (size - 1)][j - (size - 1)].green;
zero_fill_red[i][j] = grayValue[i - (size - 1)][j - (size - 1)].red;
}
else
{
zero_fill_blue[i][j] = 0;
zero_fill_green[i][j] = 0;
zero_fill_red[i][j] = 0;
}
}
}
double** fill_blue; //double传BYTE会丢失数据,所以建double来存数据
double** fill_green;
double** fill_red;
fill_blue = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
fill_green = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
fill_red = new double* [(bmpInfoHeader.biHeight + (size - 1) * 2)];
for (int i = 0; i < bmpInfoHeader.biHeight + (size - 1) * 2; i++)
{
fill_blue[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
fill_green[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
fill_red[i] = new double[((bmpInfoHeader.biWidth * 3 + 3) / 4 * 4 + (size - 1) * 2)];
}
for (int i = 0; i < bmpInfoHeader.biHeight; i++)
{
for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
{
fill_blue[i][j] = 0;
fill_green[i][j] = 0;
fill_red[i][j] = 0;
}
}
double sum_blue = 0;
double sum_green = 0;
double sum_red = 0;
for (int i = size/2; i < bmpInfoHeader.biHeight +size / 2; i++)
{
for (int j = size/2; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4+size/2; j++)
{
for (int a = 0; a < size; a++)
{
for (int b = 0; b < size; b++)
{
fill_blue[i - size / 2][j - size / 2] += zero_fill_blue[i + a - size / 2][j + b - size / 2] * w[a][b] * exp(-pow(zero_fill_blue[i + a - size / 2][j + b - size / 2] - zero_fill_blue[i][j], 2) / (2 * sigma_1 * sigma_1));
sum_blue += w[a][b] * exp(-pow(zero_fill_blue[i + a - size / 2][j + b - size / 2] - zero_fill_blue[i][j], 2) / (2 * sigma_1 * sigma_1));
fill_green[i - size / 2][j - size / 2] += zero_fill_green[i + a - size / 2][j + b - size / 2] * w[a][b] * exp(-pow(zero_fill_green[i + a - size / 2][j + b - size / 2] - zero_fill_green[i][j], 2) / (2 * sigma_1 * sigma_1));
sum_green += w[a][b] * exp(-pow(zero_fill_green[i + a - size / 2][j + b - size / 2] - zero_fill_green[i][j], 2) / (2 * sigma_1 * sigma_1));
fill_red[i - size / 2][j - size / 2] += zero_fill_red[i + a - size / 2][j + b - size / 2] * w[a][b] * exp(-pow(zero_fill_red[i + a - size / 2][j + b - size / 2] - zero_fill_red[i][j], 2) / (2 * sigma_1 * sigma_1));
sum_red += w[a][b] * exp(-pow(zero_fill_red[i + a - size / 2][j + b - size / 2] - zero_fill_red[i][j], 2) / (2 * sigma_1 * sigma_1));
}
}
fill_blue[i - size / 2][j - size / 2] = fill_blue[i - size / 2][j - size / 2] / sum_blue ;
fill_green[i - size / 2][j - size / 2] = fill_green[i - size / 2][j - size / 2] / sum_green ;
fill_red[i - size / 2][j - size / 2] = fill_red[i - size / 2][j - size / 2] / sum_red ;
sum_blue = 0;
sum_green = 0;
sum_red = 0;
}
}
for (int i = 0; i < bmpInfoHeader.biHeight; i++)
{
for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
{
grayValue[i][j].blue = fill_blue[i][j];
grayValue[i][j].green = fill_green[i][j];
grayValue[i][j].red = fill_red[i][j];
}
}
//写入滤波后的新图像
fp = fopen("bilateral _2.bmp", "wb");
if (fp == NULL)
{
printf("写入失败\n");
exit(1);
}
fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fwrite(&bmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);
for (int i = 0; i < bmpInfoHeader.biHeight; i++)
{
for (int j = 0; j < (bmpInfoHeader.biWidth * 3 + 3) / 4 * 4; j++)
{
fwrite(&grayValue[i][j], sizeof(tagRGB), 1, fp);
}
}
fclose(fp);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)