1. 程式人生 > >影象資訊處理實驗六

影象資訊處理實驗六

要求:

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;
}