matlab图像细化函数,把MATLAB的细化函数bwmorph改成纯VC版的艰辛经历【原创】

%以下示范调用MATLAB的细化函数

I = imread('BW.bmp');

I2 = bwmorph(I, 'thin',Inf);

figure,imshow(I)

figure,imshow(I2)

可以看出,MATLAB的细化效果是很好的,相比之下,网上找的一些代码的效果就差很多了。MATLAB很强大!

我通过设置断点,进入MATLAB底层,看看BWMORPH这个函数是怎么样的,把程序实际运行了的代码抠出来,得到以下结果:

%

I = imread(BW.bmp');

I2 = thin(I, Inf);

figure,imshow(I)

figure,imshow(I2)

function cout= thin(a,n)

c = a;

iter = 1;

done = n == 0;

while (~done)

lastc =

c;

c=

iptThin(c);

done =

((iter >= n) | isequal(lastc, c));

iter = iter

+ 1;

end

cout = c;

function c= iptThin(a)

lut = [];

if (isempty(a))

c =

zeros(size(a));

return;

end

lut1 = lutthin1;

image_iter1 = applylutc(a, lut1);

lut2 = lutthin2;

c = applylutc(image_iter1, lut2);

function lut = lutthin1

lut =

[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;0;1;1;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;1;1;0;0;1;1;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;0;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0;0;0;1;0;0;1;1;0;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;];

function lut = lutthin2

lut =

[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;0;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;0;0;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;0;0;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;1;0;0;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;0;0;1;1;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;1;0;0;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;1;0;1;1;1;0;0;1;1;0;1;1;1;];

现在关键就是applylutc这个函数没有抠出来了!

好家伙,你猜这个函数是在哪里?原来是在TOOLBOX\IMAGE目录下面的一个MEXW32文件,也就是DLL.于是,我找到该DLL对应的C文件,啃了起来。这些东西调来调去的,还真是复杂,我用VC重新建立了一个DLL工程,然后通过MATLAB调试进入DLL,找出需要的代码。最终,成功改为C++代码。完全不需要MATLAB的支持!而且,效果和MATLAB的保持一致!

代码如下:

//##########图像细化######################################

//2009年12月6日

//PEAK Sun Yat-sen University

//使用须知:

//只需调用void Thin(IMAGE Src, IMAGE& Dst, int n)即可.

//参数n可以取一个很大的数,比如说1000.

//图像结构体

typedef struct tagIMAGE

{

BYTE * imageData;  //指向图像数据区域的指针

int width;  //图像的宽度

int height;  //图像的高度

int widthstep;  //图像每行所占得字节数

} IMAGE;

#define INIT_IMAGE(Img, wid, hei, widstep){if(Img.imageData !=

0) delete [] Img.imageData;\

Img.imageData = new BYTE [(widstep) * (hei)];

memset(Img.imageData, 0, sizeof(BYTE) * (widstep) * (hei));\

Img.width = (wid); Img.height = hei;

Img.widthstep = widstep;}

//释放

#define RLSE_BUFFER(x) {if (x != 0) delete [] x; x = NULL;}

#define MATRIX_REF(PR, NUMROWS, R, C) \

(*((PR) + (NUMROWS)*(C) + (R)))

static int weights3[3][3] = { {1, 8, 64}, {2, 16, 128}, {4, 32,

256} };

int iptNhood3Offset(unsigned char *pBWin, int numRows, int

numCols,

int r, int c)

{

int minR, maxR, minC,

maxC;

int rr, cc;

int result = 0;

if (r == 0) {

minR = 1;

} else {

minR = 0;

}

if (r == (numRows-1))

{

maxR = 1;

} else {

maxR = 2;

}

if (c == 0) {

minC = 1;

} else {

minC = 0;

}

if (c == (numCols-1))

{

maxC = 1;

} else {

maxC = 2;

}

for (rr = minR; rr <=

maxR; rr++) {

for (cc = minC; cc <= maxC; cc++) {

result +=

weights3[rr][cc] *

(MATRIX_REF(pBWin, numRows, r + rr - 1, c + cc - 1) != 0);

}

}

return(result);

}

void iptMyapplylutc(IMAGE BWin, IMAGE& BWout, BYTE*

lut)

{

int numRows, numCols;

int r, c;

unsigned char *pBWin;

unsigned char *plut;

unsigned char *pBWout;

pBWin =

BWin.imageData;

plut = lut;

pBWout = BWout.imageData;

numRows =

BWin.height;

numCols = BWin.width;

for (c = 0; c <

numCols; c++) {

for (r = 0; r < numRows; r++) {

MATRIX_REF(pBWout, numRows, r, c) = (unsigned char)

(*(plut + iptNhood3Offset(pBWin, numRows, numCols, r, c)) == 0?

0: 255);

}

}

}

//图像细化导出函数

void Thin(IMAGE Src, IMAGE& Dst, int n)

{

int i, j;

int wid = Src.width;

int hei = Src.height;

int widEff = Src.widthstep;

int nSize = wid * hei * sizeof(BYTE);

IMAGE mySrc, myDst,c, lastc, image_iter1;

mySrc.imageData = NULL; INIT_IMAGE(mySrc, wid, hei, wid);

myDst.imageData = NULL; INIT_IMAGE(myDst, wid, hei, wid);

c.imageData = NULL; INIT_IMAGE(c, wid, hei, wid);

lastc.imageData = NULL; INIT_IMAGE(lastc, wid, hei, wid);

image_iter1.imageData = NULL; INIT_IMAGE(image_iter1, wid, hei,

wid);

//mySrc, myDst,...

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

{

for (j = 0; j < wid; j++)

{

*(mySrc.imageData + j * hei + i)  =

*(Src.imageData + i * widEff + j);

*(myDst.imageData + j * hei + i)  =

*(Src.imageData + i * widEff + j);

*(c.imageData + j * hei + i)  = *(Src.imageData

+ i * widEff + j);

*(lastc.imageData + j * hei + i)  =

*(Src.imageData + i * widEff + j);

*(image_iter1.imageData + j * hei + i)  =

*(Src.imageData + i * widEff + j);

}

}

unsigned char lut1[512] =

{

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1

,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,

1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1

,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,

1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1

,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,

1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1

,1,1,1,1,1,1,1,1,1,1,1,1};

unsigned char lut2[512] =

{

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,0,1,1,1,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,0,1,1,1,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,0,1,1,1,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,1,1,0,1,1,1};

int iter = 1;

bool done = 0;

bool equalC;

while (!done)

{

memcpy(lastc.imageData, c.imageData, nSize);

iptMyapplylutc(c, image_iter1, lut1);

iptMyapplylutc(image_iter1, c, lut2);

for (i = 0; i < nSize; i++){ if ( *(lastc.imageData+i) !=

*(c.imageData+i) ) {equalC = 0; break;}}

done = ((iter >= n) | equalC);

iter++;

}

//返回结果

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

{

for (j = 0; j < wid; j++)

{

*(Dst.imageData + i * widEff + j)  =

*(c.imageData + j * hei + i);

}

}

//释放空间

RLSE_BUFFER(mySrc.imageData);

RLSE_BUFFER(myDst.imageData);

RLSE_BUFFER(c.imageData);

RLSE_BUFFER(lastc.imageData);

RLSE_BUFFER(image_iter1.imageData);

}

//##########END:图像细化######################################

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值