📄 cellview.cpp
字号:
if (/*cur_hsi->Intensity>max_intensity &&*/ // 亮度大于最大值并且色调超出范围
(cur_hsi->Hue>max_hue || cur_hsi->Hue<min_hue) )
cur_flag->marked=0;
}
}
cur_hsi++;
cur_flag++;
cur_sobel++;
}
GenEdge();
InvalidateRect(0,TRUE);
}
void CCellView::CalcCenterArea(int i, int j)
{
if (i<1 || i>g_nMapWidth-2 || j<1 || j>g_nMapHeight-2)
{
return;
}
tot_area++;
tot_x+=i;
tot_y+=j;
g_pFlags[j*g_nMapWidth+i].center=0;
for ( int n=0; n<points_temp.size(); n++ )
{
if (points_temp.at(n).x==i && points_temp.at(n).y==j)
{
if (points_temp.at(n).radius>max_radius)
max_radius=points_temp.at(n).radius;
break;
}
}
if ( g_pFlags[j*g_nMapWidth+i-1].center )
{
CalcCenterArea(i-1,j);
}
if ( g_pFlags[j*g_nMapWidth+i+1].center )
{
CalcCenterArea(i+1,j);
}
if ( g_pFlags[(j-1)*g_nMapWidth+i].center )
{
CalcCenterArea(i,j-1);
}
if ( g_pFlags[(j+1)*g_nMapWidth+i].center )
{
CalcCenterArea(i,j+1);
}
if ( g_pFlags[(j+1)*g_nMapWidth+i+1].center )
{
CalcCenterArea(i+1,j+1);
}
if ( g_pFlags[(j+1)*g_nMapWidth+i-1].center )
{
CalcCenterArea(i-1,j+1);
}
if ( g_pFlags[(j-1)*g_nMapWidth+i+1].center )
{
CalcCenterArea(i+1,j-1);
}
if ( g_pFlags[(j-1)*g_nMapWidth+i-1].center )
{
CalcCenterArea(i-1,j-1);
}
}
void CCellView::OnProcForceKill()
{
// TODO: Add your command handler code here
if(g_hBitmap)
{
m_bForceKill = true;
}
else
MessageBox("请先打开图像文件!");
}
void CCellView::OnProcForceSele()
{
// TODO: Add your command handler code here
if(g_hBitmap)
{
m_bForceAdd = true;
}
else
MessageBox("请先打开图像文件!");
}
void CCellView::OnProcDilation()
{
if (g_bDir4Dil)
g_bDir4Dil=false;
else g_bDir4Dil=true;
// backup
memcpy(g_pFlagsBack,g_pFlags,
sizeof(FLAGS)*g_nMapWidth*g_nMapHeight);
// 膨胀
RGB *cur=g_pImgBuffer;
FLAGS *cur_flag=g_pFlags;
vector<long> addr;
for (int ht=0;ht<g_nMapHeight;ht++)
for (int wd=0;wd<g_nMapWidth;wd++)
{
if (!cur_flag->marked)
{
if (ht==0 || wd==0 || ht==g_nMapHeight-1 || wd==g_nMapWidth-1)
{
cur++;
cur_flag++;
continue;
}
else if (g_bDir4Dil)
{
if ( (cur_flag-1)->marked || // left
(cur_flag+1)->marked || // right
(cur_flag-g_nMapWidth-1)->marked || // left up
(cur_flag-g_nMapWidth+1)->marked || // right up
(cur_flag+g_nMapWidth-1)->marked || // left down
(cur_flag+g_nMapWidth+1)->marked || // right down
(cur_flag-g_nMapWidth)->marked || // up
(cur_flag+g_nMapWidth)->marked ) // down
addr.push_back((long)cur_flag);
}
else
{
if ( (cur_flag-1)->marked || // left
(cur_flag+1)->marked || // right
(cur_flag-g_nMapWidth)->marked || // up
(cur_flag+g_nMapWidth)->marked ) // down
addr.push_back((long)cur_flag);
}
}
cur++;
cur_flag++;
}
int size=addr.size();
for (int i=0;i<size;i++)
((FLAGS *)addr.at(i))->marked=1;
addr.clear();
GenEdge();
InvalidateRect(0,TRUE);
}
void CCellView::OnProcErosion()
{
if (g_bDir4Ero)
g_bDir4Ero=false;
else g_bDir4Ero=true;
// backup
memcpy(g_pFlagsBack,g_pFlags,
sizeof(FLAGS)*g_nMapWidth*g_nMapHeight);
// 腐蚀
RGB *cur=g_pImgBuffer;
FLAGS *cur_flag=g_pFlags;
vector<long> addr;
for (int ht=0;ht<g_nMapHeight;ht++)
for (int wd=0;wd<g_nMapWidth;wd++)
{
if (cur_flag->marked)
{
if (ht==0 || wd==0 || ht==g_nMapHeight-1 || wd==g_nMapWidth-1)
{
cur_flag->marked=0;
cur++;
cur_flag++;
continue;
}
else if (g_bDir4Ero)
{
if ( !(cur_flag-1)->marked || // left
!(cur_flag+1)->marked || // right
!(cur_flag-g_nMapWidth-1)->marked || // left up
!(cur_flag-g_nMapWidth+1)->marked || // right up
!(cur_flag+g_nMapWidth-1)->marked || // left down
!(cur_flag+g_nMapWidth+1)->marked || // right down
!(cur_flag-g_nMapWidth)->marked || // up
!(cur_flag+g_nMapWidth)->marked ) // down
addr.push_back((long)cur_flag);
}
else
{
if ( !(cur_flag-1)->marked || // left
!(cur_flag+1)->marked || // right
!(cur_flag-g_nMapWidth)->marked || // up
!(cur_flag+g_nMapWidth)->marked ) // down
addr.push_back((long)cur_flag);
}
}
cur++;
cur_flag++;
}
int size=addr.size();
for (int i=0;i<size;i++)
((FLAGS *)addr.at(i))->marked=0;
addr.clear();
GenEdge();
InvalidateRect(0,TRUE);
}
void CCellView::OnProcSmooth()
{
int wd,ht;
if(g_hBitmap)
{
RGB *g_pTemp=new RGB[g_nMapWidth*g_nMapHeight];
RGB *ptemp=g_pTemp;
memset(g_pTemp,0,g_nMapWidth*g_nMapHeight*sizeof(RGB));
RGB *cur=g_pImgBuffer;
for (ht=0;ht<g_nMapHeight;ht++)
for (wd=0;wd<g_nMapWidth;wd++)
{
if (ht==0 || wd==0 || ht==g_nMapHeight-1 || wd==g_nMapWidth-1)
{ }
else
{
ptemp->r=( (cur-g_nMapWidth-1)->r +
(cur-g_nMapWidth )->r +
(cur-g_nMapWidth+1)->r +
(cur-1)->r +
cur->r +
(cur+1)->r +
(cur+g_nMapWidth-1)->r +
(cur+g_nMapWidth )->r +
(cur+g_nMapWidth+1)->r )/9;
ptemp->g=( (cur-g_nMapWidth-1)->g +
(cur-g_nMapWidth )->g +
(cur-g_nMapWidth+1)->g +
(cur-1)->g +
cur->g +
(cur+1)->g +
(cur+g_nMapWidth-1)->g +
(cur+g_nMapWidth )->g +
(cur+g_nMapWidth+1)->g )/9;
ptemp->b=( (cur-g_nMapWidth-1)->b +
(cur-g_nMapWidth )->b +
(cur-g_nMapWidth+1)->b +
(cur-1)->b +
cur->b +
(cur+1)->b +
(cur+g_nMapWidth-1)->b +
(cur+g_nMapWidth )->b +
(cur+g_nMapWidth+1)->b )/9;
}
cur++;
ptemp++;
}
memcpy(g_pImgBuffer,g_pTemp,g_nMapWidth*g_nMapHeight*sizeof(RGB));
delete[] g_pTemp;
InvalidateRect(0,TRUE);
}
else
MessageBox("请先打开图像文件!");
}
void CCellView::CountSeeds()
{
int wd,ht;
FLAGS *cur_flag;
g_nCellCount=0;
g_nCellTotArea=0;
cur_flag=g_pFlags;
for (ht=0;ht<g_nMapHeight;ht++)
for (wd=0;wd<g_nMapWidth;wd++)
{
cur_flag->visited=0; // clear visited
cur_flag++;
}
cur_flag=g_pFlags;
for (ht=0;ht<g_nMapHeight;ht++)
for (wd=0;wd<g_nMapWidth;wd++)
{
if (cur_flag->marked && !cur_flag->visited)
{
g_nCellCount++;
ProcessCountSeeds(wd,ht,cur_flag);
}
cur_flag++;
}
InvalidateRect(0,TRUE);
char msg[256];
double avgarea=(double)g_nCellTotArea/(double)g_nCellCount;
sprintf(msg,"一共有%d个细胞,平均面积%d象素(大约%d*%d)",
g_nCellCount,(int)avgarea,(int)sqrt(avgarea),(int)sqrt(avgarea));
MessageBox(msg);
}
void CCellView::ProcessCountSeeds(int wd, int ht, FLAGS *curf)
{
if (wd<0 || wd>g_nMapWidth-1 || ht<0 || ht>g_nMapHeight-1)
return;
FLAGS *next;
g_nCellTotArea++;
curf->visited=1;
if (ht>0)
{
next=curf-g_nMapWidth;
if (next->marked && !next->visited)
ProcessCountSeeds(wd,ht-1,next); // up
}
if (ht<g_nMapHeight-1)
{
next=curf+g_nMapWidth;
if (next->marked && !next->visited)
ProcessCountSeeds(wd,ht+1,next); // down
}
if (wd>0)
{
next=curf-1;
if (next->marked && !next->visited)
ProcessCountSeeds(wd-1,ht,next); // left
}
if (wd<g_nMapWidth-1)
{
next=curf+1;
if (next->marked && !next->visited)
ProcessCountSeeds(wd+1,ht,next); // right
}
}
void CCellView::OnProcStat()
{
int result;
result=MessageBox("是否使用中心点标注信息?",NULL,MB_YESNO);
if (result==IDYES)
{
CounterSeedsCenter();
}
else
{
CountSeeds();
}
}
void CCellView::CounterSeedsCenter()
{
if (m_vCenterPoints.size==0)
MessageBox("中心点数据似乎没有生成...");
else
{
long tota,totr;
tota=0; totr=0;
for (int i=0;i<m_vCenterPoints.size();i++)
{
tota+=m_vCenterPoints.at(i).radius*m_vCenterPoints.at(i).radius*3.14;
totr+=m_vCenterPoints.at(i).radius;
}
char msg[256];
sprintf(msg,"共有%d个细胞,平均半径%d,平均面积%d",
m_vCenterPoints.size(),
totr/m_vCenterPoints.size(),
tota/m_vCenterPoints.size());
MessageBox(msg);
}
}
void CCellView::FillHoles()
{
int wd,ht;
FLAGS *cur_flag=g_pFlags;
// backup
memcpy(g_pFlagsBack,g_pFlags,
sizeof(FLAGS)*g_nMapWidth*g_nMapHeight);
qSz=g_nMapWidth*g_nMapHeight*2;
qh=new int[qSz+1];
if(!qh) return;
for (ht=0;ht<g_nMapHeight;ht++)
for (wd=0;wd<g_nMapWidth;wd++)
{
cur_flag->visited=0; // clear visited
cur_flag++;
}
cur_flag=g_pFlags;
for (ht=0;ht<g_nMapHeight;ht++)
for (wd=0;wd<g_nMapWidth;wd++)
{
if (!cur_flag->marked && !cur_flag->visited)
{
g_nCellTotArea=0;
ProcessFillHoles(wd,ht);
if (g_nCellTotArea<MAX_HOLE && g_nCellTotArea>0)
FillTheHole(wd,ht);
// char msg[128];
// sprintf(msg,"%d",g_nCellTotArea);
// InvalidateRect(0,TRUE);
// MessageBox(msg);
}
cur_flag++;
}
delete[] qh;
GenEdge();
InvalidateRect(0,TRUE);
}
void CCellView::ProcessFillHoles(int wd, int ht)
{
if (wd<0 || wd>g_nMapWidth-1 || ht<0 || ht>g_nMapHeight-1)
return;
qst=qh;
memset(qst,0,qSz); //Clear the contents
qs=qr=qst;
*qs=xt=wd;
qs++;
*qs=yt=ht;
qs++;
g_pFlags[INDEX(xt,yt)].visited=1;
g_nCellTotArea++;
//Main queue loop
while(qr!=qs)
{
//Add new members to queue
//Above current pixel
if (yt>0)
if(!g_pFlags[(yt-1)*g_nMapWidth+xt].visited &&
!g_pFlags[(yt-1)*g_nMapWidth+xt].marked)
{
g_nCellTotArea++;
*qs=xt;
qs++;
*qs=yt-1;
qs++;
g_pFlags[(yt-1)*g_nMapWidth+xt].visited=1;
}
//Below current pixel
if (yt<g_nMapHeight-1)
if(!g_pFlags[(yt+1)*g_nMapWidth+xt].visited &&
!g_pFlags[(yt+1)*g_nMapWidth+xt].marked)
{
g_nCellTotArea++;
*qs=xt;
qs++;
*qs=yt+1;
qs++;
g_pFlags[(yt+1)*g_nMapWidth+xt].visited=1;
}
//Left of current pixel
if (xt>0)
if(!g_pFlags[yt*g_nMapWidth+xt-1].visited &&
!g_pFlags[yt*g_nMapWidth+xt-1].marked)
{
g_nCellTotArea++;
*qs=xt-1;
qs++;
*qs=yt;
qs++;
g_pFlags[yt*g_nMapWidth+xt-1].visited=1;
}
//Right of current pixel
if (yt<g_nMapWidth-1)
if(!g_pFlags[yt*g_nMapWidth+xt+1].visited &&
!g_pFlags[yt*g_nMapWidth+xt+1].marked)
{
g_nCellTotArea++;
*qs=xt+1;
qs++;
*qs=yt;
qs++;
g_pFlags[yt*g_nMapWidth+xt+1].visited=1;
}
//Retrieve current queue member
qr+=2;
xt=*qr;
yt=*(qr+1);
} //Back to beginning of loop
}
void CCellView::FillTheHole(int wd, int ht)
{
if (wd<0 || wd>g_nMapWidth-1 || ht<0 || ht>g_nMapHeight-1)
return;
g_nCellTotArea--;
if (g_nCellTotArea<0)
return;
qst=qh;
memset(qst,0,qSz); //Clear the contents
qs=qr=qst;
*qs=xt=wd;
qs++;
*qs=yt=ht;
qs++;
g_pFlags[INDEX(xt,yt)].marked=1;
//Main queue loop
while(qr!=qs)
{
//Add new members to queue
//Above current pixel
if (yt>0)
if(g_pFlags[(yt-1)*g_nMapWidth+xt].visited &&
!g_pFlags[(yt-1)*g_nMapWidth+xt].marked)
{
g_nCellTotArea--;
if (g_nCellTotArea<0)
return;
*qs=xt;
qs++;
*qs=yt-1;
qs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -