%以下示范调用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:图像细化######################################