影象資訊處理實驗六
阿新 • • 發佈:2019-01-10
要求:
1. Astandard bilateral filter
#include <stdio.h> #include <Windows.h> #include <math.h> //線性均值濾波 void bf(char* a, char* b) { BITMAPFILEHEADER fileHeader;// 點陣圖標頭檔案 BITMAPINFOHEADER infoHeader;// 點陣圖資訊頭 FILE* pFile = fopen(a, "rb"); if (pFile == NULL) { printf("開啟檔案失敗\n"); exit(-1); } // 讀取頭資訊 fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, pFile); //讀取檔案頭 fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pFile); //讀取資訊頭 WORD bitCount = infoHeader.biBitCount;//色彩的位數 if (bitCount == 16) { exit(-1); } int Clr = 0; RGBQUAD *QUAD = NULL; if (bitCount < 16) { Clr = infoHeader.biClrUsed ? infoHeader.biClrUsed : 1 << bitCount; if (Clr>256) Clr = 0; } // 讀取調色盤 int i = 0, j = 0; if (Clr > 0) { QUAD = (RGBQUAD*)malloc(sizeof(RGBQUAD)*Clr); fread(QUAD, sizeof(RGBQUAD)*Clr, 1, pFile); for (i = 0; i < Clr; i++) { QUAD[i].rgbRed = QUAD[i].rgbBlue = QUAD[i].rgbGreen = (BYTE)(0.3 * QUAD[i].rgbRed + 0.59 * QUAD[i].rgbGreen + 0.11 * QUAD[i].rgbBlue); //灰度影象三個都是y } } LONG pW = infoHeader.biWidth; //影象資料的寬度 LONG pH = infoHeader.biHeight; //影象資料的高度 int pSize = ((pW * bitCount)>>3)*pH; //影象資料大小 BYTE* P = (BYTE*)malloc(pSize); //申請空間儲存影象資料 fread(P, pSize, 1, pFile); //存入影象資料 //先轉grey影象 if (Clr == 0) { for (i = 0; i < pH; i++)//行 { for (j = 0; j < pW*3; j = j + 3)// 列 { int n = i*pW*3 + j; P[n] = P[n + 1] = P[n + 2] = (BYTE)(0.299*P[n] + 0.587*P[n + 1] + 0.114*P[n + 2]); //分別是r,g,b分量 } } } int r=5; double sigma_d=1000,sigma_r=10; //空間函式方差,相似函式方差 double gsd_coeff=-0.5/(sigma_d*sigma_d); double gsr_coeff=-0.5/(sigma_r*sigma_r); double r_m[256]; //相似權重 double d_m[200][200]; //空間權重 //算出相似權重 for(i=0;i<256;i++){ r_m[i]=exp(i*i*gsr_coeff); } //算出空間權重 for(i=-r;i<=r;i++){ for(j=-r;j<=r;j++){ int x=j+r; int y=i+r; d_m[y][x]=exp((i*i+j*j)*gsd_coeff); } } //雙邊濾波 int k,m,n; for (i = 0; i < pH; i++)//行 { for (j = 0; j < pW; j++)// 列 { for(k = 0; k < 3; k++){ double total_w=0.0,total_p=0.0; for( m = - r;m <= r; m++) for(n = -r; n <= r; n++){ if(m * m + n * n > r * r) continue; int t_h = i + m; int t_w = j + n; t_h = t_h < 0 ? 0 : t_h; t_h = t_h > pH - 1 ? pH - 1 : t_h; t_w = t_w < 0 ? 0 : t_w; t_w = t_w > pW - 1 ? pW - 1 : t_w; int p_dif = (int)abs(P[t_h*pW*3+3*t_w+k]-P[i*3*pW+3*j+k]); double wei_t=d_m[m+r][n+r]*r_m[p_dif]; //複合權重 total_p+=P[t_h*3*pW+3*t_w+k]*wei_t; total_w+=wei_t; } total_p = total_p / total_w; P[i*3*pW+3*j+k]=(UCHAR)total_p; } } } //存在檔案中 FILE* dFile = fopen(b, "wb");//建立目標檔案 fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, dFile); //寫入檔案頭 fwrite(&infoHeader, sizeof(BITMAPINFOHEADER), 1, dFile); //寫入檔案資訊頭 if (QUAD) { fwrite(QUAD, sizeof(RGBQUAD)* Clr, 1, dFile); } //寫入影象資料 fwrite(P, pSize, 1, dFile); fclose(dFile); if (QUAD) { free(QUAD); QUAD = NULL; } if (P) { free(P); P = NULL; } } int main() { bf("b.bmp", "bfb.bmp"); return 0; }