📄 cellview.cpp
字号:
{
if ( !(cur_flag-1)->center && !(cur_flag+1)->center &&
!(cur_flag+g_nMapWidth)->center &&
!(cur_flag-g_nMapWidth)->center &&
!(cur_flag+g_nMapWidth-1)->center &&
!(cur_flag+g_nMapWidth+1)->center &&
!(cur_flag-g_nMapWidth-1)->center &&
!(cur_flag-g_nMapWidth+1)->center )
{
// 孤立的点
pt.x=x;
pt.y=y;
points.push_back(pt);
cur_flag++;
continue;
}
else
{
tot_area=0;
max_radius=0;
tot_x=0;
tot_y=0;
CalcCenterArea(x,y);
pt.x=tot_x/tot_area;
pt.y=tot_y/tot_area;
pt.radius=max_radius;
g_pFlags[pt.y*g_nMapWidth+pt.x].center=1;
points.push_back(pt);
}
}
}
cur_flag++;
}
m_vCenterPoints.clear();
int x0,y0;
bool adj;
// 清除center标志
cur_flag=g_pFlags;
for(y = 0; y < g_nMapHeight; y++)
for(x = 0; x < g_nMapWidth; x++)
{
cur_flag->center=0;
cur_flag++;
}
// 平均化相近的中心点
for (i=0;i<points.size();i++)
{
x0=points.at(i).x;
y0=points.at(i).y;
adj=false;
for (j=i+1;j<points.size();j++)
{
x=points.at(j).x;
y=points.at(j).y;
if (abs(x0-x)+abs(y0-y)<10) // 相近
{
points.at(j).x=(x+x0)/2;
points.at(j).y=(y+y0)/2;
points.at(j).radius=points.at(i).radius;
points.erase(&points.at(j));
i--;
adj=true;
break;
}
}
if (!adj) // 非相近
{
if (points.at(i).radius>5)
{
m_vCenterPoints.push_back(points.at(i));
g_pFlags[points.at(i).y*g_nMapWidth+points.at(i).x].center=1;
}
}
}
double max_intensity=0.0;
double hue,inte;
double min_hue=255.0;
double max_hue=0.0;
double overmax;
double overmin;
if (m_vAllSelected.size()>0) // 保存着的选项
{
for (int i=0;i<m_vAllSelected.size();i++)
{
if (m_vAllSelected.at(i).Intensity>max_intensity)
max_intensity=m_vAllSelected.at(i).Intensity;
if (m_vAllSelected.at(i).Hue>max_hue)
max_hue=m_vAllSelected.at(i).Hue;
if (m_vAllSelected.at(i).Hue<min_hue)
min_hue=m_vAllSelected.at(i).Hue;
}
InvalidateRect(0,TRUE);
MessageBox("准备开始修正");
}
else
{
InvalidateRect(0,TRUE);
return;
}
max_hue+=max_hue*0.02;
min_hue-=min_hue*0.02;
overmax=max_hue*1.08;
overmin=min_hue*0.92;
int r0,r;
int tx,ty;
int area,toobad;
// 去掉被包含的圆
for (i=0;i<m_vCenterPoints.size();i++)
{
x0=m_vCenterPoints.at(i).x;
y0=m_vCenterPoints.at(i).y;
r0=m_vCenterPoints.at(i).radius;
for (j=i+1;j<m_vCenterPoints.size();j++)
{
x=m_vCenterPoints.at(j).x;
y=m_vCenterPoints.at(j).y;
r=m_vCenterPoints.at(j).radius;
if (DISTANCE(x0,y0,x,y)<abs(r0-r)+4) // 包含
{
CDC *pdc=GetDC();
CENTER_POINT centerp;
CPen pen;
pen.CreatePen(PS_DOT, 1, RGB(255,0,0));
pdc->SelectObject(pen);
if (r0>r) // 去掉r0
centerp=m_vCenterPoints.at(i);
else
centerp=m_vCenterPoints.at(j);
Arc(pdc->m_hDC,
centerp.x-scroll_lefttop.x-centerp.radius,
centerp.y-scroll_lefttop.y-centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y+centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y
);
DeleteObject(pen);
if (r0>r) // 去掉r0
{
m_vCenterPoints.erase(&m_vCenterPoints.at(i));
i--;
}
else
m_vCenterPoints.erase(&m_vCenterPoints.at(j));
}
}
}
vector<CENTER_POINT> tocheck;
int n,size,total;
bool isok;
// 去掉潜在的错误(同两个圆相交,并且不相交的部分是噪声)
for (i=0;i<m_vCenterPoints.size();i++)
{
tocheck.clear();
x0=m_vCenterPoints.at(i).x;
y0=m_vCenterPoints.at(i).y;
r0=m_vCenterPoints.at(i).radius;
for (j=0;j<m_vCenterPoints.size();j++)
{
if (i==j)
continue;
x=m_vCenterPoints.at(j).x;
y=m_vCenterPoints.at(j).y;
r=m_vCenterPoints.at(j).radius;
if (DISTANCE(x0,y0,x,y)<abs(r0+r)) // 相交
{
pt.x=x; pt.y=y; pt.radius=r;
tocheck.push_back(pt);
}
}
size=tocheck.size();
if (size>1) // 同两个以上的圆相交
{
area=0;
total=0;
toobad=0;
for (tx=x0-r0;tx<x0+r0;tx++)
for (ty=y0-r0;ty<y0+r0;ty++)
{
if (DISTANCE(x0,y0,tx,ty)<r0) // 所有圆内部的点
{
if (tx<0 || tx>g_nMapWidth-1 || ty<0 || ty>g_nMapHeight-1)
continue;
isok=true;
for (n=0;n<size;n++)
{
pt=tocheck.at(n);// 取得
if (DISTANCE(tx,ty,pt.x,pt.y)<pt.radius)
{
isok=false;
break;
}
}
if (isok) // 同所有的圆都不相交的部分
{
total++;
hue=g_pHSIBuffer[ty*g_nMapWidth+tx].Hue;
inte=g_pHSIBuffer[ty*g_nMapWidth+tx].Intensity;
if (inte>max_intensity || hue > max_hue || hue < min_hue)
area++;
if (hue > overmax || hue < overmin)
toobad++;
}
}
}
if (total<r0*r0 || (total<r0*r0*1.5 && area>total*0.5) || toobad>total/6) // need adjust
{
CDC *pdc=GetDC();
CENTER_POINT centerp;
CPen pen;
if (total<r0*r0) // 红色 面积过小
pen.CreatePen(PS_SOLID, 2, RGB(255,0,0));
else if (toobad>total/6) // 绿色 错误点过多
pen.CreatePen(PS_SOLID, 2, RGB(0,255,0));
else // 浅蓝 误差过大
pen.CreatePen(PS_SOLID, 2, RGB(0,255,255));
pdc->SelectObject(pen);
centerp=m_vCenterPoints.at(i);
Arc(pdc->m_hDC,
centerp.x-scroll_lefttop.x-centerp.radius,
centerp.y-scroll_lefttop.y-centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y+centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y
);
DeleteObject(pen);
m_vCenterPoints.erase(&m_vCenterPoints.at(i));
i--;
}
}
}
for (i=0;i<m_vCenterPoints.size();i++)
{
r0=m_vCenterPoints.at(i).radius;
if (r0<10)
{
x0=m_vCenterPoints.at(i).x;
y0=m_vCenterPoints.at(i).y;
area=0;
toobad=0;
for (tx=x0-r0;tx<x0+r0;tx++)
for (ty=y0-r0;ty<y0+r0;ty++)
if (sqrt((x0-tx)*(x0-tx)+(y0-ty)*(y0-ty))<r0)
{
if (tx<0 || tx>g_nMapWidth-1 || ty<0 || ty>g_nMapHeight-1)
continue;
hue=g_pHSIBuffer[ty*g_nMapWidth+tx].Hue;
if (hue > max_hue || hue < min_hue)
area++;
if (hue > overmax || hue < overmin)
toobad++;
}
if (area>r0*r0 || toobad>r0*r0/2) // need adjust
{
CDC *pdc=GetDC();
CENTER_POINT centerp;
CPen pen;
if (toobad>r0*r0/2)
pen.CreatePen(PS_DOT, 1, RGB(0,128,0));
else
pen.CreatePen(PS_DOT, 1, RGB(0,0,255));
pdc->SelectObject(pen);
centerp=m_vCenterPoints.at(i);
Arc(pdc->m_hDC,
centerp.x-scroll_lefttop.x-centerp.radius,
centerp.y-scroll_lefttop.y-centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y+centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y
);
DeleteObject(pen);
m_vCenterPoints.erase(&m_vCenterPoints.at(i));
i--;
}
}
}
/* // 去掉潜在的错误(相交,并且包含许多色调范围外的象素)
for (i=0;i<m_vCenterPoints.size();i++)
{
x0=m_vCenterPoints.at(i).x;
y0=m_vCenterPoints.at(i).y;
r0=m_vCenterPoints.at(i).radius;
for (j=i+1;j<m_vCenterPoints.size();j++)
{
x=m_vCenterPoints.at(j).x;
y=m_vCenterPoints.at(j).y;
r=m_vCenterPoints.at(j).radius;
if (sqrt((x0-x)*(x0-x)+(y0-y)*(y0-y))<abs(r0+r)) // 相交
{
area=0;
toobad=0;
for (tx=x0-r0;tx<x0+r0;tx++)
for (ty=y0-r0;ty<y0+r0;ty++)
if (sqrt((x0-tx)*(x0-tx)+(y0-ty)*(y0-ty))<r0)
{
if (tx<0 || tx>g_nMapWidth-1 || ty<0 || ty>g_nMapHeight-1)
continue;
hue=g_pHSIBuffer[ty*g_nMapWidth+tx].Hue;
if (hue > max_hue || hue < min_hue)
area++;
if (hue > overmax || hue < overmin)
toobad++;
}
if (area>r0*r0 || toobad>r0*r0/2) // need adjust
{
InvalidateRect(0,TRUE);
{
CDC *pdc=GetDC();
CENTER_POINT centerp;
CPen pen;
if (toobad>r0*r0/6)
pen.CreatePen(PS_SOLID, 3, RGB(255,0,0));
else
pen.CreatePen(PS_SOLID, 3, RGB(0,0,0));
pdc->SelectObject(pen);
centerp=m_vCenterPoints.at(i);
Arc(pdc->m_hDC,
centerp.x-scroll_lefttop.x-centerp.radius,
centerp.y-scroll_lefttop.y-centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y+centerp.radius,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y,
centerp.x-scroll_lefttop.x+centerp.radius,
centerp.y-scroll_lefttop.y
);
DeleteObject(pen);
}
m_vCenterPoints.erase(&m_vCenterPoints.at(i));
i--;
Sleep(2000);
break;
}
}
}
}
*/// Sleep(10000);
// InvalidateRect(0,TRUE);
}
else
MessageBox("请先打开图像文件!");
}
void CCellView::MarkIt(int i, int j)
{
// if (!m_bFullEdge)
// return; // 如果已经知道不是FullEdge了,那么不用做了!
if (i<1 || i>g_nMapWidth-2 || j<1 || j>g_nMapHeight-2)
{
return;
}
g_pFlags[j*g_nMapWidth+i].visited=1;
if ( !g_pFlags[j*g_nMapWidth+i-1].visited && // 没有访问过
g_pFlags[j*g_nMapWidth+i-1].marked ) // 标志了
{
if (g_pFlags[j*g_nMapWidth+i-1].edged ) // 并且是边缘
MarkIt(i-1,j); // 左边
else
m_bFullEdge=false;
}
if ( !g_pFlags[j*g_nMapWidth+i+1].visited && // 没有访问过
g_pFlags[j*g_nMapWidth+i+1].marked ) // 标志了
{
if (g_pFlags[j*g_nMapWidth+i+1].edged ) // 并且是边缘
MarkIt(i+1,j); // 右边
else
m_bFullEdge=false;
}
if ( !g_pFlags[(j-1)*g_nMapWidth+i].visited && // 没有访问过
g_pFlags[(j-1)*g_nMapWidth+i].marked ) // 标志了
{
if (g_pFlags[(j-1)*g_nMapWidth+i].edged ) // 并且是边缘
MarkIt(i,j-1); // 上面
else
m_bFullEdge=false;
}
if ( !g_pFlags[(j+1)*g_nMapWidth+i].visited && // 没有访问过
g_pFlags[(j+1)*g_nMapWidth+i].marked ) // 标志了
{
if (g_pFlags[(j+1)*g_nMapWidth+i].edged ) // 并且是边缘
MarkIt(i,j+1); // 下面
else
m_bFullEdge=false;
}
if ( !g_pFlags[(j-1)*g_nMapWidth+i-1].visited && // 没有访问过
g_pFlags[(j-1)*g_nMapWidth+i-1].marked ) // 标志了
{
if (g_pFlags[(j-1)*g_nMapWidth+i-1].edged ) // 并且是边缘
MarkIt(i-1,j-1); // 左上
else
m_bFullEdge=false;
}
if ( !g_pFlags[(j+1)*g_nMapWidth+i-1].visited && // 没有访问过
g_pFlags[(j+1)*g_nMapWidth+i-1].marked ) // 标志了
{
if (g_pFlags[(j+1)*g_nMapWidth+i-1].edged ) // 并且是边缘
MarkIt(i-1,j+1); // 左下
else
m_bFullEdge=false;
}
if ( !g_pFlags[(j-1)*g_nMapWidth+i+1].visited && // 没有访问过
g_pFlags[(j-1)*g_nMapWidth+i+1].marked ) // 标志了
{
if (g_pFlags[(j-1)*g_nMapWidth+i+1].edged ) // 并且是边缘
MarkIt(i+1,j-1); // 右上
else
m_bFullEdge=false;
}
if ( !g_pFlags[(j+1)*g_nMapWidth+i+1].visited && // 没有访问过
g_pFlags[(j+1)*g_nMapWidth+i+1].marked ) // 标志了
{
if (g_pFlags[(j+1)*g_nMapWidth+i+1].edged ) // 并且是边缘
MarkIt(i+1,j+1); // 右下
else
m_bFullEdge=false;
}
}
void CCellView::SaveIt(int i, int j, int radius)
{
if (i<1 || i>g_nMapWidth-2 || j<1 || j>g_nMapHeight-2)
{
return;
}
CENTER_POINT pt;
pt.x=i;
pt.y=j;
pt.radius=radius;
points_temp.push_back(pt);
// marke current point
g_pFlags[j*g_nMapWidth+i].center=1;
g_pFlags[j*g_nMapWidth+i].visited=0;
if ( g_pFlags[j*g_nMapWidth+i-1].visited )
{
SaveIt(i-1,j,radius);
}
if ( g_pFlags[j*g_nMapWidth+i+1].visited )
{
SaveIt(i+1,j,radius);
}
if ( g_pFlags[(j-1)*g_nMapWidth+i].visited )
{
SaveIt(i,j-1,radius);
}
if ( g_pFlags[(j+1)*g_nMapWidth+i].visited )
{
SaveIt(i,j+1,radius);
}
if ( g_pFlags[(j+1)*g_nMapWidth+i+1].visited )
{
SaveIt(i+1,j+1,radius);
}
if ( g_pFlags[(j+1)*g_nMapWidth+i-1].visited )
{
SaveIt(i-1,j+1,radius);
}
if ( g_pFlags[(j-1)*g_nMapWidth+i+1].visited )
{
SaveIt(i+1,j-1,radius);
}
if ( g_pFlags[(j-1)*g_nMapWidth+i-1].visited )
{
SaveIt(i-1,j-1,radius);
}
}
// 利用sobel信息进行修正
void CCellView::OnProcSobelCorrect()
{
if (!g_hBitmap)
{
MessageBox("请先打开图片");
return;
}
// backup
memcpy(g_pFlagsBack,g_pFlags,
sizeof(FLAGS)*g_nMapWidth*g_nMapHeight);
double max_intensity=0.0;
double min_hue=255.0;
double max_hue=0.0;
if (m_vAllSelected.size()) // 还保存着啊!
for (int i=0;i<m_vAllSelected.size();i++)
{
if (m_vAllSelected.at(i).Intensity>max_intensity)
max_intensity=m_vAllSelected.at(i).Intensity;
if (m_vAllSelected.at(i).Hue>max_hue)
max_hue=m_vAllSelected.at(i).Hue;
if (m_vAllSelected.at(i).Hue<min_hue)
min_hue=m_vAllSelected.at(i).Hue;
}
max_hue-=max_hue*0.1;
min_hue+=min_hue*0.1;
int x,y;
FLAGS *cur_flag=g_pFlags;
BYTE *cur_sobel=g_pSobelResult;
HSI *cur_hsi=g_pHSIBuffer;
for(y = 0; y < g_nMapHeight; y++)
for(x = 0; x < g_nMapWidth; x++)
{
if ( cur_flag->marked )
{
if (*cur_sobel > 40) // 参数需要调整
{
if (max_intensity>0.01)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -