分享
 
 
 

并行图像细化算法和C代码实现

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

并行图像细化算法和C代码实现

图像细化一般作为一种图像预处理技术出现,目的是提取源图像的骨架,即是将原图像中线条宽度大于1个象素的线条细化成只有一个象素宽,形成'骨架',形成骨架后能比较容易的分析图像,如提取图像的特征.

细化分成串行细化和并行细化2中,串行细化即是一遍检测满足细化条件的点一边删除细化点,并行细化即是检测细化点的时候不进行点的删除只进行标记,而在检测完整幅图像后一次性去除要细化的点.

细化基本思想是'层层剥夺',即从线条边缘开始一层一层向里剥夺,直到线条剩下一个象素的为止.

进行细化算法前要先对图像进行2值化,即图像中直包含'黑'和'白'2中颜色.

细化算法:

在微观上取检测点的8个临域(由于是并行细化,有些模板要扩展为12临域),如下

xxx

xox

xxx

其中o为检测点x为其相邻点

以下用1代表黑色点,用0代表白色点,用x代表任意颜色的点,要剥夺(删除)的点应满足一下8个模板中的一个.

模板a(向右扩大)

0x1x

0111

0x1x

模板b(向右扩大)

00xx

0111

x11x

模板c(向右扩大)

x11x

0111

00xx

模板d

111

x1x

000

模板e

1x0

110

1x0

模板f

x00

110

x1x

模板g

x1x

110

x00

模板h(向下扩大)

000

x1x

111

x1x

符合以上8个模板的点为要剥夺的点,因为符合这8个模板的点可以确认为线条边沿上的点.

而试事实上经过这8个模板并行细化后还有下面2种特殊的边沿点保留了下来,

特殊边沿点1

000

010

111

特殊边沿点2

001

011

001

造成这种2种特殊点的原因扩大后的模板a和扩大后的模板h,扩大的的本意是防止偶数列(行)的线条被完全消去(并行细化并然的).

解决方法是在并行细化后再进行一次串行细化,选取缩小后的模板a和模板h

模板a(缩小后)

0x1

011

0x1

模板h(缩小后)

000

x1x

111

其中缩小后的模板a解决了特殊情况1,缩小后的模板h解决了特殊情况2,注意这次是串行细化了.一下根据这个原理用C++Builder6.0实现,关键代码如下.

//--------------------------------BCB6 代码

#include <vcl.h>

#pragma hdrstop

#include<stdio.h>

#include "Unit1.h"

#include"File1.h"

#include<math.h>

#include<time.h>

#include<vector>

#pragma pack(1)

using namespace std;

/*

程序:图像细化

作者:sboom(Lingch)

日期:05年1月18日

*/

//BMP文件头

struct BITMAPFILEHEADER_

{

short type;

int bfSize;

short re1,re2;

int Offbits;

};

//BMP信息头

struct BITMAPINFO_

{

long size;

long width,height;

short planes,bitCount;

long comp,sizeImg;

long xpels,ypels;

long used,important;

};

//------将BMP彩色表的数据校正到BCB 的TColor的数据。

TColor* SwitchColor(unsigned char r,unsigned char g,unsigned char b)

{

TColor *re=new TColor;

*re=(r | g<<8 | b<<16 );

*re=*re & 0x00ffffff;

return re;

}

void xxx()

{

FILE *f=fopen("f:\\1.bmp","rb");

if(f==NULL) /*判断文件是否打开成功*/

{

ShowMessage("File open error");

return;

}

fseek(f,0,0);//移动到开头

//----------读BMP文件头

BITMAPFILEHEADER_ *bmph=new BITMAPFILEHEADER_();

if(fread((char*)bmph,sizeof(BITMAPFILEHEADER_),1,f)==NULL)

{

ShowMessage("File read error");

return;

}

//-----------读BMP信息头

BITMAPINFO_ *bmpi=new BITMAPINFO_();

if(fread((char*)bmpi,sizeof(BITMAPINFO_),1,f)==NULL)

{

ShowMessage("File read 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);

int i,j,k,l,wc,pos;

long N=bmph->bfSize- bmph->Offbits;//象素总数

unsigned char *image=new unsigned char[N]; //位图矩阵

fread(image,N,1,f);//读入位图矩阵

int skip=0; //BMP 文件4字节对齐

if(bmpi->width%4==0)

skip=0;

else

skip=4-bmpi->width%4;

unsigned char color=0;

TColor *tc;

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

//2值化

for(i=0;i<N;i++)

{

if((unsigned char)image[i]<0xa0)

image[i]=(unsigned char)0;

else

image[i]=(unsigned char)0xff;

}

//

int flag=1;

long x,b;

unsigned char *om=new unsigned 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;j<bmpi->width-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;i<N;i++)

{

if(om[i]==0xff)

{

image[i]=0xff;

}

}

}

//-------------第二次串行细化

for( i=2;i<bmpi->height-2;i++)

{

for(j=2;j<bmpi->width-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;i<bmpi->height;i++)

{

for(j=0;j<bmpi->width;j++)

{

//-----原始图形

color=image[(i)*(bmpi->width+skip)+j];

tc=SwitchColor(color,color,color);

Form1->Canvas->Pixels[10+j][400-i]=*tc;

}

}

//----------关闭文件

fclose(f);

}

//------------------------------------------------------------------------

原图和细化效果图对比

细化是常用的图像预处理技术,目前也有很多图像细化算法,细化后能更好的分析图像,现在很多图像的特征提取,特征分析算法是基于细化后的图像的.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有