📄 threshold.cpp
字号:
}
}
}
}
//**************************对每个种子进行区域生长****************************
int *GrowFlag;
GrowFlag = new int[iHeight*iWidth];
for (j=0; j<iHeight; j++)
{
for (i=0; i<iWidth; i++)
{
GrowFlag[(iHeight-1-j)*nWidthBytes + i] = 0;//生长标志初值全部为0;
}
}
CList <int,int> Area;
int AreaNum,GrowStopFlag;
int threshold = 10;
for (i=0; i<n; i++)
{
Area.AddTail((iHeight-1-germ_y[i])*nWidthBytes + germ_x[i]);
AreaNum = 1,GrowStopFlag = 1;
float AreaSum = pNewBits[(iHeight-1-germ_y[i])*nWidthBytes + germ_x[i]];
float AreaAvg = AreaSum;
int AreaSize = 3;
int iX=1,iY=1;
do {
GrowStopFlag = 0;
for (jj=0; jj<AreaSize; jj++)
{
for (ii=0; ii<AreaSize; ii++)
{
if (ii == 1 && jj==1)
{
continue;//种子点不再生长
}
int GrowPoint = (iHeight-1-(germ_y[i]-iY+jj))*nWidthBytes + (germ_x[i]-iX+ii);
if ((germ_x[i]-iX+ii)<0 || (germ_x[i]-iX+ii)>=iWidth || (germ_y[i]-iY+jj)<0 || (germ_y[i]-iY+jj)>=iHeight)
{
continue;//避免生长点超出图像范围
}
if (GrowFlag[GrowPoint] == 0 && (float(pNewBits[GrowPoint])-AreaAvg)<threshold)
{
Area.AddTail(GrowPoint);
GrowFlag[GrowPoint] = 1;
AreaSum += pNewBits[GrowPoint];
AreaNum ++;
AreaAvg = AreaSum/AreaNum;
GrowStopFlag ++;
}
}
}
AreaSize += 2;
iX = AreaSize/2;
iY = AreaSize/2;
} while(GrowStopFlag > 0);
POSITION pos = Area.GetHeadPosition();
for(int p=0; p<AreaNum; p++)
{
pNewBits[Area.GetNext(pos)] = int(AreaAvg);
//pNewBits[(iHeight-1-germ_y[i])*nWidthBytes + germ_x[i]];
}
Area.RemoveAll();
}
//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::OnDivCom()
{
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 j,i;
m_pBits = new int[iHeight*iWidth];
for(j=0;j<iHeight;j++)
{
for(i=0;i<iWidth;i++)
{
m_pBits[(iHeight-1-j)*nWidthBytes+i]=pOldBits[(iHeight-1-j)*nWidthBytes+i];
}
}
m_iHeight = m_pImageObject->GetHeight();
m_iWidth = m_pImageObject->GetWidth();
//弹入根结点
QuartTree root;
root.xs = 0;
root.ys = 0;
root.n = m_iHeight;
DivideRecursion(root);
for(j=0;j<iHeight;j++)
{
for(i=0;i<iWidth;i++)
{
pNewBits[(iHeight-1-j)*nWidthBytes+i] = m_pBits[(iHeight-1-j)*nWidthBytes+i];
}
}
delete [] m_pBits;
m_pBits = NULL;
//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::GetVariance(QuartTree qtree)
{
int i,j;
int n = qtree.n;
int x = qtree.xs;
int y = qtree.ys;
long temp = 0;
int aver = 0;
double variance = 0;
for(j=y;j<y+n;j++)
{
for(i=x;i<x+n;i++)
{
temp+=m_pBits[(256-1-j)*256+i];
}
}
aver = temp/(n*n);
for(j=y;j<y+n;j++)
{
for(i=x;i<x+n;i++)
{
variance+=pow((m_pBits[(256-1-j)*m_iWidth+i]-aver),2);
}
}
variance = variance/n/n;
if (variance<=100)
{
return TRUE;
}
else
{
return FALSE;
}
}
void CThreshold::DivideRecursion(QuartTree tree)
{
tree.child = new QuartTree[4];
//child0
tree.child[0].xs = tree.xs;
tree.child[0].ys = tree.ys;
tree.child[0].n = tree.n/2;
if (!GetVariance(tree.child[0]))
{
DivideRecursion(tree.child[0]);
}
else
{
Combine(tree.child[0]);
}
//child1
tree.child[1].xs = tree.xs+tree.n/2;
tree.child[1].ys = tree.ys;
tree.child[1].n = tree.n/2;
if (!GetVariance(tree.child[1]))
{
DivideRecursion(tree.child[1]);
}
else
{
Combine(tree.child[1]);
}
//child2
tree.child[2].xs = tree.xs;
tree.child[2].ys = tree.ys+tree.n/2;
tree.child[2].n = tree.n/2;
if (!GetVariance(tree.child[2]))
{
DivideRecursion(tree.child[2]);
}
else
{
Combine(tree.child[2]);
}
//child3
tree.child[3].xs = tree.xs+tree.n/2;
tree.child[3].ys = tree.ys+tree.n/2;
tree.child[3].n = tree.n/2;
if (!GetVariance(tree.child[3]))
{
DivideRecursion(tree.child[3]);
}
else
{
Combine(tree.child[3]);
}
Merge(tree);
}
void CThreshold::Combine(QuartTree qtree)
{
int i,j;
int aver;
int temp = 0;
for(j=qtree.ys;j<qtree.ys+qtree.n;j++)
{
for(i=qtree.xs;i<qtree.xs+qtree.n;i++)
{
temp+=m_pBits[(m_iHeight-1-j)*m_iWidth+i];
}
}
aver = (int) temp/(qtree.n*qtree.n);
for(j=qtree.ys;j<qtree.ys+qtree.n;j++)
{
for(i=qtree.xs;i<qtree.xs+qtree.n;i++)
{
m_pBits[(m_iHeight-1-j)*m_iWidth+i] = aver;
}
}
}
void CThreshold::Merge(QuartTree tree)
{
int i,j,m;
int temp,mergaver;
int *aver;
aver=new int[4];
for(m=0;m<4;m++)
{
temp=0;
for(j=tree.child[m].ys;j<tree.child[m].ys+tree.child[m].n;j++)
{
for(i=tree.child[m].xs;i<tree.child[m].xs+tree.child[m].n;i++)
{
temp+=m_pBits[(m_iHeight-1-j)*m_iWidth+i];
}
}
aver[m] = (int) temp/(tree.child[m].n*tree.child[m].n);
}
for (i=0; i<4; i++)
{
for (j=i+1; j<4; j++)
{
mergaver=0;
if ((j-i)!=2 && GetVariance(tree.child[i])
&& GetVariance(tree.child[j]) && fabs(aver[j]-aver[i])<10)
{
mergaver = (int)(aver[j]+aver[i])/2;
combinetwo(tree.child[i],tree.child[j],mergaver);
}
}
}
delete [] aver;
aver=NULL;
}
void CThreshold::combinetwo(QuartTree child1, QuartTree child2, int aver)
{
int i,j;
for (j=child1.ys; j<child1.ys+child1.n; j++)
{
for (i=child1.xs; i<child1.xs+child1.n; i++)
{
m_pBits[(m_iHeight-1-j)*m_iWidth+i] = unsigned char (aver);
}
}
for (j=child2.ys; j<child2.ys+child2.n; j++)
{
for (i=child2.xs; i<child2.xs+child2.n; i++)
{
m_pBits[(m_iHeight-1-j)*m_iWidth+i] = unsigned char (aver);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -