⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cellview.cpp

📁 这是一个细胞识别系统及其开放的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					{
						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 + -