细胞识别-图像处理课件_第1页
细胞识别-图像处理课件_第2页
细胞识别-图像处理课件_第3页
细胞识别-图像处理课件_第4页
细胞识别-图像处理课件_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数字图像处理

---课程设计

姓名:杜培明、王立Email:dpm@Email:wli1129@163.com安工大电信学院机器视觉—框图机器视觉—应用机器视觉—应用机器视觉—举例ReadingofSerialNumbers机器视觉—举例InspectionofSawBlades机器视觉—举例SurfaceInspection

机器视觉—举例3d_plane_reconstruction_with_stereo机器视觉—举例冷轧带钢边部缺陷在线检测细胞识别—原图24bit目标图细胞

个数大小标注(Red)-可能标注(Blue)RGB信息非细胞:细胞:1:Area:(169,200)Mean=1842:Area:(111,158)Mean=1273:Area:(153,193)Mean=1771:Area:(166,237)Mean=1982:Area:(144,226)Mean=1813:Area:(146,213)Mean=176HSI信息细胞:非细胞:结论:利用H、S区分1:Area:(208,232)Mean=2162:Area:(22,74)Mean=553:Area:(153,185)Mean=1631:Area:(225,36)Mean=32:Area:(2,31)Mean=133:Area:(158,219)Mean=186图像信息获取RGB:lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes*(lHeight-1-point.y)+point.x*3;Rgbrgb;rgb.b=*lpSrc;rgb.g=*(lpSrc+1);rgb.r=*(lpSrc+2);

structRgb{ unsignedchar b; unsignedchar g; unsignedchar r;};intgray=(int)(0.114*rgb.r+0.587*rgb.g+0.299*rgb.b);亮度:RGB----HSI函数代码RgbtoHsi(Rgb*pRgb,HSI*pHsi)R=((double)pRgb->r)/255.0;G=((double)pRgb->g)/255.0;B=((double)pRgb->b)/255.0;Sum=R+G+B;pHsi->Intensity=Sum/3.0;

MinValue=(R<G)?R:G;MinValue=(B<MinValue)?B:MinValue;MaxValue=(R>G)?R:G;MaxValue=(B>MaxValue)?B:MaxValue;if(pHsi->Intensity<0.00001) pHsi->Saturation=ZERO_SATURATION;else pHsi->Saturation=1.0-(3.0*MinValue)/Sum;

函数代码RgbtoHsi(Rgb*pRgb,HSI*pHsi)if(MinValue==MaxValue){ pHsi->Hue=UNDEFINED_HUE; pHsi->Saturation=ZERO_SATURATION; return;

} TempDouble1=(((R-G)+(R-B))/2.0); TempDouble2=(R-G)*(R-G)+(R-B)*(G-B); Quotient=(TempDouble1/sqrt(TempDouble2)); Radians=acos(Quotient); Angle=Radians*DEGREES_PER_RADIAN; pHsi->Hue=(B>G)?360.0–Angle:Angle;函数调用OnMouseMove(UINTnFlags,CPointpoint) CStringstr=""; if(pDoc->m_pDib->m_lpBMIH){ unsignedchar*lpSrc; if((point.x>0)&&(point.x<lWidth)&&(point.y>0)&&(point.y<lHeight)){

if(pDoc->m_pDib->m_lpBMIH->biBitCount==8){ lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes*(lHeight-1-point.y)+point.x; str.Format(L"(x=%dy=%d)=%d",point.x,point.y,*lpSrc);

}函数调用OnMouseMove(UINTnFlags,CPointpoint)elseif(pDoc->m_pDib->m_lpBMIH->biBitCount==24){lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+ lLineBytes*(lHeight-1-point.y)+point.x*3; Rgbrgb; HSIHsi; rgb.b=*lpSrc;rgb.g=*(lpSrc+1);rgb.r=*(lpSrc+2); RgbtoHsi(&rgb,&Hsi); intgray=(int)(0.114*rgb.r+0.587*rgb.g+0.299*rgb.b); str.Format(L"Pos(%d%d)RGB(%d%d%d)Gray(%d)HSI(%4.1f %3.2f%3.2f--%d%d%d)“, point.x,point.y,rgb.r,rgb.g,rgb.b,gray, Hsi.Hue,Hsi.Saturation,Hsi.Intensity, (int)(Hsi.Hue/360.0*255.0),(int)(Hsi.Saturation*255.0),(int)(Hsi.Intensity*255.0));

}((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0,str);

函数代码OnCellprocessMark()//不要取中心点,应该向远离背景方向偏移(小)doublemeanH=210.0*360/255;//youselectdoublemeanS=55.0/255;//youselectdoubleMarkDoor=0.09;doubleMayBeMarkDoor=0.15;

doublex1=Hsi.Hue;//0—360doublex2=meanH;//近似if(x1<90)x1+=360;

//归一化doubley1=Hsi.Saturation;doubley2=meanS;x1/=360;x2/=360;//0--1doubledis=DISTANCE(x1,y1,x2,y2);

函数代码OnCellprocessMark()if(dis<MarkDoor){//Mark *lpSrc=0;*(lpSrc+1)=0;*(lpSrc+2)=255;//Red

} elseif(dis<MayBeMarkDoor){//maybeMark

*lpSrc=255;*(lpSrc+1)=0;*(lpSrc+2)=0;//Blue

} else{//notMark/maybeMark if(*lpSrc==0)*lpSrc=1;//Mark elseif(*lpSrc==255)*lpSrc=254;//maybemark if(*(lpSrc+1)==255)*(lpSrc+1)=254;//edge

}

}

} YouRWork1.OpenImage2.AddRgbtoHsi

3.AddOnMouseMove4.SelectThreshold5.AddMenu(&Mark)Doityourself!WeCanHelp!MaybeMarkedtoMarkedMaybeMarkedtoMarked-codeboolMarkChg=true;while(MarkChg){MarkChg=false;for(inti=StartPoint.y;i<=EndPoint.y;i++){ for(intj=StartPoint.x;j<=EndPoint.x;j++){lpSrc=pDoc->m_pDib->m_lpImage+ lLineBytes*(lHeight-1-i)+j*3; if(*lpSrc==255){//maybeMark boolbProc=false; if(j>0)if(*(lpSrc-3)==0)bProc=true; if(j<lWidth-1)if(*(lpSrc+3)==0)bProc=true; if(i>0)if(*(lpSrc+lLineBytes)==0)bProc=true; if(i<lHeight-1)if(*(lpSrc-lLineBytes)==0)bProc=true //maybeMarkhaveMarkPointtoMark if(bProc){ *lpSrc=0; MarkChg=true; *(lpSrc+2)=128;

}}}}} Mark&Edgeedgeinformationdoublepixel[9];lpDst=pDoc->m_pDib->m_lpImage+lLineBytes*(lHeight-1-i)+j*3;if(*(lpDst)==0||*(lpDst)==255){//Mark/MaybeMark doublepixel[9]; lpSrc=lpNewDIBBits+lLineBytes*(lHeight-1-i)+j*3; for(intm=-1;m<2;m++) for(intn=-1;n<2;n++){ unsignedchar*lpSrc1=lpSrc-lLineBytes*m+3*n; pixel[(m+1)*3+n+1]=((int)*lpSrc1+*(lpSrc1+1)+*(lpSrc1+2))/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]; doubleedge=sqrt(tmp1*tmp1+tmp2*tmp2); if(edge>edgeDoor) *(lpDst+1)=255;//edge

}

EdgeFilterconstintM=5;boolbdelete;//filterfor(inti=StartPoint.y+M;i<EndPoint.y-M;i++)

{

for(intj=StartPoint.x+M;j<EndPoint.x-M;j++){

pDst=pDoc->m_pDib->m_lpImage+lLineBytes*(lHeight-1-i)+j*3;if(*(lpDst+1)==255)//edge{ bdelete=true; for(intm=-M;m<=M;m++) for(intn=-M;n<=M;n++) {if(m==-M||m==M||n==-M||n==M){ if(*(lpDst+lLineBytes*m+n*3)|| (*(lpDst+lLineBytes*m+n*3+1)==255))//noMark&&noEdge

{ bdelete=false; m=M+1;n=M+1;//out

}

}

} if(bdelete) *(lpDst+1)=0;//deleteedge

}}}二值化Marked-----Gray(128)Edge----Bright(240=0xf0)二值化OnCellprocessTwovalue():for(inti=0;i<lHeight;i++){for(intj=0;j<lWidth;j++){ lpSrc=pDoc->m_pDib->m_lpImage+ lLineBytes*(lHeight-1-i)+j*3; lpDst=lpNewDIBBits+lNewLineBytes*(lHeight-1-i)+j; unsignedintv; v=0; if(*(lpSrc)==0)//Mark

{ v=TWOVALUE_H; if(*(lpSrc+1)) v|=EDGEPOINT;//setedge

} *lpDst=(unsignedchar)v;

}

} lLineBytes=lNewLineBytes;

二值化//复制转置后的图像 delete pDoc->m_pDib; pDoc->m_pDib=newCDib(CSize(lNewLineBytes,lHeight),8);

lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpvColorTable; for(inti=0;i<256;i++){ *lpSrc=(unsignedchar)i;lpSrc++; *lpSrc=(unsignedchar)i;lpSrc++; *lpSrc=(unsignedchar)i;lpSrc++; *lpSrc=0;lpSrc++;

}

memcpy(pDoc->m_pDib->m_lpImage,lpNewDIBBits,lLineBytes*lHeight); delete[]lpNewDIBBits; Invalidate(true);YouRWork1.MaybeMarktoMark2.GetEdgeinformation3.TwoValueDoityourself!WeCanHelp!填洞填洞OnCellprocessFillholes()//0x7X---edge//0x8X---Mark--notedge//0xfX--Mark–edge//0xX1---visited

//ifno-marked&no-visitedif(!(*lpSrc&MARK_VISITED)){//未访问过的黑点 ProcessFillHoles(j,i);//line,col }//edgeareaback//0xfX--Mark–edgeif(!(*lpSrc&MARKED))//非MarkPoint *lpSrc=0;//删除访问标志 elseif(*lpSrc&EDGEPOINT)//ifmarked&edge *lpSrc=0;

填洞填洞ProcessFillHoles(intwd,intht) stack<CPoint>s; vector<CPoint>v;//vsaveforfillholes constintMAX_HOLE=100; intxt,yt; xt=wd; yt=ht; s.push(CPoint(xt,yt)); v.push_back(CPoint(xt,yt)); unsignedchar*lpSrc; lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes*(lHeight-1-yt)+xt; *lpSrc|=VISITED;//vistied boolbBorder=false;填洞ProcessFillHoles(intwd,intht)while(s.size())

{ //Addnewmemberstostack //Abovecurrentpixel lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+ lLineBytes*(lHeight-1-yt)+xt; if(yt>StartPoint.y){ //ifno-marked&no-visited if(!(*(lpSrc+lLineBytes)&MARK_VISITED))

{ s.push(CPoint(xt,yt-1)); v.push_back(CPoint(xt,yt-1)); *(lpSrc+lLineBytes)|=VISITED;

} }elsebBorder=true; //Belowcurrentpixel……………

填洞ProcessFillHoles(intwd,intht) //Leftofcurrentpixel ………. //Rightofcurrentpixel if(xt<EndPoint.x){ //ifno-marked&no-visited if(!(*(lpSrc+1)&MARK_VISITED)){ s.push(CPoint(xt+1,yt)); v.push_back(CPoint(xt+1,yt)); *(lpSrc+1)|=VISITED;

} }elsebBorder=true; //Retrievecurrentstackmember xt=s.top().x; yt=s.top().y; s.pop(); }//Backtobeginningofloop填洞ProcessFillHoles(intwd,intht)//fillhole if(v.size()<MAX_HOLE&&!bBorder)

{ //forsee if(v.size()>50){ CStringmsg; msg.Format(L"%d--(%d%d)",v.size(),wd,ht); Invalidate(true); MessageBox(msg);

} for(UINTk=0;k<v.size();k++){ xt=v[k].x; yt=v[k].y; lpSrc=pDoc->m_pDib->m_lpImage+ lLineBytes*(lHeight-1-yt)+xt; *lpSrc|=MARKED;

}

}收缩收缩OnCellprocessShrink()//先去掉pre_shrink_count层皮GenEdge();for(intk=0;k<pre_shrink_count;k++)

{ for(inti=StartPoint.y;i<=EndPoint.y;i++) { for(intj=StartPoint.x;j<=EndPoint.x;j++)

{

//去掉边界! if(*lpSrc&EDGEPOINT) (*lpSrc)&=NO_MARK;//marked=0;

}

} if(k%2==0) GenEdge4(); else GenEdge();

}收缩GenEdge(void)//八方向生成边界*lpSrc&=NO_EDGE_POINT;//noedgeif(*lpSrc&MARKED)//marked{if(j==StartPoint.y||i==StartPoint.x||j==EndPoint.y|| i==EndPoint.x) //

*lpSrc|=EDGEPOINT;

elseif//normal (!((*(lpSrc-lLineBytes-1)&MARKED) && (*(lpSrc-lLineBytes)&MARKED) && (*(lpSrc-lLineBytes+1)&MARKED) && (*(lpSrc-1)&MARKED) && (*(lpSrc+1)&MARKED) && (*(lpSrc+lLineBytes-1)&MARKED) && (*(lpSrc+lLineBytes)&MARKED) && (*(lpSrc+lLineBytes+1)&MARKED))) *lpSrc|=EDGEPOINT;

}

GenEdge4(void)YouRWork1.OnCellprocessFillholes()2.ProcessFillHoles(intwd,intht)

3.OnCellprocessShrink()Doityourself!WeCanHelp!4.GenEdge(void)、GenEdge4(void)

中心点获取中心点获取OnCellprocessFindcenter()for(intk=0;bChanged;k++)//标志中心点的腐蚀 { bChanged=false;

//清除visited标志 for(intj=StartPoint.y;j<=EndPoint.y;j++){ lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage +lLineBytes*(lHeight-1-j)+StartPoint.x-1; for(inti=StartPoint.x;i<=EndPoint.x;i++)

{ lpSrc++; *lpSrc&=NO_VISITED;//

}

}

中心点获取OnCellprocessFindcenter()if(j>StartPoint.y&&j<EndPoint.y&&i>StartPoint.x&& i<EndPoint.x)//最边上的不用处理{m_bFullEdge=true;if(*lpSrc&EDGEPOINT&&!(*lpSrc&VISITED))//没有访问过的边界{ if(!(*(lpSrc-1)&MARKED)&& !(*(lpSrc+1)&MARKED)&& !(*(lpSrc+lLineBytes)&MARKED)&& !(*(lpSrc-lLineBytes)&MARKED))

{ if(k==0)//基本上这种是噪音

continue;

中心点获取OnCellprocessFindcenter() //孤立的点 *lpSrc|=CENTERED; //保存一下CENTER_POINT信息 pt.x=i; pt.y=j; pt.radius=k+pre_shrink_count+4;//circleadjust points_temp.push_back(pt); continue;

} else MarkIt(i,j);//判断是否需要保存

//没有访问过标志了并且是边缘邻域

//需要保存! if(m_bFullEdge) SaveIt(i,j,k+pre_shrink_count+3);//保存

}

}

}中心点获取OnCellprocessFindcenter()for(intj=StartPoint.y;j<=EndPoint.y;j++){lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes* (lHeight-1-j)+StartPoint.x-1;for(inti=StartPoint.x;i<=EndPoint.x;i++){ lpSrc++;

//去掉边界! if(*lpSrc&EDGEPOINT)

{ bChanged=true; *lpSrc&=NO_MARK;

}}}if(k%2==0) GenEdge4();else GenEdge();

}

中心点获取MarkIt(inti,intj)lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes* (lHeight-1-j)+i;*(lpSrc)|=VISITED;if(j==StartPoint.y||j==EndPoint.y||i==StartPoint.x|| i==EndPoint.x)//最边上的不用处理 return;if(!(*(lpSrc-1)&VISITED)&& //没有访问过 *(lpSrc-1)&MARKED) //标志了

{ if(*(lpSrc-1)&EDGEPOINT) //并且是边缘 MarkIt(i-1,j);//左边 else m_bFullEdge=false;

}……//右下中心点获取SaveIt(inti,intj,intradius)lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes* (lHeight-1-j)+i;if(j==StartPoint.y||j==EndPoint.y||i==StartPoint.x|| i==EndPoint.x)//最边上的不用处理 return;if(!(*lpSrc&CENTERED)){ CENTER_POINTpt; pt.x=i; pt.y=j; pt.radius=radius; points_temp.push_back(pt); //markecurrentpoint *lpSrc|=CENTERED;//0x02

}*lpSrc&=NO_VISITED;

if(*(lpSrc-1)&VISITED){ SaveIt(i-1,j,radius);

}

中心点获取YouRWork1.OnCellprocessFindcenter()2.MarkIt(inti,intj)Doityourself!WeCanHelp!3.SaveIt(inti,intj,intradius)中心点获取中心点获取OnCellprocessFindcenter()if(j>StartPoint.y&&j<EndPoint.y&&i>StartPoint.x&&i<EndPoint.x) if(*lpSrc&CENTERED){ if(!(*(lpSrc-1)&CENTERED)&&!(*(lpSrc+1)&CENTERED)&& !(*(lpSrc+lLineBytes)&CENTERED)&& !(*(lpSrc-lLineBytes)&CENTERED)&& !(*(lpSrc+lLineBytes-1)&CENTERED)&& !(*(lpSrc+lLineBytes+1)&CENTERED)&& !(*(lpSrc-lLineBytes-1)&CENTERED)&& !(*(lpSrc-lLineBytes+1)&CENTERED))

{

//孤立的点保存 pt.x=i; pt.y=j; for(unsignedintn=0;n<points_temp.size();n++){ if(points_temp.at(n).x==i&& points_temp.at(n).y==j){ pt.radius=points_temp.at(n).radius; break;

}} points.push_back(pt); continue;}

中心点获取OnCellprocessFindcenter()else{//多个点求其质点 tot_num=0; max_radius=0; tot_x=0; tot_y=0; CalcCenterAverage(i,j); pt.x=tot_x/tot_area; pt.y=tot_y/tot_area; pt.radius=max_radius; *(lpSrc-(pt.y-j)*lLineBytes+pt.x-i)|=CENTERED; points.push_back(pt);

}

}

}

}msg.Format(L"取邻域(相连)中心点合并后,

获得中心点数目=%d",points.size());MessageBox(msg);中心点获取CalcCenterAverage(inti,intj)//计算其邻域(相连)中心点的质点与最大半径并去除其中心点标志lpSrc=(unsignedchar*)pDoc->m_pDib->m_lpImage+lLineBytes* (lHeight-1-j)+i;if(j==StartPoint.y||j==EndPoint.y||i==StartPoint.x||i==EndPoint.x) return;tot_num++;tot_x+=i; tot_y+=j;*lpSrc&=NO_CENTER;for(unsignedintn=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(*(lpSrc-1)&CENTERED) CalcCenterAverage(i-1,j);

中心点获取中心点获取//相近的(不相连)中心点的处理(取半径大的)for(unsignedinti=0;i<points.size();i++)

{ x0=points.at(i).x; y0=points.at(i).y; pt=points.at(i); adj=false; //Red相近-delete pdc->SelectObject(Redpen); for(unsignedintj=i+1;j<points.size()-1;j++){ intx=points.at(j).x; inty=points.at(j).y; if(abs(x0-x)+abs(y0-y)<10)//相近

{//displayerrposition--delete pt=points.at(j); if(points.at(i).radius<points.at(j).radius) pt=points.at(i); points.at(i).x=(x+x0)/2;//save points.at(i).y=(y+y0)/2 points.at(i).radius=max(points.at(i).radius, points.at(j).radius)+2;//changepoint中心点获取中心点获取//去掉潜在的错误(圆r<9) pdc->SelectObject(Redpen1); bdelete=false; for(unsignedinti=0;i<m_vCenterPoints.size();i++) { //baordareaprocess CENTER_POINTcenterp; centerp=m_vCenterPoints.at(i); if(centerp.x-centerp.radius<0) centerp.radius-=(centerp.x-centerp.radius); if(centerp.y-centerp.radius<0) centerp.radius-=(centerp.y-centerp.radius); if(centerp.x+centerp.radius>lWidth-1) centerp.radius+=(centerp.x+centerp.radius-lWidth); if(centerp.y+centerp.radius>lHeight-1) centerp.radius+=(centerp.y+centerp.radius-lHeight); if(m_vCenterPoints.at(i).radius<9)//needadjust<

{m_vCenterPoints.erase(m_vCenterPoints.begin()+i i--; bdelete=true;

}

}

中心点获取中心点获取 pdc->SelectObject(Bluepen1);

//去掉潜在的错误(同两个圆相交,并且不相交的部分是噪声) for(unsignedinti=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(unsignedintj=0;j<m_vCenterPoints.size();j++)

{ if(i==j) continue; intx=m_vCenterPoints.at(j).x; inty=m_vCenterPoints.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论