并行图像细化算法和C代码实现 选择自sboom的Blog并行图像细化算法和C代码实现图像细化一般作为一种图像预处理技术出现,目的是提取源图像的骨架,即是将原图像中线条宽度大于1个象素的线条细化成只有一个象素宽,形成'骨架',形成骨架后能比较容易的分析图像,如提取图像的特征.细化分成串行细化和并行细化2中,串行细化即是一遍检测满足细化条件的点一边删除细化点,并行细化即是检测细化点的时候不进行点的删除只进行标记,而在检测完整幅图像后一次性去除要细化的点.细化基本思想是'层层剥夺',即从线条边缘开始一层一层向里剥夺,直到线条剩下一个象素的为止.进行细化算法前要先对图像进行2值化,即图像中直包含'黑'和'白'2中颜色.细化算法:ﻫ在微观上取检测点的8个临域(由于是并行细化,有些模板要扩展为12临域),如下ﻫxxxﻫxoxﻫxxxﻫ其中o为检测点x为其相邻点ﻫ以下用1代表黑色点,用0代表白色点,用x代表任意颜色的点,要剥夺(删除)的点应满足一下8个模板中的一个.ﻫ模板a(向右扩大)ﻫ0x1x01110x1xﻫ模板b(向右扩大)ﻫ00xxﻫ0111ﻫx11x模板c(向右扩大)x11xﻫ011100xxﻫ模板dﻫ111x1x000模板e1x0ﻫ110ﻫ1x0模板fx00ﻫ110x1x模板gﻫx1xﻫ110x00ﻫ模板h(向下扩大)ﻫ000ﻫx1xﻫ111x1x符合以上8个模板的点为要剥夺的点,因为符合这8个模板的点可以确认为线条边沿上的点.而试事实上经过这8个模板并行细化后还有下面2种特殊的边沿点保留了下来,特殊边沿点1000ﻫ010111特殊边沿点2ﻫ001ﻫ011ﻫ001ﻫ造成这种2种特殊点的原因扩大后的模板a和扩大后的模板h,扩大的的本意是防止偶数列(行)的线条被完全消去(并行细化并然的).解决
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
是在并行细化后再进行一次串行细化,选取缩小后的模板a和模板h模板a(缩小后)ﻫ0x1011ﻫ0x1模板h(缩小后)ﻫ000x1xﻫ111ﻫ其中缩小后的模板a解决了特殊情况1,缩小后的模板h解决了特殊情况2,注意这次是串行细化了.一下根据这个原理用C++Builder6.0实现,关键代码如下.//--------------------------------BCB6代码ﻫ#include
ﻫ#include"Unit1.h"#include""ﻫ#includeﻫ#include#pragmapack(1)ﻫusingnamespacestd;/* 程序:图像细化ﻫ 作者:sboom(Lingch)ﻫ 日期:05年1月18日*///BMP文件头struct BITMAP{short type;ﻫ intbfSize;ﻫshortre1,re2;ﻫ intOffbits;};//BMP信息头ﻫstructBITMAPINFO_ﻫ{ﻫlongsize;longwidth,height;shortplanes,bitCount;longcomp,sizeImg;ﻫlong xpels,ypels;ﻫlong used,important;ﻫ};//------将BMP彩色表的数据校正到BCB的TColor的数据。ﻫTColor*SwitchColor(unsignedcharr,unsignedcharg,unsignedcharb){ﻫ TColor*re=newTColor;ﻫ *re=(r |g<<8|b<<16 ); *re=*re&0x00ffffff; returnre;ﻫ}void xxx(){ﻫ FILE*f=fopen("f:\\1.bmp","rb");ﻫ if(f==NULL) /*判断文件是否打开成功*/ﻫ {ﻫ ShowMessage("error"); return; } fseek(f,0,0);//移动到开头 //----------读BMP文件头ﻫ BITMAP *bmph=new BITMAP(); if(fread((char*)bmph,sizeof(BITMAP),1,f)==NULL) { ShowMessage("error"); return;ﻫ } //-----------读BMP信息头ﻫ BITMAPINFO_*bmpi=newBITMAPINFO_(); if(fread((char*)bmpi,sizeof(BITMAPINFO_),1,f)==NULL)ﻫ {ﻫ ShowMessage("error2"); return; }ﻫ fseek(f,bmph->Offbits,0);ﻫ //----------显示一些信息ﻫ Form1->Edit1->Text=IntToStr(bmph->bfSize);ﻫ Form1->Edit2->Text=IntToStr(bmpi->width);ﻫ Form1->Edit3->Text=IntToStr(bmpi->height); Form1->Edit4->Text=IntToStr(bmpi->comp); Form1->Edit5->Text=IntToStr(bmpi->used); inti,j,k,l,wc,pos;ﻫ longN=bmph->bfSize-bmph->Offbits;//象素总数ﻫ unsignedchar *image=newunsignedchar[N];//位图矩阵 fread(image,N,1,f);//读入位图矩阵 intskip=0; //BMP文件4字节对齐ﻫ if(bmpi->width%4==0) skip=0;ﻫ else skip=4-bmpi->width%4;ﻫ unsignedcharcolor=0; TColor*tc; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //2值化 for(i=0;i<N;i++) { if((unsignedchar)image[i]<0xa0) image[i]=(unsignedchar)0; elseﻫ image[i]=(unsignedchar)0xff; } //ﻫ intflag=1;ﻫ longx,b; unsignedchar*om=newunsigned char[N];//标记矩阵 for(i=0;i<N;i++) //初始化 om[i]=0; while(flag==1) //flag=0时迭代结束ﻫ { flag=0; for(i=2;i<bmpi->height-2;i++)ﻫ { for(j=2;jwidth-2;j++)ﻫ {ﻫ //模板a if(image[(i-1)*(bmpi->width+skip)+j-1]==0xffﻫ &&image[(i-1)*(bmpi->width+skip)+j+1]==0 && image[(i)*(bmpi->width+skip)+j-1]==0xffﻫ &&image[(i)*(bmpi->width+skip)+j-0]==0 &&image[(i)*(bmpi->width+skip)+j+1]==0ﻫ && image[(i)*(bmpi->width+skip)+j+2]==0ﻫ &&image[(i+1)*(bmpi->width+skip)+j-1]==0xff &&image[(i+1)*(bmpi->width+skip)+j+1]==0) { om[(i)*(bmpi->width+skip)+j]=0xff;ﻫ flag=1;ﻫ continue; } //模板b if(image[(i-1)*(bmpi->width+skip)+j-0]==0 && image[(i-1)*(bmpi->width+skip)+j+1]==0 &&image[(i)*(bmpi->width+skip)+j-1]==0xffﻫ && image[(i)*(bmpi->width+skip)+j-0]==0 &&image[(i)*(bmpi->width+skip)+j+1]==0 &&image[(i)*(bmpi->width+skip)+j+2]==0ﻫ &&image[(i+1)*(bmpi->width+skip)+j-1]==0xff && image[(i+1)*(bmpi->width+skip)+j-0]==0xff) { om[(i)*(bmpi->width+skip)+j]=0xff; flag=1;ﻫ continue;ﻫ } //模板c if(image[(i-1)*(bmpi->width+skip)+j-1]==0xff &&image[(i-1)*(bmpi->width+skip)+j-0]==0xffﻫ && image[(i)*(bmpi->width+skip)+j-1]==0xffﻫ &&image[(i)*(bmpi->width+skip)+j-0]==0ﻫ && image[(i)*(bmpi->width+skip)+j+1]==0ﻫ &&image[(i)*(bmpi->width+skip)+j+2]==0ﻫ && image[(i+1)*(bmpi->width+skip)+j-0]==0 &&image[(i+1)*(bmpi->width+skip)+j+1]==0) {ﻫ om[(i)*(bmpi->width+skip)+j]=0xff; flag=1; continue;ﻫ } //模板d if(image[(i-1)*(bmpi->width+skip)+j-1]==0xff &&image[(i-1)*(bmpi->width+skip)+j-0]==0xffﻫ &&image[(i-1)*(bmpi->width+skip)+j+1]==0xffﻫ &&image[(i)*(bmpi->width+skip)+j-0]==0ﻫ &&image[(i+1)*(bmpi->width+skip)+j-1]==0ﻫ &&image[(i+1)*(bmpi->width+skip)+j-0]==0 && image[(i+1)*(bmpi->width+skip)+j+1]==0)ﻫ {ﻫ om[(i)*(bmpi->width+skip)+j]=0xff;ﻫ flag=1;ﻫ continue; } //模板eﻫ if(image[(i-1)*(bmpi->width+skip)+j-1]==0 &&image[(i-1)*(bmpi->width+skip)+j+1]==0xff && image[(i)*(bmpi->width+skip)+j-1]==0 &&image[(i)*(bmpi->width+skip)+j-0]==0ﻫ &&image[(i)*(bmpi->width+skip)+j+1]==0xffﻫ &&image[(i+1)*(bmpi->width+skip)+j-1]==0ﻫ &&image[(i+1)*(bmpi->width+skip)+j+1]==0xff)ﻫ { om[(i)*(bmpi->width+skip)+j]=0xff; flag=1; continue;ﻫ } //模板f if(image[(i-1)*(bmpi->width+skip)+j-0]==0 &&image[(i)*(bmpi->width+skip)+j-1]==0 &&image[(i)*(bmpi->width+skip)+j-0]==0ﻫ &&image[(i)*(bmpi->width+skip)+j+1]==0xffﻫ && image[(i+1)*(bmpi->width+skip)+j-0]==0xff &&image[(i+1)*(bmpi->width+skip)+j+1]==0xff) {ﻫ om[(i)*(bmpi->width+skip)+j]=0xff;ﻫ flag=1;ﻫ continue; } //模板gﻫ if(image[(i-1)*(bmpi->width+skip)+j-0]==0xff &&image[(i-1)*(bmpi->width+skip)+j+1]==0xffﻫ &&image[(i)*(bmpi->width+skip)+j-1]==0ﻫ &&image[(i)*(bmpi->width+skip)+j-0]==0 &&image[(i)*(bmpi->width+skip)+j+1]==0xffﻫ &&image[(i+1)*(bmpi->width+skip)+j-0]==0) {ﻫ om[(i)*(bmpi->width+skip)+j]=0xff;ﻫ flag=1; continue;ﻫ } //模板hﻫ if(image[(i-2)*(bmpi->width+skip)+j-0]==0ﻫ &&image[(i-1)*(bmpi->width+skip)+j-1]==0 &&image[(i-1)*(bmpi->width+skip)+j-0]==0ﻫ &&image[(i-1)*(bmpi->width+skip)+j+1]==0 &&image[(i)*(bmpi->width+skip)+j-0]==0ﻫ &&image[(i+1)*(bmpi->width+skip)+j-1]==0xffﻫ &&image[(i+1)*(bmpi->width+skip)+j-0]==0xff &&image[(i+1)*(bmpi->width+skip)+j+1]==0xff) { om[(i)*(bmpi->width+skip)+j]=0xff; flag=1; continue; }ﻫ }ﻫ } for(i=0;iheight-2;i++) {ﻫ for(j=2;jwidth-2;j++) {ﻫ //缩小后的模板aﻫ if(image[(i-1)*(bmpi->width+skip)+j-1]==0xff && image[(i-1)*(bmpi->width+skip)+j+1]==0 &&image[(i)*(bmpi->width+skip)+j-1]==0xffﻫ &&image[(i)*(bmpi->width+skip)+j-0]==0 &&image[(i)*(bmpi->width+skip)+j+1]==0 &&image[(i+1)*(bmpi->width+skip)+j-1]==0xffﻫ && image[(i+1)*(bmpi->width+skip)+j+1]==0) { image[(i)*(bmpi->width+skip)+j]=0xff;ﻫ flag=1; continue;ﻫ } //缩小后的模板h if(image[(i-1)*(bmpi->width+skip)+j-1]==0ﻫ &&image[(i-1)*(bmpi->width+skip)+j-0]==0ﻫ && image[(i-1)*(bmpi->width+skip)+j+1]==0ﻫ &&image[(i)*(bmpi->width+skip)+j-0]==0 &&image[(i+1)*(bmpi->width+skip)+j-1]==0xff && image[(i+1)*(bmpi->width+skip)+j-0]==0xff &&image[(i+1)*(bmpi->width+skip)+j+1]==0xff)ﻫ {ﻫ image[(i)*(bmpi->width+skip)+j]=0xff; flag=1;ﻫ continue;ﻫ } } }ﻫ //---------------显示图形 for(i=0;iheight;i++)ﻫ { for(j=0;jwidth+skip)+j]; tc=SwitchColor(color,color,color);ﻫ Form1->Canvas->Pixels[10+j][400-i]=*tc;ﻫ }ﻫ } //----------关闭文件 fclose(f);}//------------------------------------------------------------------------原图和细化效果图对比ﻫ细化是常用的图像预处理技术,目前也有很多图像细化算法,细化后能更好的分析图像,现在很多图像的特征提取,特征分析算法是基于细化后的图像的.