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

📄 cellview.cpp

📁 一个血液红细胞识别与统计系统。图像处理、图像分析、图像识别的一些基础算法和基本思路。内涵血液图片。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						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 + -