数字图像处理课程设计报告
细胞识别
目录
第一部分
1、实验课题名称----------------------------------------------------------------------------------3
2、实验目的----------------------------------------------------------------------------------------3
3、实验内容概要----------------------------------------------------------------------------------3
第二部分
1、建立工程文件----------------------------------------------------------------------------------3
2、图像信息获取----------------------------------------------------------------------------------4
3、如何建立下拉菜单----------------------------------------------------------------------------6
4、标记Mark点------------------------------------------------------------------------------------6
5、二值化---------------------------------------------------------------------------------------------9
6、填洞------------------------------------------------------------------------------------------------9
7、收缩------------------------------------------------------------------------------------------------10
8、获取中心点--------------------------------------------------------------------------------------11
9、细胞计数-----------------------------------------------------------------------------------------13
10、All-steps-----------------------------------------------------------------------------------------13
11、扩展功能---------------------------------------------------------------------------------------14 第三部分
12、各步骤结果和错误举例--------------------------------------------------------------------16 第四部分
13、心得体会----------------------------------------------------------------------------------------22
第一部分
1、实验课题:细胞识别
2、实验目的:对血液细胞切片图片进行各种处理,最终得出细胞的数目、面积等信息。
3、实验内容概要:基于VC++软件下的细胞识别,通过细胞的标记、二值化、
填洞、收缩、获取中心点、计数等过程完成实验目的。
第二部分——实验具体步骤
1、建立工程文件
①新建MFC工程项目:--MFC AppWizard、工程名
②拷贝,到工程文件夹,再向工程里添加
③添加变量:m_lpDib 和头文件#include””
④:变量(m_lpDib)的new、delete
⑤: Serialize()
2、图像信息获取
①读取图像参数: OnDraw() m_pDib->Draw()
如果图像不为空的话,那么就执行如下主要代码:
②点击键,建立类向导,在messages中添加OnInitialUpdate()函数,添加代码实现对自动打开固定图片。
③通过鼠标右击,点击建立类向导,在messages中添加OnMouseMove()函数,添加代码实现获取所要信息,即实现鼠标在图像任一位置移动时可以直观的读取相对应位置的信息。可以在屏幕上显示鼠标所指点的坐标以及RGB、HSI和灰度值,通过HSI的可以选取合适的阈值来找到细胞以及边界。
④为了RGB图像转化为人眼更容易识别的HSI模型,我们可以通过添加成员函数RgbtoHsi来实现这一功能。
HSI模型与RGB模型的转化关系
(添加函数时,可以右击类窗口中的,选中add member function,之后选择函数的返回值类型和函数描述,其它默认不变)
确定后在里面添加实现函数功能的代码。
3、添加下拉菜单
在resourceview那栏的找到菜单按键设置
双击,后在里面添加所需按键
每个按键的ID号为注意在填写为IDR_加菜单大写。
之后右击按键,建立类向导添加按键所需函数
4、标记mark
分为四步
1.找出mark(red)点和maybemark(blue)点
2.将maybemark(blue)点变成mark(black red)点
3.将mark(black red)点变成edge(yellow(fullred&&fullgreen))点
4.edge点滤波
基本思想:Mark点指的是我们要寻找的细胞内的点。我们先获取每一个像素点的RGB 分量,然后我们将其转化成HSI分量,将H分量进行归一化,因为S的范围是0到1,所以我们要进行尺度的一致,这样才具有可计算性。然后我们通过每个像素点的H分量和S分量的值与细胞内部的H分量和S分量计算欧几里得距离,设定一个Mark门限值(我们这里将MarkDoor设置为,大家可以行设置合适的参数),小于这个门限值我们就当做是细胞的内部,然后对细胞进行标记(Red)。还需要设定一个Maybe Mark门限值(我们这里将Maybe MarkDoor设置为,大家可以行设置合适的参数),我们大于Mark门限值小于Maybe Mark 门限值时,我们暂时看成是细胞,我们进行Maybe Mark的标记(Blue)。否则的话,我们需要考虑,一些不是Mark和Maybe Mark点的*lpSrc==0我们区别一下赋值为1,*lpSrc==255
我们区别一下赋值为254,*(lpSrc+1)==255我们区别一下赋值为254.这样的话,我们在后面判断是否为Mark点的时候,我们只需要判断*lpSrc是否为0就可以了,判断Maybe Mark 点时只需要判断*(lpSrc)是否为255就可以了。对于边缘的判断只需要判断*(lpSrc+1)是否为255就可以了。
将细胞标记为Mark用红色(255,0,0)标记出来,将可能是的细胞标记为MayBe Mark 用蓝色(0,0,255)标记出来。将MayBeMark To Mark的区域用亮红(128,0,0)表示,将不可能是细胞的区域、细胞边界分别用绿色标记出来。
操作过程:
(1)根据H、S的欧几里得距离sqrt(s2+h2)来大致的确定哪些是细胞(Mark)和可能是细胞(Maybe Mark)的点。
(2)根据Maybe Mark点周围的情况,如果它的上下左右四个方向有Mark点,则将Maybe Mark点变成Mark点。
(3)用Sobel算子来做边缘的提取边界(0,255,255)(255,255,0),使用3*3的模板,使用欧几里得距离来判断是否为边缘。
两种Sobel算子如下:
主要代码如下:
doubletmp1=pixel[0]+2*pixel[1]+pixel[2]-pixel[6]-2*pixel[7]-pixel[8]; doubletmp2=pixel[0]+2*pixel[3]+pixel[6]-pixel[2]-2*pixel[5]-pixel[8]; double edge=sqrt(tmp1*tmp1+tmp2*tmp2);
if(edge>edgeDoor)
*(lpDst+1)=255;
adius<(j).radius) pt=(i);*/
(i).x=(x+x0)/2;=(y+y0)/2;
(i).radius=max(i).radius,(j).radius)+4;
pt=pt=(i);
d)在无相近点的情况下,若半径小于8,则删除。
主要代码如下:
if(bdelete)
{
("去掉潜在的错误(圆r<8 Redpen)后数目=%d",());
MessageBox(msg);
}
e)两圆相交,若其中一圆非相交部分面积小于50%,则删除
主要代码如下:
if (total (int)(tota/()+.5), *min[0]/,*max[0]/, *min[1]/,*max[1]/, *min[2]/,*max[2]/; 10、All-steps 可以一次性实现细胞识别的所有操作步骤 设置控制按键的权限,点击update_command_ui ,键入控制条件 每步操作时给cellprocess设置不同数值,表示那步进行过,只能进行规定的下步操作,从而在运行过程中放置按键误触导致程序崩溃。 11、扩展: 区域选择: 建立类向导:OnButtonDown 和OnButtonUp 键入代码: 在OnDraw中添加下列代码 注意:bool 变量m_bDrag要定义在文件头部,定义在会出现第一次区域选择时出现错误。 添加复位按键: 点击该键后会重新读取图像(和图像自动打开代码一样) 第三部分 12、各步骤结果和错误举例 ①各步骤结果图 a.Mark(Red)& MayBe Mark(Blue) maybemark to mark(black red) edge information and edge filter twovalue fillholes shrink findcenter count 出现的错误举例: Mousemove 程序中出现问题:1.错误: 没有加#include ""头文件 2.错误 error C2248: 'm_wndStatusBar' : cannot access protected member declared in class 'CMainFrame' 需将protected: 和.cpp文件仍然存在 解决方案:先保存workspace,然后关闭工程,删除此工程目录中的.ncb文件,重新打开workspace 原因:classview显示混乱在类中添加的成员变量和成员函数不能显示出来,即使显示出来了变量或函数,双击后不能跳至正确的位置。 Edge information中出现问题 正常不正常 memcpy(lpNewDIBBits,lpSrc,lHeight *lLineBytes); 代码应放在图像处理前,参考图像是初始状态的图像,把第一步的四个小步骤分开写在不同的函数内时,因为每一小步的操作都会改变图像的状态,如果把: memcpy(lpNewDIBBits,lpSrc,lHeight *lLineBytes); 写在maybemark_to_mark之后那么参考图像就不是原始图像 发现:做到shrink时,看到收缩后的图像效果很差,和标准收缩图像相差较大,经调试后发现问题(没注意ppt最后一页有,老师在qq群在中也提到过)。 Shrink操作后,关闭图像,出现问题 GenEdge4()函数中出现问题 for (int j=0;j 和 for (int j=0;j for循环问题 有差异 后面起始点地址为dot1 前面起始点地址为dot1+1,不处理四周边界 可以把第二个for循环语句中前面的i=0 改成i=1. 观察图像,发现Shirnk后未保存填洞点,结果只有0x00 0x80 0xf0 等同于temp[n].y 13、心得体会 通过对本次数字图像处理课程设计的学习,进一步加深了对数图知识的理解,同时也基本掌握了VC++软件的使用方法。从一开始的连图像都无法打开,到最后在老师上课的资料以及同学的帮助和学长的参考程序下终于完成了一幅细胞图像的整个识别过程。自己一向在编程方面有所欠缺,通过咨询老师和同学还有百度,自己也慢慢理解了所写程序代码的含义,间接地提高了自己写代码与识别代码的能力。 通过一个星期多的学习,我对细胞识别的基本思想有了深一步的理解,也让我对c语言 相关的知识得到了回顾。此次课程设计给我们提供了一个既能学习又能锻炼的机会,使我们养成了查找资料(主要是在百度上查阅一些代码的含义)的习惯,将理论与实际相结合起来,锻炼了分析问题和实际解决问题的能力。提高了适应能力,为今后的学习和实践打下了基础。