灰度影象二值化-----c++實現
阿新 • • 發佈:2018-12-31
前天閒著沒事幹,就寫了寫BMP影象處理,感覺大家還比較感興趣。。所以現在沒事,繼續更新。。這次簡單的寫了灰度影象二值化。。這是什麼概念呢?
影象的二值化的基本原理
影象的二值化處理就是將影象上的點的灰度置為0或255,也就是講整個影象呈現出明顯的黑白效果。即將256個亮度等級的灰度影象通過適當的閥值選取而獲得仍然可以反映影象整體和區域性特徵的二值化影象。在數字影象處理中,二值影象佔有非常重要的地位,特別是在實用的影象處理中,以二值影象處理實現而構成的系統是很多的,要進行二值影象的處理與分析,首先要把灰度影象二值化,得到二值化影象,這樣子有利於再對影象做進一步處理時,影象的集合性質只與畫素值為0或255的點的位置有關,不再涉及畫素的多級值,使處理變得簡單,而且資料的處理和壓縮量小。為了得到理想的二值影象,一般採用封閉、連通的邊界定義不交疊的區域。所有灰度大於或等於閥值的畫素被判定為屬於特定物體,其灰度值為255表示,否則這些畫素點被排除在物體區域以外,灰度值為0,表示背景或者例外的物體區域。如果某特定物體在內部有均勻一致的灰度值,並且其處在一個具有其他等級灰度值的均勻背景下,使用閥值法就可以得到比較的分割效果。如果物體同背景的差別表現不在灰度值上(比如紋理不同),可以將這個差別特徵轉換為灰度的差別,然後利用閥值選取技術來分割該影象。動態調節閥值實現影象的二值化可動態觀察其分割影象的具體結果。
相信大家看到這裡應該覺得很簡單吧。。二值化就是把原來灰度影象中每個畫素的值要麼變成255(白色),要麼變為0(黑色)。(
程式碼:
#include<iostream> #include <Windows.h> using namespace std; void main() { int threshold=200; FILE* stream=fopen("D:\\6.bmp","rb"); if(stream==NULL) { cout<<"檔案不存在"<<endl; return; } int sizeFileHeader=sizeof(BITMAPFILEHEADER); int sizeInfoHeader=sizeof(BITMAPINFOHEADER); BITMAPFILEHEADER* bitmapFileHeader=new BITMAPFILEHEADER[sizeFileHeader+1]; BITMAPINFOHEADER* bitmapInfoHeader=new BITMAPINFOHEADER[sizeInfoHeader+1]; memset(bitmapFileHeader,0,sizeFileHeader+1); memset(bitmapInfoHeader,0,sizeInfoHeader+1); fread(bitmapFileHeader,sizeof(char),sizeFileHeader,stream); fseek(stream,sizeFileHeader,0); fread(bitmapInfoHeader,sizeof(char),sizeInfoHeader,stream); fseek(stream,sizeInfoHeader+sizeFileHeader,0); RGBQUAD* pRgbQuards=new RGBQUAD[256]; for (int k=0;k<256;k++) { fread(&pRgbQuards[k],sizeof(RGBQUAD),1,stream); } int count=(((bitmapInfoHeader->biWidth)*8+31)/32)*4-bitmapInfoHeader->biWidth*(bitmapInfoHeader->biBitCount/8); BYTE* tempData=new BYTE[count+1]; memset(tempData,0,count+1); fseek(stream,sizeFileHeader+sizeInfoHeader+256*sizeof(RGBQUAD),0); BYTE** data=new BYTE*[bitmapInfoHeader->biHeight]; for(int i=0;i<bitmapInfoHeader->biHeight;i++) { data[i]=new BYTE[bitmapInfoHeader->biWidth]; for (int j=0;j<bitmapInfoHeader->biWidth;j++) { fread(&data[i][j],sizeof(char),1,stream); if(data[i][j]>threshold) data[i][j]=255; else data[i][j]=0; } for (int n=0;n<count;n++) { fread(&tempData[n],sizeof(char),1,stream); } } fclose(stream); //寫入。。 FILE* fileWrite=fopen("D:\\9.bmp","a+"); fwrite(bitmapFileHeader,sizeof(char),sizeof(BITMAPFILEHEADER),fileWrite); fwrite(bitmapInfoHeader,sizeof(char),sizeof(BITMAPINFOHEADER),fileWrite); fwrite(pRgbQuards,sizeof(RGBQUAD),256,fileWrite); for(int i=0;i<bitmapInfoHeader->biHeight;i++) { for(int j=0;j<bitmapInfoHeader->biWidth;j++) { fwrite(&data[i][j],sizeof(BYTE),1,fileWrite); } for(int m=0;m<count;m++) fwrite(&tempData[m],sizeof(char),1,fileWrite); } fclose(fileWrite); cout<<"success"<<endl; }
這裡我就不解釋了。看了前幾篇文章肯定覺的very easy....
效果:
原圖:
二值圖:
MY QUESTION:上面說了二值化就是變成二值化影象,而我在網上查了資料說二值化影象畫素的大小是1位,這就和上面說的不符合了,應該上面介紹的是還是8位。所以我就有些不懂了。。希望大神可以給我解釋解釋....