/*****************************************************************************
* 函式名稱: cvOtsu2D()
* 函式引數: CvMat* pGrayMat:灰度圖形相對應的矩陣
* 回傳值: int nThreshold
* 函式說明:實作灰度圖的二值化分割——最大類間方差法(二維Otsu演算法)
* 備注:在構建二維直方圖的時候,采用灰度點的3*3鄰域均值
******************************************************************************/
int cvOtsu2D(CvMat *pGrayMat)
{
double dHistogram[256][256]; //建立二維灰度直方圖
double dTrMatrix = 0.0; //離散矩陣的跡
int height = pGrayMat->rows;
int width = pGrayMat->cols;
int N = height*width; //總像素數
int i, j;
for(i = 0; i < 256; i++)
{
for(j = 0; j < 256; j++)
dHistogram[i][j] = 0.0; //初始化變數
}
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
unsigned char nData1 = (unsigned char)cvGetReal2D(pGrayMat, i, j);//當前的灰度值
unsigned char nData2 = 0;
int nData3 = 0;//注意9個值相加可能超過一個位元組
for(int m = i-1; m <= i+1; m++)
{
for(int n = j-1; n <= j+1; n++)
{
if((m >= 0) && (m < height) && (n >= 0) && (n < width))
nData3 += (unsigned char)cvGetReal2D(pGrayMat, m, n); //當前的灰度值
}
}
nData2 = (unsigned char)(nData3 / 9); //對于越界的索引值進行補零,鄰域均值
dHistogram[nData1][nData2]++;
}
}
for(i = 0; i < 256; i++)
for(j = 0; j < 256; j++)
dHistogram[i][j] /= N; //得到歸一化的概率分布
double Pai = 0.0; //目標區均值矢量i分量
double Paj = 0.0; //目標區均值矢量j分量
double Pbi = 0.0; //背景區均值矢量i分量
double Pbj = 0.0; //背景區均值矢量j分量
double Pti = 0.0; //全域均值矢量i分量
double Ptj = 0.0; //全域均值矢量j分量
double W0 = 0.0; //目標區的聯合概率密度
double W1 = 0.0; //背景區的聯合概率密度
double dData1 = 0.0;
double dData2 = 0.0;
double dData3 = 0.0;
double dData4 = 0.0; //中間變數
int nThreshold_s = 0;
int nThreshold_t = 0;
double temp = 0.0; //尋求最大值
for(i = 0; i < 256; i++)
{
for(j = 0; j < 256; j++)
{
Pti += i*dHistogram[i][j];
Ptj += j*dHistogram[i][j];
}
}
for(i = 0; i < 256; i++)
{
for(j = 0; j < 256; j++)
{
W0 += dHistogram[i][j];
dData1 += i*dHistogram[i][j];
dData2 += j*dHistogram[i][j];
W1 = 1-W0;
dData3 = Pti-dData1;
dData4 = Ptj-dData2;
Pai = dData1 / W0;
Paj = dData2 / W0;
Pbi = dData3 / W1;
Pbj = dData4 / W1; // 得到兩個均值向量,用4個分量表示
dTrMatrix = ((W0 * Pti - dData1) * (W0 * Pti - dData1) + (W0 * Ptj - dData2) * (W0 * Ptj- dData2)) / (W0 * W1);
if(dTrMatrix > temp)
{
temp = dTrMatrix;
nThreshold_s = i;
nThreshold_t = j;
}
}
}
nThreshold = (nThreshold_s + nThreshold_t) / 2;//回傳閾值,有多種形式,可以單獨某一個,也可 //是兩者的均值
return nThreshold;
}
int main( )
{
IplImage *img = cvLoadImage("C:\\Miss.bmp", 0);//加載圖片
cvNamedWindow("Miss", CV_WINDOW_AUTOSIZE);//創建顯示視窗
cvShowImage("Miss", img);//顯示圖片
cvNamedWindow("二維Otsu", CV_WINDOW_AUTOSIZE);
CvMat *imgMat = cvCreateMat(img->height, img->width, CV_8UC1);//創建矩陣,其type為CV_8UC1
cvConvert(img, imgMat);//將影像轉換成矩陣形式
int t = cvOtsu2D(imgMat);//求二維閾值分割的閾值
cvThreshold(img, img, t, 255, CV_THRESH_BINARY);//用求得的閾值分割影像
cvShowImage("二維Otsu", img);
cvWaitKey(0);//保持影像的顯示視窗
cvReleaseImage(&img);//釋放影像資源
cvReleaseMat(&imgMat);//釋放矩陣資源
cvDestroyAllWindows();//銷毀視窗
return 0;
}
uj5u.com熱心網友回復:
還沒看代碼 但看了下 效果 和 一維對比,果真好很多的樣紙
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/140573.html
標籤:基礎類
下一篇:win7下的滑鼠鍵盤鎖定
