圖像平滑是一種區(qū)域增強(qiáng)的算法,平滑算法有鄰域平均法许赃、中指濾波、邊界保持類濾波等馆类。在圖像產(chǎn)生混聊、傳輸和復(fù)制過(guò)程中,常常會(huì)因?yàn)槎喾矫嬖蚨辉肼暩蓴_或出現(xiàn)數(shù)據(jù)丟失乾巧,降低了圖像的質(zhì)量(某一像素句喜,如果它與周圍像素點(diǎn)相比有明顯的不同,則該點(diǎn)被噪聲所感染)沟于。這就需要對(duì)圖像進(jìn)行一定的增強(qiáng)處理以減小這些缺陷帶來(lái)的影響咳胃。
? ? ? ?1.簡(jiǎn)單平滑-鄰域平均法
? ? ? ??圖像簡(jiǎn)單平滑是指通過(guò)鄰域簡(jiǎn)單平均對(duì)圖像進(jìn)行平滑處理的方法,用這種方法在一定程度上消除原始圖像中的噪聲旷太、降低原始圖像對(duì)比度的作用展懈。它利用卷積運(yùn)算對(duì)圖像鄰域的像素灰度進(jìn)行平均,從而達(dá)到減小圖像中噪聲影響供璧、降低圖像對(duì)比度的目的存崖。
? ? ? ? 但鄰域平均值主要缺點(diǎn)是在降低噪聲的同時(shí)使圖像變得模糊,特別在邊緣和細(xì)節(jié)處睡毒,而且鄰域越大来惧,在去噪能力增強(qiáng)的同時(shí)模糊程度越嚴(yán)重。
2.高斯平滑
? ? ? ??為了克服簡(jiǎn)單局部平均法的弊端(圖像模糊)演顾,目前已提出許多保持邊緣供搀、細(xì)節(jié)的局部平滑算法。它們的出發(fā)點(diǎn)都集中在如何選擇鄰域的大小偶房、形狀和方向趁曼、參數(shù)加平均及鄰域各店的權(quán)重系數(shù)等。
? ? ? ? 圖像高斯平滑也是鄰域平均的思想對(duì)圖像進(jìn)行平滑的一種方法棕洋,在圖像高斯平滑中挡闰,對(duì)圖像進(jìn)行平均時(shí),不同位置的像素被賦予了不同的權(quán)重。
? ? ? ? 在圖像簡(jiǎn)單平滑中摄悯,算法利用卷積模板逐一處理圖像中每個(gè)像素赞季,這一過(guò)程可以形象地比作對(duì)原始圖像的像素一一進(jìn)行過(guò)濾整理,在圖像處理中把鄰域像素逐一處理的算法過(guò)程稱為濾波器奢驯。平滑線性濾波器的工作原理是利用模板對(duì)鄰域內(nèi)像素灰度進(jìn)行加權(quán)平均申钩,也稱為均值濾波器。
? ? ? ? 高斯平滑與簡(jiǎn)單平滑不同瘪阁,它在對(duì)鄰域內(nèi)像素進(jìn)行平均時(shí)撒遣,給予不同位置的像素不同的權(quán)值,下圖的所示的3*3和5*5領(lǐng)域的高斯模板管跺。
?模板越靠近鄰域中心位置义黎,其權(quán)值越高。在圖像細(xì)節(jié)進(jìn)行模糊時(shí)豁跑,可以更多的保留圖像總體的灰度分布特征廉涕。下圖是常用的四個(gè)模板和matlab代碼實(shí)現(xiàn):?
? 代碼如下:
I1?=?imread('blood1.tif');??
I=imnoise(I1,‘salt?&?pepper’,0.04);????????????????%對(duì)圖像加椒鹽噪聲??
imshow(I);??
h1=?[0.1?0.1?0.1;?0.1?0.2?0.1;?0.1?0.1?0.1];????????%定義4種模板??
h2=1/16.*[1?2?1;2?4?2;1?2?1];??
h3=1/8.*[1?1?1;1?0?1;1?1?1];??
h4=1/2.*[0?1/4?0;1/4?1?1/4;0?1/4?0];??
I2=filter2(h1,I);???????????????????????????????????%用4種模板進(jìn)行濾波處理??
I3=filter2(h2,I);??
I4=filter2(h3,I);??
I5=filter2(h4,I);??
figure,imshow(I2,[])????????????????????????????????%顯示處理結(jié)果??
figure,imshow(I3,[])??
figure,imshow(I4,[])??
figure,imshow(I5,[])??
3.中值濾波
? ? ? ??在使用鄰域平均法去噪的同時(shí)也使得邊界變得模糊。而中值濾波是非線性的圖像處理方法艇拍,在去噪的同時(shí)可以兼顧到邊界信息的保留狐蜕。
? ? ? ? 選一個(gè)含有奇數(shù)點(diǎn)的窗口W,將這個(gè)窗口在圖像上掃描卸夕,把窗口中所含的像素點(diǎn)按灰度級(jí)的升或降序排列层释,取位于中間的灰度值來(lái)代替該點(diǎn)的灰度值。
常用的窗口還有方形快集、十字形湃累、圓形和環(huán)形。不同形狀的窗口產(chǎn)生不同的濾波效果碍讨,方形和圓形窗口適合外輪廓線較長(zhǎng)的物體圖像,而十字形窗口對(duì)有尖頂角狀的圖像效果好蒙秒。
中值濾波對(duì)于消除孤立點(diǎn)和線段的干擾十分有用勃黍,尤其是對(duì)于二進(jìn)噪聲,但對(duì)消除高斯噪聲的影響效果不佳晕讲。對(duì)于一些細(xì)節(jié)較多的復(fù)雜圖像覆获,可以多次使用不同的中值濾波。matlab實(shí)現(xiàn)參考:http://blog.csdn.net/timidsmile/article/details/6904381
? ? ? ??4.邊界保持類濾波
? ? ? ? K近鄰均值濾波器(KNNF)是指在m*m的窗口中瓢省,屬于同一集合類的像素弄息,它們的灰度值將高度相關(guān)。被處理的像素(對(duì)應(yīng)于窗口中心的像素)可以用窗口內(nèi)與中心像素灰度最接近的k個(gè)近鄰像素的平均灰度來(lái)替代勤婚。步驟如下:
? ? ? ? (1).作一個(gè)m*m的作用模板
? ? ? ? (2).在其中選擇K個(gè)與待處理像素的灰度差為最小的像素
? ? ? ? (3).用這K個(gè)像素的灰度均值替換掉原來(lái)的值
在K近旁均值濾波器(KNNMF)中摹量,不選K個(gè)鄰近像素的平均灰度來(lái)替代,而選K個(gè)鄰近像素的中值灰度來(lái)替代,上圖中2,3,3中選擇3即可缨称。
? ? ? ? 下面介紹具體MFC VC++6.0代碼實(shí)現(xiàn)過(guò)程凝果。
三. 圖像平滑代碼實(shí)現(xiàn)
? ? ? ? 第一步:在資源視圖的Menu中添加子菜單“圖像增強(qiáng)”,然后添加“圖像平滑”四個(gè)選項(xiàng)如下圖所示:
第二步:打開(kāi)類向?qū)谰。贗mageProcessingView類中添加相應(yīng)的四個(gè)實(shí)現(xiàn)函數(shù):
?第三步:就是具體的平滑實(shí)現(xiàn)函數(shù)器净。
1.普通平滑 模板一
該算法采用的模板如下:
代碼如下:
void CImageProcessingView::OnTxzqptph()
{
// TODO: 在此添加命令處理程序代碼
if (numPicture == 0)
{
AfxMessageBox("請(qǐng)輸入一張圖片", MB_OK, 0);
return;
}
AfxMessageBox("普通平滑,均值平滑", MB_OK, 0);
float H1[3][3] = {
{0.1,0.1,0.1},
{0.1,0.2,0.1},
{0.1,0.1,0.1}
};
int HWS = 3;
FILE *fpo = fopen(BmpName, "rb");
FILE *fpw = fopen(BmpNameLin, "wb+");
fread(&bfh, sizeof(BITMAPFILEHEADER), 1, fpo);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, fpo);
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fpw);
fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fpw);
fread(m_pImage, m_nImage, 1, fpo);
unsigned char *ImageSize;//動(dòng)態(tài)內(nèi)存的分配和釋放
ImageSize = new unsigned char[m_nImage];
float red, green, blue;
int x=0, y=0;//代表寬和高的位置
int LR, LG, LB;//記錄實(shí)際的位置
int xx, yy;
int num;//記錄需要填充的字節(jié)当凡,因?yàn)锽MP掃描行字節(jié)必須是4的倍數(shù)山害,比如一個(gè)像素是3字節(jié),實(shí)際需要補(bǔ)1個(gè)字節(jié)
if (m_nWidth * 3 % 4 != 0)
{
num = 4 - m_nWidth * 3 % 4;
}
else if (m_nWidth * 3 % 4 == 0)
{
num = 0;
}
for (x = HWS/2; x < m_nWidth-HWS/2; x++)//這邊我默認(rèn)原圖像邊界一個(gè)像素不處理沿量,也就是直接給0了浪慌,x代表原圖第列
{
for (y = HWS / 2; y < m_nHeight- HWS / 2; y++)//y代表第幾行
{
red = green = blue = 0;
LR = (x + y*m_nWidth) * 3 + y*num;//之所以要加num*y,還是因?yàn)閽呙栊械膯?wèn)題
//LG = (x + y*m_nWidth) * 3 + 1;
//LB = (x + y*m_nWidth) * 3 + 2;
for (int j = 0; j < HWS; j++)//第幾行
{
yy = y + j - 1;
for (int i = 0; i < HWS; i++)//第幾列
{
xx = x + i - 1;
red += H1[j][i] * (float)(m_pImage[(xx + yy*m_nWidth) * 3 + yy*num]);
green += H1[j][i] * (float)(m_pImage[(xx + yy*m_nWidth) * 3 + 1+ yy*num]);
blue+= H1[j][i] * (float)(m_pImage[(xx + yy*m_nWidth) * 3 + 2 + yy*num]);
}
}
ImageSize[LR] = (unsigned char)(red);
ImageSize[LR + 1] = (unsigned char)(green);
ImageSize[LR + 2] = (unsigned char)(blue);
}
}
fwrite(ImageSize, m_nImage, 1, fpw);
/*fwrite(ImageSize, m_nImage, 1, fpw);*/
fclose(fpo);
fclose(fpw);
numPicture = 2;
level = 400;
Invalidate();
}
3.高斯平滑
? ? ? ? ?采用的模板如下:
代碼如下圖所示:
void CImageProcessingView::OnGsph()
{
// TODO: 在此添加命令處理程序代碼
if (numPicture == 0)
{
AfxMessageBox("請(qǐng)輸入一張圖片", MB_OK, 0);
return;
}
AfxMessageBox("普通平滑欧瘪,均值平滑", MB_OK, 0);
float H1[3][3] = {
{ 1.0 / 16,2.0 / 16,1.0 / 16 }, //模板二:系數(shù)1/16
{ 2.0 / 16,4.0 / 16,2.0 / 16 },
{ 1.0 / 16,2.0 / 16,1.0 / 16 } };
int HWS = 3;
FILE *fpo = fopen(BmpName, "rb");
FILE *fpw = fopen(BmpNameLin, "wb+");
fread(&bfh, sizeof(BITMAPFILEHEADER), 1, fpo);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, fpo);
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fpw);
fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fpw);
fread(m_pImage, m_nImage, 1, fpo);
unsigned char *ImageSize;
ImageSize = new unsigned char[m_nImage];//new可以有效的內(nèi)存釋放
float red, green, blue;
int x = 0, y = 0;//代表寬和高的位置
int LR, LG, LB;//記錄實(shí)際的位置
int xx, yy;
int num;//記錄需要填充的字節(jié)
if (m_nWidth * 3 % 4 != 0)
{
num = 4 - m_nWidth * 3 % 4;
}
else if (m_nWidth * 3 % 4 == 0)
{
num = 0;
}
for (x = 0, y = 0; x < m_nWidth; x++)
{
LR = (x + y*m_nWidth) * 3;
ImageSize[LR++] = 0;
ImageSize[LR++] = 0;
ImageSize[LR++] = 0;
}
for (x = 0, y = 0; y < m_nHeight; y++)
{
LR = (x + y*m_nWidth) * 3;
ImageSize[LR++] = 0;
ImageSize[LR++] = 0;
ImageSize[LR++] = 0;
}
for (x = HWS / 2; x < m_nWidth - HWS / 2; x++)
{
for (y = HWS / 2; y < m_nHeight - HWS / 2; y++)
{
red = green = blue = 0;
LR = (x + y*m_nWidth) * 3 + y*num;
//LG = (x + y*m_nWidth) * 3 + 1;
//LB = (x + y*m_nWidth) * 3 + 2;
for (int j = 0; j < HWS; j++)//第幾行
{
yy = y + j - 1;
for (int i = 0; i < HWS; i++)//第幾列
{
xx = x + i - 1;
red += H1[j][i] * (float)(m_pImage[(xx + yy*m_nWidth) * 3 + yy * num]);
green += H1[j][i] * (float)(m_pImage[(xx + yy*m_nWidth) * 3 + 1 + yy * num]);
blue += H1[j][i] * (float)(m_pImage[(xx + yy*m_nWidth) * 3 + 2 + yy * num]);
}
}
ImageSize[LR] = (unsigned char)(red);
ImageSize[LR + 1] = (unsigned char)(green);
ImageSize[LR + 2] = (unsigned char)(blue);
}
}
fwrite(ImageSize, m_nImage, 1, fpw);
/*fwrite(ImageSize, m_nImage, 1, fpw);*/
fclose(fpo);
fclose(fpw);
numPicture = 2;
level = 400;
Invalidate();
}
運(yùn)行結(jié)果如下所示眷射,可以清楚看出斜線沒(méi)了上面是有斜線的,下面是沒(méi)有斜線的
4.中值濾波
? ? ? ? 中值濾波我的理解是:它不但可以去除孤點(diǎn)噪聲佛掖,而且可以保持圖像的邊緣特性妖碉,不會(huì)產(chǎn)生顯著的模糊;它的方法是把局部區(qū)域的像素按灰度等級(jí)進(jìn)行排序芥被,再取該鄰域中灰度的中值作為當(dāng)前像素的灰度值欧宜。其步驟如下:
? ? ? ? ?(1).將濾波模板(含若干個(gè)點(diǎn)的滑動(dòng)窗口)在圖像中漫游,并將模板中心與圖像中的某個(gè)像素位置重合拴魄;
? ? ? ? (2).讀取模板中各對(duì)應(yīng)像素的灰度值冗茸;
? ? ? ? (3).將這些灰度值從小到大排序;
? ? ? ? (4).取這一列數(shù)據(jù)的中間數(shù)據(jù)匹中,將其賦值給對(duì)應(yīng)模板中心位置的像素夏漱。
? ? ? ? 我采用的是3*3的模本,取矩陣中間位置像素替代原像素顶捷。代碼如下:
void CImageProcessingView::OnZzlb()
{
// TODO: 在此添加命令處理程序代碼
if (numPicture == 0)
{
AfxMessageBox("請(qǐng)輸入一張圖片", MB_OK, 0);
return;
}
AfxMessageBox("中值濾波", MB_OK, 0);
FILE *fpo = fopen(BmpName, "rb");
FILE *fpw = fopen(BmpNameLin, "wb+");
fread(&bfh, sizeof(BITMAPFILEHEADER), 1, fpo);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, fpo);
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fpw);
fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fpw);
fread(m_pImage, m_nImage, 1, fpo);
unsigned char *ImageSize;
ImageSize = new unsigned char[m_nImage];
int HR[9] = { 0 };
int HG[9] = { 0 };
int HB[9] = { 0 };
int x, y,xx,yy;
int HWS = 3;
int LR;
int num;//記錄需要填充的字節(jié)
if (m_nWidth * 3 % 4 != 0)
{
num = 4 - m_nWidth * 3 % 4;
}
else if (m_nWidth * 3 % 4 == 0)
{
num = 0;
}
for (x = HWS / 2; x <? m_nWidth - HWS / 2; x++)
{
for (y = HWS / 2; y < m_nHeight - HWS / 2; y++)
{
LR = (x + y*m_nWidth) * 3 + y*num;
int number = 0;
for (int j = 0; j < HWS; j++)
{
yy = y + j - 1;
for (int i = 0; i < HWS; i++)
{
xx = x + i - 1;
HR[number] = m_pImage[(xx + yy*m_nWidth)*3 + yy*num];
HG[number] = m_pImage[(xx + yy*m_nWidth) * 3 + 1 + yy*num];
HB[number] = m_pImage[(xx + yy*m_nWidth) * 3 + 2 + yy*num];
number++;
}
}
bubbleSort(HR, 9);//對(duì)RGB三個(gè)顏色通道排序
bubbleSort(HG, 9);
bubbleSort(HB, 9);
ImageSize[LR] = HR[4];//這里我沒(méi)有嚴(yán)格按照中值的定義挂绰,但是書上寫的是H4
ImageSize[LR+1] = HG[4];
ImageSize[LR+2] = HB[4];
}
}
fwrite(ImageSize, m_nImage, 1, fpw);
fclose(fpo);
fclose(fpw);
numPicture = 2;
level = 400;
Invalidate();
}
四. 圖像銳化
? ? ? ?有時(shí)還需要加強(qiáng)圖像中景物的邊緣和輪廓,邊緣和輪廓通常位于圖像中灰度突出的地方服赎,因而可以直觀的想到用灰度的差分對(duì)邊緣和輪廓進(jìn)行提取葵蒂,通常可以通過(guò)梯度算子進(jìn)行提取重虑。圖像銳化的目的是提高圖像的對(duì)比度践付,從而使圖像更清晰,通過(guò)提高鄰域內(nèi)像素的灰度差來(lái)提高圖像的對(duì)比度缺厉。
? ? ? ?下面介紹圖像銳化的幾種算子及效果永高。
? ? ? ??1.拉普拉斯算子(Laplacian)
? ? ? ? 拉普拉斯算子是圖像鄰域內(nèi)像素灰度差分計(jì)算的基礎(chǔ)隧土,通過(guò)二階微分推導(dǎo)出的一種圖像鄰域增強(qiáng)算法。它的基本思想是當(dāng)鄰域的中心像素灰度低于它所在鄰域內(nèi)的其他像素的平均灰度時(shí)乏梁,此中心像素的灰度應(yīng)該被進(jìn)一步降低次洼;當(dāng)高于時(shí)進(jìn)一步提高中心像素的灰度,從而實(shí)現(xiàn)圖像銳化處理遇骑。
? ? ? ? 在算法實(shí)現(xiàn)過(guò)程中卖毁,通過(guò)對(duì)鄰域中心像素的四方向或八方向求梯度,并將梯度和相加來(lái)判斷中心像素灰度與鄰域內(nèi)其他像素灰度的關(guān)系落萎,并用梯度運(yùn)算的結(jié)果對(duì)像素灰度進(jìn)行調(diào)整亥啦。
? ? ? ? 一個(gè)連續(xù)的二元函數(shù)f(x,y),其拉普拉斯運(yùn)算定義為:
?對(duì)于數(shù)字圖像练链,拉普拉斯算子可以簡(jiǎn)化為:
? ? ? ? 也可以表示為卷積的形式:
其中K=1措伐,I=1時(shí)H(r,s)取下式钝腺,四方向模板:
通過(guò)模板可以發(fā)現(xiàn),當(dāng)鄰域內(nèi)像素灰度相同時(shí),模板的卷積運(yùn)算結(jié)果為0吗货;當(dāng)中心像素灰度高于鄰域內(nèi)其他像素的平均灰度時(shí)维雇,模板的卷積運(yùn)算結(jié)果為正數(shù)肥橙;當(dāng)中心像素的灰度低于鄰域內(nèi)其他像素的平均灰度時(shí)栽燕,模板的卷積為負(fù)數(shù)。對(duì)卷積運(yùn)算的結(jié)果用適當(dāng)?shù)乃ト跻蜃犹幚聿⒓釉谠行南袼厣铣蹦#涂梢詫?shí)現(xiàn)圖像的銳化處理亮蛔。
? ? ? ? 其中實(shí)現(xiàn)過(guò)程步驟如下:
? ? ? ? 添加子菜單和類向?qū)砑訉?shí)現(xiàn)函數(shù)
代碼如下:
void CImageProcessingView::OnLp()
{
// TODO: 在此添加命令處理程序代碼
if (numPicture == 0)
{
AfxMessageBox("請(qǐng)輸入一張圖像", MB_OK, 0);
return;
}
AfxMessageBox("拉布拉斯變換", MB_OK, 0);
int H1[3][3] = {
{ 0,-1,0}, //模板二:
{ -1,4,-1},
{ 0,-1,0 } };
int HWS = 3;
FILE *fpo = fopen(BmpName, "rb");
FILE *fpw = fopen(BmpNameLin, "wb+");
fread(&bfh, sizeof(BITMAPFILEHEADER), 1, fpo);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, fpo);
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fpw);
fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fpw);
fread(m_pImage, m_nImage, 1, fpo);
unsigned char *ImageSize;
ImageSize = new unsigned char[m_nImage];
int red, green, blue;
int x = 0, y = 0;//代表寬和高的位置
int LR, LG, LB;//記錄實(shí)際的位置
int xx, yy;
int num;//記錄需要填充的字節(jié)
if (m_nWidth * 3 % 4 != 0)
{
num = 4 - m_nWidth * 3 % 4;
}
else if (m_nWidth * 3 % 4 == 0)
{
num = 0;
}
for (x = HWS / 2; x < m_nWidth - HWS / 2; x++)
{
for (y = HWS / 2; y < m_nHeight - HWS / 2; y++)
{
red = green = blue = 0;
LR = (x + y*m_nWidth) * 3 + y*num;
//LG = (x + y*m_nWidth) * 3 + 1;
//LB = (x + y*m_nWidth) * 3 + 2;
for (int j = 0; j < HWS; j++)//第幾行這兩個(gè)循環(huán)是求權(quán)重后的均值
{
yy = y + j - 1;
for (int i = 0; i < HWS; i++)//第幾列
{
xx = x + i - 1;
red += H1[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + yy*num]);
green += H1[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + 1 + yy*num]);
blue += H1[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + 2 + yy*num]);
}
}
if (red < 0 || red >= 256) red = 0;
ImageSize[LR] = (unsigned char)(red);
if (green < 0 || green >= 256) green= 0;
ImageSize[LR + 1] = (unsigned char)(green);
if (blue < 0 || blue >= 256) blue = 0;
ImageSize[LR + 2] = (unsigned char)(blue);
}
}
fwrite(ImageSize, m_nImage, 1, fpw);
fclose(fpo);
fclose(fpw);
numPicture = 2;
level = 400;
Invalidate();
}
? 運(yùn)行效果如下圖所示:
??2.高通濾波?
? ? ? ? 常用的高通模板如下所示,其中H2有的書又稱為拉普拉斯八方向的銳化模板擎厢。?
?3.Sobel算子
代碼如下所示究流,需要注意X和Y兩個(gè)方向的模板處理:
void CImageProcessingView::OnSobel()
{
// TODO: 在此添加命令處理程序代碼
if (numPicture == 0)
{
AfxMessageBox("Plaece Enter a picture!", MB_OK, 0);
return;
}
AfxMessageBox("Sobel in sessing", MB_OK, 0);
int HX[3][3] = {{-1,-2,-1},{0,0,0,},{1,2,1}};
int HY[3][3] = { {-1,0,1},{-2,0,2},{-1,0,1} };
int HWS = 3;
int num;//記錄需要填充的字節(jié)
if (m_nWidth * 3 % 4 != 0)
{
num = 4 - m_nWidth * 3 % 4;
}
else if (m_nWidth * 3 % 4 == 0)
{
num = 0;
}
FILE *fpo = fopen(BmpName, "rb");
FILE *fpw = fopen(BmpNameLin, "wb+");
fread(&bfh, sizeof(BITMAPFILEHEADER), 1, fpo);
fread(&bih, sizeof(BITMAPINFOHEADER), 1, fpo);
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, fpw);
fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, fpw);
fread(m_pImage, m_nImage, 1, fpo);
unsigned char *ImageSize;
ImageSize = new unsigned char[m_nImage];
int x, y,xx,yy;
int redX, greenX, blueX;
int redY, greenY, blueY;
int R, G, B;
int LR;
unsigned char other = 0;? ? ? ? //補(bǔ)碼00H='\0'?
for (x = HWS / 2; x < m_nWidth - HWS / 2; x++)
{
for (y = HWS / 2; y < m_nHeight - HWS / 2; y++)
{
redX = greenX = blueX = 0;
redY = greenY = blueY = 0;
LR = (y*m_nWidth + x)*3 + y*num;
for (int j = 0; j < HWS; j++)//第幾行這兩個(gè)循環(huán)是求權(quán)重后的均值
{
yy = y + j - 1;
for (int i = 0; i < HWS; i++)//第幾列
{
xx = x + i - 1;
redX += HX[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + yy*num]);
greenX += HX[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + 1 + yy*num]);
blueX += HX[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + 2 + yy*num]);
redY += HY[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + yy*num]);
greenY += HY[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + 1 + yy*num]);
blueY += HY[j][i] * (m_pImage[(xx + yy*m_nWidth) * 3 + 2 + yy*num]);
}
}
R = (int)sqrt(redX*redX*1.0 + redY*redY*1.0);
G = (int)sqrt(greenX*greenX*1.0 + greenY*greenY*1.0);
B = (int)sqrt(blueX*blueX*1.0 + blueY*blueY*1.0);
if (R > 255) R = 255;
ImageSize[LR] = unsigned char(R);
if (G > 255)G = 255;
ImageSize[LR+1] = unsigned char(G);
if (B > 255)B = 255;
ImageSize[LR+2] = unsigned char(B);
}
}
fwrite(ImageSize, m_nImage, 1, fpw);
fclose(fpo);
fclose(fpw);
numPicture = 2;
level = 401;
Invalidate();
}
?4.Isotropic算子
5.?Prewitt算子