📄 threshold.cpp
字号:
// Threshold.cpp : implementation file
//
#include "stdafx.h"
#include "photostar.h"
#include "Threshold.h"
#include <afxtempl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CThreshold dialog
CThreshold::CThreshold(CWnd* pParent /*=NULL*/)
: CDialog(CThreshold::IDD, pParent)
{
//{{AFX_DATA_INIT(CThreshold)
m_thresholdvalue = 0;
//}}AFX_DATA_INIT
}
void CThreshold::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CThreshold)
DDX_Text(pDX, IDC_EDIT1, m_thresholdvalue);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CThreshold, CDialog)
//{{AFX_MSG_MAP(CThreshold)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CThreshold message handlers
BOOL CThreshold::OnManualThreshold()
{
if (m_pImageObject == NULL)
{
return FALSE;
}
int iWidth = m_pImageObject->GetWidth();
int iHeight = m_pImageObject->GetHeight();
int iNumBits=m_pImageObject->GetNumBits();
/******************************the old image*****************************/
unsigned char *pOldBuffer, *pNewBuffer, *pOldBits, *pNewBits;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
RGBQUAD *pOldPalette, *pNewPalette;
int nWidthBytes, nNumColors;
pOldBuffer = (unsigned char *) m_pImageObject->GetDIBPointer(&nWidthBytes, m_pImageObject->GetNumBits());
if (pOldBuffer == NULL)
{
return FALSE;
}
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
nNumColors = m_pImageObject->GetNumColors();
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
/*****************************the new image*****************************/
DWORD dwNewSize;
HGLOBAL hNewDib;
//Allocate a global memory block for the new image
dwNewSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)
+ nWidthBytes * (m_pImageObject->GetHeight());
hNewDib = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize);
if (hNewDib == NULL)
{
m_pImageObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock(m_pImageObject->GetDib());
return FALSE;
}
//Get the pointer to the new memory block
pNewBuffer = (unsigned char *) ::GlobalLock(hNewDib);
if (pNewBuffer == NULL)
{
::GlobalFree( hNewDib );
m_pImageObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock(m_pImageObject->GetDib());
return FALSE;
}
pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
//Make a copy of the old image
memcpy(pNewBuffer,pOldBuffer,dwNewSize);
/*****************************************手动阈值处理**************************************/
int i,j;
for(i=0;i<iHeight;i++)
{
for(j=0;j<iWidth;j++)
{
if (pOldBits[(iHeight-1-i)*nWidthBytes+j]>m_thresholdvalue)
{
pNewBits[(iHeight-1-i)*nWidthBytes+j]=255;
}
else
{
pNewBits[(iHeight-1-i)*nWidthBytes+j]=0;
}
}
}
//free the memory for the old image
::GlobalUnlock(m_pImageObject->GetDib());
::GlobalFree(m_pImageObject->GetDib());
//Update the DIB in the object pointed by m_pImaeObject
::GlobalUnlock(hNewDib);
m_pImageObject->SetDib(hNewDib);
return TRUE;
}
BOOL CThreshold::OnAutoThreshold()
{
//**********获取图像的像素区指针和各种参数,这段代码是通用的****************
int nWidth = m_pImageObject->GetWidth(); //取得图像的宽度
int nHeight = m_pImageObject->GetHeight(); //取得图像的高度
int nNumBits = m_pImageObject->GetNumBits();//取得图像的位数
m_pTempBits=new BYTE[nWidth*nHeight];
int nWidthBytes; //图像每行所占的字节数
char *pBuffer = (char *) m_pImageObject->GetDIBPointer( &nWidthBytes );
BITMAPFILEHEADER *pBFH; //图像文件头指针
BITMAPINFOHEADER *pBIH; //图像信息头指针
RGBQUAD *pRGBPalette; //图像调色板指针
unsigned char *pBits; //像素区的首指针
int nNumColors = m_pImageObject->GetNumColors();
pBFH = (BITMAPFILEHEADER *) pBuffer;
pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
pRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)];
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
//pBits就是我们所必须要的像素指针!!!
/****************************************自动阈值处理********************************/
//*************初始化类的其他数据成员********************
int m=1<<nNumBits;
int i, j, k ,max,min;
float *w0,*w1,*u0,*u1,*u,*result,*plCount;
w0=new float[m];
w1=new float[m];
u0=new float[m];
u1=new float[m];
u=new float[m];
plCount=new float[m];
result=new float[m];
m_pfDistr=new float[m];
for( i=0;i<m;i++)
{
w0[i]=0;
w1[i]=0;
u0[i]=0;
u1[i]=0;
u[i] =0;
plCount[i]=0;
result[i]=0;
m_pfDistr[i]=0;
}
//********************计算直方图********************
for (j=0; j<nHeight; j++)
{
for (i=0; i<nWidth; i++)
{
m_pTempBits[(nHeight-1-j)*nWidthBytes + i]=
pBits[(nHeight-1-j)*nWidthBytes+i];
}
}
for (j=0; j<nHeight; j++)
{
for (i=0; i<nWidth; i++)
{
plCount[pBits[(nHeight-1-j)*nWidthBytes + i]] ++;
//注意取图像中(i, j )点像素的方式!!!!!
}
}
long lTotalCount = (long)nHeight * nWidth;
for (k=0; k<m; k++)
{
m_pfDistr[k] = plCount[k] / (float)lTotalCount;
}
for(i=0;i<m;i++)
{
if (m_pfDistr[i]>0)
{
max=i;//图象中的最大灰度值
}
}
i=0;
if (m_pfDistr[0]==0)
{
while (m_pfDistr[i]==0)
{
i++;
min=i;//图象中的最小灰度值
}
}
else
{
min=0;
}
for(k=min;k<=max;k++)
{
for(i=0;i<=k;i++)
{
w0[k]+=m_pfDistr[i];
u0[k]+=i*m_pfDistr[i];
}
for(i=k;i<=max;i++)
{
w1[k]+=m_pfDistr[i];
u1[k]+=i*m_pfDistr[i];
}
u0[k]=u0[k]/w0[k];
u1[k]=u1[k]/w1[k];
u[k] =w0[k]*u0[k]+w1[k]*u1[k];
result[k]=float(w0[k]*pow(u0[k]-u[k],2)+w1[k]*pow(u1[k]-u[k],2));
}
float temp;
temp=result[min];
for(i=min;i<=max;i++)
{
if(temp<result[i])
{
temp=result[i];
m_thresholdvalue=i;
}
}
delete w0;
delete w1;
delete u0;
delete u1;
delete u;
delete plCount;
delete result;
OnManualThreshold();
return true;
}
BOOL CThreshold::OnAreaGrowing()
{
if (m_pImageObject == NULL)
{
return FALSE;
}
int iWidth = m_pImageObject->GetWidth();
int iHeight = m_pImageObject->GetHeight();
/*************************************the old image*****************************/
unsigned char *pOldBuffer, *pNewBuffer, *pOldBits, *pNewBits;
BITMAPFILEHEADER *pOldBFH, *pNewBFH;
BITMAPINFOHEADER *pOldBIH, *pNewBIH;
RGBQUAD *pOldPalette, *pNewPalette;
int nWidthBytes, nNumColors;
pOldBuffer = (unsigned char *) m_pImageObject->GetDIBPointer(&nWidthBytes, m_pImageObject->GetNumBits());
if (pOldBuffer == NULL)
{
return FALSE;
}
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
nNumColors = m_pImageObject->GetNumColors();
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
/*************************************the new image*****************************/
DWORD dwNewSize;
HGLOBAL hNewDib;
//Allocate a global memory block for the new image
dwNewSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ nNumColors * sizeof(RGBQUAD)
+ nWidthBytes * (m_pImageObject->GetHeight());
hNewDib = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize);
if (hNewDib == NULL)
{
m_pImageObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock(m_pImageObject->GetDib());
return FALSE;
}
//Get the pointer to the new memory block
pNewBuffer = (unsigned char *) ::GlobalLock(hNewDib);
if (pNewBuffer == NULL)
{
::GlobalFree( hNewDib );
m_pImageObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock(m_pImageObject->GetDib());
return FALSE;
}
pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
//Make a copy of the old image
memcpy(pNewBuffer,pOldBuffer,dwNewSize);
int i,j,ii,jj;
int n = 0;
int temp =0;
int germ_x[10000],germ_y[10000];
//*******************************找出种子***********************
for (j=1; j<iHeight; j++)
{
for (i=1; i<iWidth; i++)
{
temp = 0;
for (jj=0; jj<3; jj++)
{
for (ii=0; ii<3; ii++)
{
if (ii!=1 || jj!=1)
{
if (pOldBits[(iHeight-1-(j-1+jj))*nWidthBytes + (i-1+ii)]
!= pOldBits[(iHeight-1-j)*nWidthBytes + i])
{
temp++;
}
if (temp == 8)
{
germ_x[n] = i;
germ_y[n] = j;
n++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -