当前位置:文档之家› 数字图像处理期末作业1

数字图像处理期末作业1

上海电力学院实验报告实验课程名称:数字图像处理实验项目名称:实验7 细胞面积计算与个数统计班级: 2009073姓名:杨祯学号: 20092006一、实验目的1、熟悉Visual C++开发环境和Windows编程模型。

2、掌握设备无关位图的数据格式。

3、学会使用DIBAPI函数访问设备无关位图。

4、结合实例学习如何在应用程序中添加图像处理算法。

5、运用所学的图像处理方法对细胞图像进行细胞面积计算与个数统计。

二、实验原理在填充孔洞以后的细胞图像中出现粘连,可以通过较为复杂的算法将粘连细胞分割开来。

这里采取如下简单方法进行细胞计数和面积计算.(1)对填充孔洞后后细胞图像进行标记处理,初步计算出细胞的个数;(2)计算不同标记区域的像素数,并用区域的像素数代表其面积;(3)若某个标记区域像素数大于1000,则认为该标记区域为两个粘连在一起的细胞,原细胞数量增加1;若某个标记区域像素数小于70,则视为噪声,原细胞数量减1。

三、实验步骤1、在资源浏览方式下,选择Menu节点,点击IDR_MAINFRAME,增加操作按钮,见下图,如在菜单“细胞计数”中添加“统计个数和面积”按钮。

2、对该按钮进行编辑,如图:ID设为ID_CELLCOUNT E,标题设为“统计个数和面积”。

3、(1)按下快捷键CTRL+W,弹出向导对话框,利用向导在CCellCounView类中添加响应函数—腐蚀OnCellcount,如图:1、注意类名2、选择ID4、点击按钮3、双击COMMAND添加函数后的结果(2)点击Edit Code按钮后,在CCellCountView.cpp文件中便添加了OnCellcount ()函数,此时需要在该函数中添加实现代码,具体如下:void CCellCountView::OnCellcount(){CCellCountDoc* pDoc=GetDocument();if( pDoc->m_hDIB!=NULL ){Area(pDoc->m_hDIB);pDoc->UpdateAllViews( NULL );}}(3)在CCellCountView.h文件中添加void Mark(LPSTR p_data,long wide,long height);//标记连通区域void Area(HDIB hDIB);//计算面积int x_sign;int m_temp;int x_temp;int y_temp;int flag[255];int fg[255];BYTE *p_temp;int step;在CCellCountView.cpp文件添加如下函数及代码://连通区域标记void CCellCountView::Mark(LPSTR p_data,long wide,long height){//把类中的变量初始化x_sign=0;m_temp=0;x_temp=0;y_temp=0;flag[255];memset(flag,0,255);p_temp=new BYTE[wide*height];//开辟一个临时内存区memset(p_temp,255,wide*height);//从左到右标号for(int j=1;j<height-1;j++) // 每行{for(int i=1;i<wide-1;i++) // 每列{if(*(p_data+(height-j-1)*wide+i)==0)//若当前点为黑点{if(*(p_data+(height-j-1+1)*wide+i+1)==0)//右上把右上的标号值赋给该点,因为右上以检测过{*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i+1);x_temp=*(p_temp+(height-j-1+1)*wide+i+1);//提取出右上的标志flag[x_temp]+=1;//对应的标号数加1,用于记录点数。

if(*(p_data+(height-j-1)*wide+i-1)==0&&*(p_temp+(height-j-1)*wide+i-1)!=x_t emp)//判断左前是那一个连通域的,//如果是一个连通域,就执行下一个,不是一个连通域,{y_temp=*(p_temp+(height-j-1)*wide+i-1);//则记录下这个连通与的值for(int m=1;m<=height-1;m++)for(int n=1;n<=wide-1;n++){if(*(p_temp+(height-m-1)*wide+n)==y_temp)//在整个区间找属于哪个连通域的把他们全部标记为右上的连通域{flag[y_temp]=0;*(p_temp+(height-m-1)*wide+n)=x_temp;flag[x_temp]+=1;//发现一个,把这个连通域中内容加1.}}}//end//左前if(*(p_data+(height-j-1+1)*wide+i-1)==0&&*(p_temp+(height-j-1+1)*wide+i-1)! =x_temp)//在判断左上,用相同的方法//把号全部的标记,由于对于右上来说只有这两个与他不连通,所以就只用两次判断。

{y_temp=*(p_temp+(height-j-1+1)*wide+i-1);for(int m=1;m<=height-1;m++)for(int n=1;n<=wide-1;n++){if(*(p_temp+(height-m-1)*wide+n)==y_temp){flag[y_temp]=0;*(p_temp+(height-m-1)*wide+n)=x_temp;flag[x_temp]+=1;}}}//end//左上}else if(*(p_data+(height-j-1+1)*wide+i)==0)//由于正上的判断往后走还要判断右边的所以这里不需要在做其他的检测。

{*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i);x_temp=*(p_temp+(height-j-1+1)*wide+i);flag[x_temp]+=1;}else if(*(p_data+(height-j-1+1)*wide+i-1)==0)//由于正上的判断往后走还要判断右边的所以这里不需要在做其他的检测。

{*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i-1);x_temp=*(p_temp+(height-j-1+1)*wide+i-1);flag[x_temp]+=1;}else if(*(p_data+(height-j-1)*wide+i-1)==0)//由于正上的判断往后走还要判断右边的所以这里不需要在做其他的检测。

{*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1)*wide+i-1);x_temp=*(p_temp+(height-j-1)*wide+i-1);flag[x_temp]+=1;}else//没有{++x_sign;m_temp=x_sign;//一个标号结束了*(p_temp+(height-j-1)*wide+i)=m_temp;//把它赋给相应的这个像素flag[m_temp]=0;//把对应的标号为清空即可。

}}//end if}// 每列}//end 每行}//计算面积void CCellCountView::Area(HDIB hDIB){// 指向DIB的指针LPSTR lpDIB;// 指向DIB象素指针LPSTR lpDIBBits;// 锁定DIBlpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);// 找到DIB图像象素起始位置lpDIBBits = FindDIBBits(lpDIB);// 判断是否是8-bpp位图if (DIBBitCount(lpDIB) != 8){// 提示用户MessageBox("请先将其转换为8位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);// 解除锁定::GlobalUnlock((HGLOBAL) hDIB);// 返回return;}// 更改光标形状BeginWaitCursor();// DIB的宽度LONG lWidth = DIBWidth(lpDIB);// DIB的高度LONG lHeight = DIBHeight(lpDIB);Mark(lpDIBBits, lWidth,lHeight); //调用标记函数int i;memset(fg,0,255);//初始化赋值都为0int j=0;int CellCount=0;CellCount=0;for(i=1;i<=x_sign;i++)//从标号1到最后{if(flag[i]>70){if(flag[i]>2000){CellCount=CellCount+flag[i]/1000-1;}if(fg[j]==0){fg[j]=flag[i];//这里的fg[]中就是面积的值j++;}}}CResultDlg m_ResultDlg;m_ResultDlg.Count=(j-1)+CellCount;m_ResultDlg.AreaCount=j;for(i=0;i<j;i++){m_ResultDlg.Area[i]=fg[i];}m_ResultDlg.DoModal();}(4)编译、链接(F7)及运行(CTRL+F5),打开一BMP图像cell.bmp,运行统计个数与面积,观察显示。

四、实验结果(1)、打开灰度cell图像文件cell.bmp,对其进行自适应阈值分割,得到二值图像,再进行腐蚀和膨胀,进行孔洞填充,得到结果如下图:。

相关主题