图像细化算法大全

合集下载

Zhang-Suen图像细化算法python实现

Zhang-Suen图像细化算法python实现

Zhang-Suen图像细化算法python实现算法流程⾸先要反转原图像,因为算法之后所有的操作都将0作为前景,将1作为背景。

中⼼像素x_1(x,y)的8-近邻定义如下所⽰:考虑以下两个步骤步骤1:执⾏光栅扫描并标记满⾜以下5个条件的所有像素:这是⼀个⿊⾊像素;顺时针查看x2、x3、...、x9、x2时,从0到1的变化次数仅为1;x2、x3、...、x9中1的个数在2个以上6个以下;x2、x4、x6中⾄少有1个为1;x4、x6、x8中⾄少有1个为1;将满⾜条件的所有像素标为1步骤2:执⾏光栅扫描并标记满⾜以下5个条件的所有像素:这是⼀个⿊⾊像素;顺时针查看x2、x3、...、x9、x2时,从0到1的变化次数仅为1;x2、x3、...、x9中1的个数在2个以上6个以下;x2、x4、x8中⾄少有1个为1;x2、x6、x8中⾄少有1个为1;将满⾜条件的所有像素标为1反复执⾏步骤1和步骤2,直到没有点发⽣变化。

python实现:import cv2import numpy as npimport matplotlib.pyplot as plt# Zhang Suen thining algorythmdef Zhang_Suen_thining(img):# get shapeH, W, C = img.shape# prepare out imageout = np.zeros((H, W), dtype=np.int)out[img[..., 0] > 0] = 1# inverseout = 1 - outwhile True:s1 = []s2 = []# step 1 ( rasta scan )for y in range(1, H-1):for x in range(1, W-1):# condition 1if out[y, x] > 0:continue# condition 2f1 = 0if (out[y-1, x+1] - out[y-1, x]) == 1:f1 += 1if (out[y, x+1] - out[y-1, x+1]) == 1:f1 += 1if (out[y+1, x+1] - out[y, x+1]) == 1:f1 += 1if (out[y+1, x] - out[y+1,x+1]) == 1:f1 += 1if (out[y+1, x-1] - out[y+1, x]) == 1:f1 += 1if (out[y, x-1] - out[y+1, x-1]) == 1:f1 += 1if (out[y-1, x-1] - out[y, x-1]) == 1:f1 += 1if (out[y-1, x] - out[y-1, x-1]) == 1:f1 += 1if f1 != 1:continue# condition 3f2 = np.sum(out[y-1:y+2, x-1:x+2])if f2 < 2 or f2 > 6:continue# condition 4# x2 x4 x6if (out[y-1, x] + out[y, x+1] + out[y+1, x]) < 1 : continue# condition 5# x4 x6 x8if (out[y, x+1] + out[y+1, x] + out[y, x-1]) < 1 : continues1.append([y, x])for v in s1:out[v[0], v[1]] = 1# step 2 ( rasta scan )for y in range(1, H-1):for x in range(1, W-1):# condition 1if out[y, x] > 0:continue# condition 2f1 = 0if (out[y-1, x+1] - out[y-1, x]) == 1:f1 += 1if (out[y, x+1] - out[y-1, x+1]) == 1:f1 += 1if (out[y+1, x+1] - out[y, x+1]) == 1:f1 += 1if (out[y+1, x] - out[y+1,x+1]) == 1:f1 += 1if (out[y+1, x-1] - out[y+1, x]) == 1:f1 += 1if (out[y, x-1] - out[y+1, x-1]) == 1:f1 += 1if (out[y-1, x-1] - out[y, x-1]) == 1:f1 += 1if (out[y-1, x] - out[y-1, x-1]) == 1:f1 += 1if f1 != 1:continue# condition 3f2 = np.sum(out[y-1:y+2, x-1:x+2])if f2 < 2 or f2 > 6:continue# condition 4# x2 x4 x8if (out[y-1, x] + out[y, x+1] + out[y, x-1]) < 1 : continue# condition 5# x2 x6 x8if (out[y-1, x] + out[y+1, x] + out[y, x-1]) < 1 : continues2.append([y, x])for v in s2:out[v[0], v[1]] = 1# if not any pixel is changedif len(s1) < 1 and len(s2) < 1:breakout = 1 - outout = out.astype(np.uint8) * 255return out# Read imageimg = cv2.imread("../thin.png").astype(np.float32) # Zhang Suen thiningout = Zhang_Suen_thining(img)# Save resultcv2.imwrite("out.png", out)cv2.imshow("result", out)cv2.waitKey(0)cv2.destroyAllWindows()实验结果:。

Hilditch 细化算法是经典的二值图像细化算法

Hilditch 细化算法是经典的二值图像细化算法

Hilditch 细化算法是经典的二值图像细化算法,然而,在网上却很难找到一个详细、正确的介绍和实现。

可以找到一辆个 Hilditch 算法的C实现,但缺乏注释,代码可读性也很差。

在期刊网上找到几篇论文,提及了Hilditch 算法,结果一篇说的罗哩罗嗦根本看不懂,另一篇说的说的易懂,却是错误的!拿来主义是行不通了,于是只好结合着这几个论文和代码,从头写 Hilditch 细化算法。

假设像素p的3×3邻域结构为:Hilditch 细化算法的步骤为:对图像从左向右从上向下迭代每个像素,是为一个迭代周期。

在每个迭代周期中,对于每一个像素p,如果它同时满足6个条件,则标记它。

在当前迭代周期结束时,则把所有标记的像素的值设为背景值。

如果某次迭代周期中不存在标记点(即满足6个条件的像素),则算法结束。

假设背景值为0,前景值为1,则:6个条件为:(I):p 为1,即p不是背景;(2):x1,x3,x5,x7不全部为1(否则把p标记删除,图像空心了);(3):x1-x8 中,至少有2个为1(若只有1个为1,则是线段的端点。

若没有为1的,则为孤立点);(4):p的8连通联结数为1;联结数指在像素p的3*3邻域中,和p连接的图形分量的个数:上图中,左图的4连通联结数是2,8连通联结数是1,而右图的4联通联结数和8联通联结数都是2。

4连通联结数计算公式是:8连通联结数计算公式是:其中,至于公式怎么来的就不管了,直接用就行了。

(5)假设x3已经标记删除,那么当x3为0时,p的8联通联结数为1;(6)假设x5已经标记删除,那么当x5为0时,p的8联通联结数为1。

======在程序中,我使用的是这样的邻域编码:为了方便计算联结数,以0作为前景,1作为背景。

程序如下(完整程序见:/svn/trunk/src/mon/UnmanagedI mage/ImageU8.cs):/// <summary>/// 计算八联结的联结数,计算公式为:/// (p6 - p6*p7*p0) + sigma(pk - pk*p(k+1)*p(k+2)), k = {0,2,4)/// </summary>/// <param name="list"></param>/// <returns></returns>private unsafe Int32 DetectConnectivity(Int32* list){Int32 count = list[6] - list[6] * list[7] * list[0];count += list[0] - list[0] * list[1] * list[2];count += list[2] - list[2] * list[3] * list[4];count += list[4] - list[4] * list[5] * list[6];return count;}private unsafe void FillNeighbors(Byte* p, Int32* list, Int32 width, Byte foreground = 255){// list 存储的是补集,即前景点为0,背景点为1,以方便联结数的计算list[0] = p[1] == foreground ? 0 : 1;list[1] = p[1 - width] == foreground ? 0 : 1;list[2] = p[-width] == foreground ? 0 : 1;list[3] = p[-1 - width] == foreground ? 0 : 1;list[4] = p[-1] == foreground ? 0 : 1;list[5] = p[-1 + width] == foreground ? 0 : 1;list[6] = p[width] == foreground ? 0 : 1;list[7] = p[1 + width] == foreground ? 0 : 1;}/// <summary>/// 使用 hilditch 算法进行细化/// </summary>public unsafe void Thinning(Byte foreground = 255){Byte* start = this.Start;Int32 width = this.Width;Int32 height = this.Height;Int32* list = stackalloc Int32[8];Byte background = (Byte)(255 - foreground);Int32 length = this.Length;using (ImageU8 mask = new ImageU8(this.Width, this.Height)) {mask.Fill(0);Boolean loop = true;while (loop == true){loop = false;for (Int32 r = 1; r < height - 1; r++){for (Int32 c = 1; c < width - 1; c++){Byte* p = start + r * width + c;// 条件1:p 必须是前景点if (*p != foreground) continue;// p3 p2 p1// p4 p p0// p5 p6 p7// list 存储的是补集,即前景点为0,背景点为1,以方便联结数的计算FillNeighbors(p, list, width, foreground);// 条件2:p0,p2,p4,p6 不皆为前景点if (list[0] == 0 && list[2] == 0 && list[4] == 0 && list[6] == 0)continue;// 条件3: p0~p7至少两个是前景点Int32 count = 0;for (int i = 0; i < 8; i++){count += list[i];}if (count > 6) continue;// 条件4:联结数等于1if (DetectConnectivity(list) != 1) continue;// 条件5: 假设p2已标记删除,则令p2为背景,不改变p的联结数 if (mask[r - 1, c] == 1){list[2] = 1;if (DetectConnectivity(list) != 1)continue;list[2] = 0;}// 条件6: 假设p4已标记删除,则令p4为背景,不改变p的联结数 if (mask[r, c - 1] == 1){list[4] = 1;if (DetectConnectivity(list) != 1)continue;}mask[r, c] = 1; // 标记删除loop = true;}}for (int i = 0; i < length; i++){if (mask[i] == 1){this[i] = background;}}}}}。

数字图像处理领域的二十四个典型算法

数字图像处理领域的二十四个典型算法

数字图像处理领域的⼆⼗四个典型算法数字图像处理领域的⼆⼗四个典型算法及vc实现、第⼀章⼀、256⾊转灰度图⼆、Walsh变换三、⼆值化变换四、阈值变换五、傅⽴叶变换六、离散余弦变换七、⾼斯平滑⼋、图像平移九、图像缩放⼗、图像旋转数字图像处理领域的⼆⼗四个典型算法及vc实现、第三章图像处理,是对图像进⾏分析、加⼯、和处理,使其满⾜视觉、⼼理以及其他要求的技术。

图像处理是信号处理在图像域上的⼀个应⽤。

⽬前⼤多数的图像是以数字形式存储,因⽽图像处理很多情况下指数字图像处理。

本⽂接下来,简单粗略介绍下数字图像处理领域中的24个经典算法,然后全部算法⽤vc实现。

由于篇幅所限,只给出某⼀算法的主体代码。

ok,请细看。

⼀、256⾊转灰度图算法介绍(百度百科):什么叫灰度图?任何颜⾊都有红、绿、蓝三原⾊组成,假如原来某点的颜⾊为RGB(R,G,B),那么,我们可以通过下⾯⼏种⽅法,将其转换为灰度: 1.浮点算法:Gray=R*0.3+G*0.59+B*0.11 2.整数⽅法:Gray=(R*30+G*59+B*11)/100 3.移位⽅法:Gray =(R*28+G*151+B*77)>>8; 4.平均值法:Gray=(R+G+B)/3; 5.仅取绿⾊:Gray=G; 通过上述任⼀种⽅法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统⼀⽤Gray替换,形成新的颜⾊RGB(Gray,Gray,Gray),⽤它替换原来的RGB(R,G,B)就是灰度图了。

灰度分为256阶。

所以,⽤灰度表⽰的图像称作灰度图。

程序实现: ok,知道了什么叫灰度图,下⾯,咱们就来实现此256⾊灰度图。

这个Convert256toGray(),即是将256⾊位图转化为灰度图:void Convert256toGray(HDIB hDIB) { LPSTR lpDIB; // 由DIB句柄得到DIB指针并锁定DIB lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB); // 指向DIB象素数据区的指针 LPSTR lpDIBBits; // 指向DIB象素的指针 BYTE * lpSrc; // 图像宽度 LONG lWidth; // 图像⾼度 LONG lHeight; // 图像每⾏的字节数 LONG lLineBytes; // 指向BITMAPINFO结构的指针(Win3.0) LPBITMAPINFO lpbmi; // 指向BITMAPCOREINFO结构的指针 LPBITMAPCOREINFO lpbmc; // 获取指向BITMAPINFO结构的指针(Win3.0) lpbmi = (LPBITMAPINFO)lpDIB; // 获取指向BITMAPCOREINFO结构的指针 lpbmc = (LPBITMAPCOREINFO)lpDIB; // 灰度映射表 BYTE bMap[256]; // 计算灰度映射表(保存各个颜⾊的灰度值),并更新DIB调⾊板 int i,j; for (i = 0; i < 256;i ++) { // 计算该颜⾊对应的灰度值 bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed + 0.587 * lpbmi->bmiColors[i].rgbGreen + 0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5); // 更新DIB调⾊板红⾊分量 lpbmi->bmiColors[i].rgbRed = i; // 更新DIB调⾊板绿⾊分量 lpbmi->bmiColors[i].rgbGreen = i; // 更新DIB调⾊板蓝⾊分量 lpbmi->bmiColors[i].rgbBlue = i; // 更新DIB调⾊板保留位 lpbmi->bmiColors[i].rgbReserved = 0; } // 找到DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); // 获取图像宽度 lWidth = ::DIBWidth(lpDIB); // 获取图像⾼度 lHeight = ::DIBHeight(lpDIB); // 计算图像每⾏的字节数 lLineBytes = WIDTHBYTES(lWidth * 8); // 更换每个象素的颜⾊索引(即按照灰度映射表换成灰度值) //逐⾏扫描 for(i = 0; i < lHeight; i++) { //逐列扫描 for(j = 0; j < lWidth; j++) { // 指向DIB第i⾏,第j个象素的指针 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j; // 变换 *lpSrc = bMap[*lpSrc]; } } //解除锁定 ::GlobalUnlock ((HGLOBAL)hDIB); }变换效果(以下若⽆特别说明,图⽰的右边部分都是为某⼀算法变换之后的效果):程序实现:函数名称:WALSH()参数:double * f - 指向时域值的指针double * F - 指向频域值的指针r -2的幂数返回值:⽆。

Python-图像的细化(骨架抽取)

Python-图像的细化(骨架抽取)
return i_two
# 入口函数 if __name__ == ' image = cv2.imread("1.jpg", 0) img_binary = to_binary(image)
img_thin = thin(img_binary) cv2.imshow("image", image) cv2.imshow("img_binary", img_binary) cv2.imshow("img_thin", img_thin) cv2.waitKey(0)
我们对于黑色的像素点,对于它周围的8个点,我们赋予不同的价值,若周围是黑色,我们认为其价值为0,为白色则取九宫格中对应的价 值。对于前面那幅图中第一个点,也周围的点都是黑色,所以它的总价值是0,对应于索引表的第一项,前面那幅图中第二点,它周围有三 个白色点,它的总价值为1+4+32=37,对应于索引表中第三十八项。
# 映射表 l_array = [0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1,
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 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, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0]

图像细化(骨架化)算法分析

图像细化(骨架化)算法分析

图像细化(⾻架化)算法分析图像细化(⾻架化)算法分析图像的细化是模式识别中很重要的⼀个技术,指的是将原本"臃肿"的像素简化为单像素相连接的⼆值图像(即类似⾻架的概念),细化的好坏直接影响到后⾯识别匹配的效率。

摘⾃某⽂章的话,细化就是经过⼀层层的剥离,从原来的图中去掉⼀些点,但仍要保持原来的形状,直到得到图像的⾻架。

⾻架,可以理解为图象的中轴,例如⼀个长⽅形的⾻架是它的长⽅向上的中轴线;正⽅形的⾻架是它的中⼼点;圆的⾻架是它的圆⼼,直线的⾻架是它⾃⾝,孤⽴点的⾻架也是⾃⾝。

下⾯先介绍经典的Zhang并⾏快速细化算法:设p1点的⼋邻域为:【 p9 p2 p3p8 p1 p4p7 p6 p5 】(其中p1为⽩点,如果以下四个条件同时满⾜,则删除p1,即令p1=0)其中迭代分为两个⼦过程:过程1 细化删除条件为:(1)、2 < =N(p1) <= 6, N(x)为x的8邻域中⿊点的数⽬(2)、A(p1)=1, A(x)指的是将p2-p8之间按序前后分别为0、1的对数(背景⾊:0)(3)、p2*p4*p6=0(4)、p4*p6*p8=0如果同时满⾜以上四个条件则该点可以删除(赋值为0)。

过程2 细化删除条件为:(1)、2 < =N(p1) <= 6, N(x)为x的8邻域中⿊点的数⽬(2)、A(p1)=1, A(x)指的是将p2-p8之间按序前后分别为0、1的对数(背景⾊:0)(3)、p2*p4*p8=0(4)、p2*p6*p8=0如果同时满⾜以上四个条件则该点可以删除。

代码如下:A.m1 function n=A(temp,i,j)2 %0->1的数⽬3 shuzu=[temp(i,j),temp(i-1,j),temp(i-1,j+1),temp(i,j+1),temp(i+1,j+1),temp(i+1,j),temp(i+1,j-1),temp(i,j-1),temp(i-1,j-1)];4 n=0;5for i=2:86if shuzu(i)==0&&shuzu(i+1)==17 n=n+1;8 end9 end主函数代码:1 test=input('Please input a digits image:','s'); %输⼊图像2 x=imread(test);3if ~isbw(x)4'请确保输⼊图像为⼆值化图像!';5else6 [height,width]=size(x);7 mark=1;8 % temp=zeros(height+2,width+2);9 % temp(2:height+1,2:width+1)=x(:,:);10 temp=x;11 imshow(temp);12while mark==113 mark=0;1415for i=2:height-116for j=2:width-117 condition=0;18 %判断P(r,c)是否为可细化像素19if temp(i,j)==120 n=0;21for ii=-1:122for jj=-1:123 n=n+temp(i+ii,j+jj);24 end25 end26if (n>=3 && n<=7)27 condition=condition+1;28 end29if A(temp,i,j)==130 condition=condition+1;31 end32if temp(i-1,j)*temp(i,j+1)*temp(i+1,j)==033 condition=condition+1;34 end35if temp(i,j+1)*temp(i+1,j)*temp(i,j-1)==036 condition=condition+1;37 end38if condition==439 mark=1;40 temp(i,j)=0;41 end42 end43 end44 end45 figure;imshow(temp);464748for i=2:height-149for j=2:width-150 condition=0;51 %判断P(r,c)是否为可细化像素52if temp(i,j)==153 n=0;54for ii=-1:155for jj=-1:156 n=n+temp(i+ii,j+jj);57 end58 end59if (n>=3 && n<=7)60 condition=condition+1;61 end62if A(temp,i,j)==163 condition=condition+1;64 end65if temp(i-1,j)*temp(i,j+1)*temp(i,j-1)==066 condition=condition+1;67 end68if temp(i,j-1)*temp(i+1,j)*temp(i,j-1)==069 condition=condition+1;70 end71if condition==472 mark=1;73 temp(i,j)=0;74 end75 end76 end77 end78 figure;imshow(temp);79 end80 end结果:。

hilditch 细化算法 python

hilditch 细化算法 python

Hilditch细化算法是一种用于二值图像细化(或骨架化)的算法。

以下是一个简单的Python实现:
def hilditch(image):
# 获取图像的宽度和高度
width, height = image.shape
# 创建一个与原图大小相同的掩模,所有值初始化为1
mask = image.copy()
# 遍历原图像
for y in range(height):
for x in range(width):
# 如果当前像素是1,则进行细化操作
if image[x][y] == 1:
# 判断上下左右四个方向是否为0
if (x > 0 and image[x-1][y] == 0) or (x < width-1 and image[x+1][y] == 0):
mask[x][y] = 0
if (y > 0 and image[x][y-1] == 0) or (y < height-1 and image[x][y+1] == 0):
mask[x][y] = 0
# 返回细化后的图像
return mask
这个函数接受一个二值图像作为输入,并返回一个细化后的图像。

在函数中,我们首先创建一个与原图大小相同的掩模,并将所有值初始化为1。

然后,我们遍历原图像中的每个像素,如果当前像素是1,则检查其上下左右四个方向是否为0。

如果是,则将当前像素的值设置为0,表示该像素应该被细化掉。

最后,我们返回细化后的图像。

hilditch细化算法python

Hilditch细化算法是一种用于图像处理的算法,旨在对二值化图像进行细化处理,以消除图像中不必要的细节,从而得到更加清晰的边缘轮廓。

该算法在数字图像处理领域具有广泛的应用,可以帮助我们提取出图像中的有效信息,并且在计算机视觉、模式识别等领域有着重要的作用。

Hilditch细化算法的原理比较复杂,主要包括以下几个步骤:1. 定义细化算法的结构元素:Hilditch细化算法中使用了一个3x3的结构元素,该结构元素用于检测图像中的特定模式,并对其进行处理。

2. 识别图像中的特征点:在细化算法中,首先需要识别图像中的特征点,这些特征点通常指的是图像中的边缘像素点,通过对这些特征点进行分析和处理,可以实现对图像的细化处理。

3. 进行细化处理:一旦特征点被识别出来,就可以开始对图像进行细化处理。

这通常包括对结构元素进行滑动操作,利用结构元素与图像进行匹配,并根据预先设定的条件对结构元素进行处理,以使得图像的边缘轮廓更加清晰。

4. 迭代处理:细化算法通常需要进行多次迭代处理,直到图像中的所有特征点都被处理完毕,并且不再发生变化为止。

Hilditch细化算法虽然在图像处理中有着重要的作用,但是在实际应用中也存在一些问题和挑战。

算法本身的复杂性较高,需要较高的计算和存储资源;另外在处理过程中可能会出现一些误差和不确定性,这也需要我们在实际应用中做出一些改进和调整。

在Python中,我们可以利用一些开源的图像处理库来实现Hilditch 细化算法的功能,比如OpenCV、Pillow等。

这些库提供了丰富的API和功能,可以帮助我们实现图像的二值化处理、特征点的识别以及细化处理等操作。

Python本身具有简洁清晰的语法结构,也使得我们可以比较方便地编写和调试相关的算法代码。

以OpenCV为例,我们可以通过以下步骤来实现Hilditch细化算法:1. 导入OpenCV库:首先需要导入OpenCV库,并读取需要处理的图像数据。

图像处理中的数学算法

图像处理中的数学算法图像处理是一个复杂的过程,它需要运用数学算法来处理图像中的各种信息。

这些算法可以实现图像的去噪、平滑、增强、分割、匹配等功能。

本文将介绍一些常用的图像处理算法,包括小波变换、奇异值分解、最小二乘法、K-means算法、纹理分析等。

一、小波变换小波变换是一种将时域信号转换为频域信号的数学算法。

它可以将图像分解为不同频率范围的小波系数,从而实现对图像的去噪、平滑、特征提取等操作。

小波变换在图像处理中应用广泛,特别是在去噪方面有着独特的优势。

小波变换可以将图像矩阵分解成多组小波系数,其中较高频率的小波系数表示图像中的细节信息,较低频率的小波系数表示图像中的模糊信息。

通过对小波系数的分析和处理,可以实现对图像的特定操作。

二、奇异值分解奇异值分解(SVD)是一种将矩阵分解为三个部分的数学算法,其中一个矩阵是一个对角矩阵,它的对角线上的元素称为奇异值。

奇异值对应了原始矩阵中的主要信息,可以用来构建一个低维矩阵,从而实现图像的压缩和降噪。

奇异值分解可以实现对图像中重要信息的提取和过滤,从而实现图像的压缩和去噪。

三、最小二乘法最小二乘法是一种寻找最优曲线拟合的数学方法,它的目标是通过一个最优拟合函数来表达数据的真实规律。

在图像处理中,最小二乘法可以用来寻找图像中的相关特征,从而实现对图像的分割和特征提取。

最小二乘法可以通过对图像中的像素点进行拟合来得到相应的参数,从而实现对图像中相关特征的描述和分析。

最小二乘法在图像处理中常常用于线性回归和图像灰度直方图均衡化等操作。

四、K-means算法K-means算法是一种将数据划分为多个簇的聚类算法,它可以帮助识别图像中的不同区域,并实现对图像区域的分割和聚类。

K-means算法通常可以用来处理灰度图像、二元图像和多光谱图像等。

K-means算法通过寻找多个空间点之间的相似性,来得到一个划分簇的结果。

在图像处理中,K-means算法可以用来将图像像素划分为多个簇,从而实现对图像的分割和聚类。

opencv实现二值图像细化的算法

opencv实现⼆值图像细化的算法opencv实现⼆值图像细化的算法细化算法通常和⾻骼化、⾻架化算法是相同的意思,也就是thin算法或者skeleton算法。

虽然很多图像处理的教材上不是这么写的,具体原因可以看这篇论⽂,Louisa Lam, Seong-Whan Lee, Ching Y. Suen,“Thinning Methodologies-A Comprehensive Survey ”,IEEE TRANSACTIONS ON PATTERN ANALYSIS AND MACHINE INTELLIGENCE, VOL. 14, NO. 9, SEPTEMBER 1992 ,总结了⼏乎所有92年以前的经典细化算法。

函数:void cvThin( IplImage* src, IplImage* dst, int iterations=1)功能:将IPL_DEPTH_8U型⼆值图像进⾏细化参数:src,原始IPL_DEPTH_8U型⼆值图像dst,⽬标存储空间,必须事先分配好,且和原图像⼤⼩类型⼀致iterations,迭代次数参考⽂献:T. Y. Zhang and C. Y. Suen, “A fast parallel algorithm for thinning digital patterns,” Comm. ACM, vol. 27, no. 3, pp. 236-239, 1984.void cvThin( IplImage* src, IplImage* dst, int iterations=1){CvSize size = cvGetSize(src);cvCopy(src, dst);int n = 0,i = 0,j = 0;for(n=0; n<iterations; n++){IplImage* t_image = cvCloneImage(dst);for(i=0; i<size.height; i++){for(j=0; j<size.width; j++){if(CV_IMAGE_ELEM(t_image,byte,i,j)==1){int ap=0;int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);if (p2==0 && p3==1){ap++;}int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);if(p3==0 && p4==1){ap++;}int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);if(p4==0 && p5==1){ap++;}int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);if(p5==0 && p6==1){ap++;}int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1);if(p6==0 && p7==1){ap++;}int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);if(p7==0 && p8==1){ap++;}int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);if(p8==0 && p9==1){ap++;}if(p9==0 && p2==1){ap++;}if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7){if(ap==1){if(!(p2 && p4 && p6)){if(!(p4 && p6 && p8)){CV_IMAGE_ELEM(dst,byte,i,j)=0;}}}}}}}cvReleaseImage(&t_image);t_image = cvCloneImage(dst);for(i=0; i<size.height; i++){for(int j=0; j<size.width; j++){if(CV_IMAGE_ELEM(t_image,byte,i,j)==1){int ap=0;int p2 = (i==0)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j);int p3 = (i==0 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte, i-1, j+1);if (p2==0 && p3==1){ap++;}int p4 = (j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i,j+1);if(p3==0 && p4==1){ap++;}int p5 = (i==size.height-1 || j==size.width-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j+1);if(p4==0 && p5==1){ap++;}int p6 = (i==size.height-1)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j);if(p5==0 && p6==1){ap++;}int p7 = (i==size.height-1 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i+1,j-1); if(p6==0 && p7==1){ap++;}int p8 = (j==0)?0:CV_IMAGE_ELEM(t_image,byte,i,j-1);if(p7==0 && p8==1){ap++;}int p9 = (i==0 || j==0)?0:CV_IMAGE_ELEM(t_image,byte,i-1,j-1);if(p8==0 && p9==1){ap++;}if(p9==0 && p2==1){ap++;}if((p2+p3+p4+p5+p6+p7+p8+p9)>1 && (p2+p3+p4+p5+p6+p7+p8+p9)<7) {if(ap==1){if(p2*p4*p8==0){if(p2*p6*p8==0){CV_IMAGE_ELEM(dst, byte,i,j)=0;}}}}}}}cvReleaseImage(&t_image);}}//使⽤举例#include "cxcore.h"#include "cv.h"#include "highgui.h"int main(int argc, char* argv[]){if(argc!=2){return 0;}IplImage *pSrc = NULL,*pDst = NULL,*pTmp = NULL;//传⼊⼀个灰度图像pSrc = cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE);if(!pSrc){return 0;}pTmp = cvCloneImage(pSrc);pDst = cvCreateImage(cvGetSize(pSrc),pSrc->depth,pSrc->nChannels);cvZero(pDst);cvThreshold(pSrc,pTmp,128,1,CV_THRESH_BINARY_INV);//做⼆值处理,将图像转换成0,1格式 //cvSaveImage("c://Threshold.bmp",pTmp,0);cvThin(pTmp,pDst,8);//细化,通过修改iterations参数进⼀步细化cvNamedWindow("src",1);cvNamedWindow("dst",1);cvShowImage("src",pSrc);//将⼆值图像转换成灰度,以便显⽰int i = 0,j = 0;CvSize size = cvGetSize(pDst);for(i=0; i<size.height; i++){for(j=0; j<size.width; j++){if(CV_IMAGE_ELEM(pDst,uchar,i,j)==1){CV_IMAGE_ELEM(pDst,uchar,i,j) = 0;}else{CV_IMAGE_ELEM(pDst,uchar,i,j) = 255;}}}//cvSaveImage("c://thin.bmp",pDst);cvShowImage("dst",pDst);cvWaitKey(0);cvReleaseImage(&pSrc);cvReleaseImage(&pDst);cvReleaseImage(&pTmp);cvDestroyWindow("src");cvDestroyWindow("dst");return 0;}。

一些基本的形态学算法 细化

一些基本的形态学算法细化1.引言1.1 概述概述形态学算法是图像处理领域中的一种重要技术,主要用于图像的分析和处理。

形态学算法基于数学形态学理论,通过对图像中的形状和结构进行操作和变换,从而实现图像的特征提取、图像增强、边缘检测等目的。

形态学算法最早是由Matheron于1964年提出的,其理论基础是数学形态学,借鉴了数学中对集合的运算和变换的概念和方法。

形态学算法主要基于结构元素(也称为模板或内核)与图像进行操作,通过结构元素在图像上的移动和比较,实现图像的形态学变化。

形态学算法的基础操作包括膨胀、腐蚀、开运算和闭运算。

膨胀操作将结构元素扩张到图像中的对象区域,从而使对象的尺寸增大;腐蚀操作将结构元素侵蚀图像中的对象区域,使对象的尺寸减小。

开运算是先进行腐蚀,再进行膨胀,通常用于去除图像中的小噪点;闭运算与开运算相反,先进行膨胀,再进行腐蚀,通常用于填补图像中的小孔洞。

除了基本形态学算法外,细化算法也是形态学算法的重要内容之一。

细化算法主要用于提取图像中的骨架或轮廓线。

骨架提取算法通过连续的腐蚀操作,逐步减小图像中的对象尺寸,最终得到对象的骨架;线条细化算法则通过针对对象边界的特征点进行腐蚀和连接操作,实现对边界线条的细化。

本文将详细介绍基本形态学算法和细化算法的原理和应用,并通过实例演示其在图像处理中的作用。

同时,强调细化算法在形态学算法中的重要性和应用前景,以期对读者深入理解和应用形态学算法具有指导意义。

1.2文章结构文章结构部分的内容是对整篇文章的组织和安排进行介绍。

在本篇文章中,主要包含了引言、正文和结论三个部分。

首先是引言部分,引言部分主要包括概述、文章结构和目的三个小节。

在概述中,介绍了本篇文章要讨论的主题,即一些基本的形态学算法的细化。

在文章结构中,说明了整篇文章的目录和结构安排。

在目的小节中,阐明了撰写这篇文章的目的和意义。

接下来是正文部分,正文部分分为基本形态学算法和细化算法两个小节。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

图像细化算法大全(1)#include "StdAfx.h"#include <stdlib.h>#include <malloc.h>void beforethin(unsigned char *ip, unsigned char *jp,unsigned long lx, unsigned long ly){unsigned long i,j;for(i=0; i<ly; i++){for(j=0; j<lx; j++){//这里要视前景是白点还是黑点而定,可以改动//如果前景是白点,就是这样;反之反过来if(ip[i*lx+j]>0)jp[i*lx+j]=1;elsejp[i*lx+j]=0;}}}///////////////////////////////////////////////////////////////////////////Hilditch细化算法//功能:对图象进行细化//参数:image:代表图象的一维数组// lx:图象宽度// ly:图象高度// 无返回值void ThinnerHilditch(void *image, unsigned long lx, unsigned long ly) {char *f, *g;char n[10];unsigned int counter;short k, shori, xx, nrn;unsigned long i, j;long kk, kk11, kk12, kk13, kk21, kk22, kk23, kk31, kk32, kk33, size; size = (long)lx * (long)ly;g = (char *)malloc(size);if(g == NULL){printf("error in allocating memory!\n");return;}f = (char *)image;for(i=0; i<lx; i++){for(j=0; j<ly; j++){kk=i*ly+j;if(f[kk]!=0){f[kk]=1;g[kk]=f[kk];}}}counter = 1;do{printf("%4d*",counter); counter++;shori = 0;for(i=0; i<lx; i++){for(j=0; j<ly; j++) {kk = i*ly+j;if(f[kk]<0)f[kk] = 0;g[kk]= f[kk];}}for(i=1; i<lx-1; i++){for(j=1; j<ly-1; j++) {kk=i*ly+j;if(f[kk]!=1)continue;kk11 = (i-1)*ly+j-1;kk12 = kk11 + 1;kk13 = kk12 + 1;kk21 = i*ly+j-1;kk22 = kk21 + 1;kk23 = kk22 + 1;kk31 = (i+1)*ly+j-1;kk32 = kk31 + 1;kk33 = kk32 + 1;if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])!=0)continue;nrn = g[kk11] + g[kk12] + g[kk13] + g[kk21] + g[kk23] + g[kk31] + g[kk32] + g[kk33];if(nrn <= 1){f[kk22] = 2;continue;}n[4] = f[kk11];n[3] = f[kk12];n[2] = f[kk13];n[5] = f[kk21];n[1] = f[kk23];n[6] = f[kk31];n[7] = f[kk32];n[8] = f[kk33];n[9] = n[1];xx = 0;for(k=1; k<8; k=k+2){if((!n[k])&&(n[k+1]||n[k+2]))xx++;}if(xx!=1){f[kk22] = 2;continue;if(f[kk12] == -1){f[kk12] = 0;n[3] = 0;xx = 0;for(k=1; k<8; k=k+2){if((!n[k])&&(n[k+1]||n[k+2])) xx++;}if(xx != 1){f[kk12] = -1;continue;}f[kk12] = -1;n[3] = -1;}if(f[kk21]!=-1){f[kk22] = -1;shori = 1;continue;}f[kk21] = 0;n[5] = 0;xx = 0;for(k=1; k<8; k=k+2){if((!n[k])&&(n[k+1]||n[k+2])) {xx++;}}if(xx == 1)f[kk21] = -1;f[kk22] = -1;shori =1;}elsef[kk21] = -1;}}}while(shori);free(g);}///////////////////////////////////////////////////////////////////////////Pavlidis细化算法//功能:对图象进行细化//参数:image:代表图象的一维数组// lx:图象宽度// ly:图象高度// 无返回值void ThinnerPavlidis(void *image, unsigned long lx, unsigned long ly) {char erase, n[8];char *f;unsigned char bdr1,bdr2,bdr4,bdr5;short c,k,b;unsigned long i,j;long kk,kk1,kk2,kk3;f = (char*)image;for(i=1; i<lx-1; i++){for(j=1; j<ly-1; j++){kk = i*ly + j;if(f[kk])f[kk] = 1;}}for(i=0, kk1=0, kk2=ly-1; i<lx; i++, kk1+=ly, kk2+=ly){f[kk1]=0;f[kk2]=0;}for(j=0, kk=(lx-1)*ly; j<ly; j++,kk++) {f[j]=0;f[kk]=0;}c=5;erase =1;while(erase){c++;for(i=1; i<lx-1; i++){for(j=1; j<ly-1; j++){kk=i*ly+j;if(f[kk]!=1)continue;kk1 = kk-ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[3] = f[kk1];n[2] = f[kk2];n[1] = f[kk3];kk1 = kk - 1;kk3 = kk + 1;n[4] = f[kk1];n[0] = f[kk3];kk1 = kk + ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[5] = f[kk1];n[6] = f[kk2];n[7] = f[kk3];bdr1 =0;for(k=0; k<8; k++){if(n[k]>=1)bdr1|=0x80>>k;}if((bdr1&0252)== 0252)continue;f[kk] = 2;b=0;for(k=0; k<=7; k++){b+=bdr1&(0x80>>k);}if(b<=1)f[kk]=3;if((bdr1&0160)!=0&&(bdr1&07)!=0&&(bdr1&0210)==0)f[kk]=3;else if((bdr1&&0301)!=0&&(bdr1&034)!=0&&(bdr1&042)==0) f[kk]=3;else if((bdr1&0202)==0 && (bdr1&01)!=0)f[kk]=3;else if((bdr1&0240)==0 && (bdr1&0100)!=0)f[kk]=3;else if((bdr1&050)==0 && (bdr1&020)!=0)f[kk]=3;else if((bdr1&012)==0 && (bdr1&04)!=0)f[kk]=3;}}for(i=1; i<lx-1; i++){for(j=1; j<ly-1; j++){kk = i*ly + j;if(!f[kk])continue;kk1 = kk - ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[3] = f[kk1];n[2] = f[kk2];n[1] = f[kk3];kk1 = kk - 1;kk2 = kk + 1;n[4] = f[kk1];n[0] = f[kk3];kk1 = kk + ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[5] = f[kk1];n[6] = f[kk2];n[7] = f[kk3];bdr1 = bdr2 =0;for(k=0; k<=7; k++){if(n[k]>=1)bdr1|=0x80>>k;if(n[k]>=2)bdr2|=0x80>>k;}if(bdr1==bdr2){f[kk] = 4;continue;}if(f[kk]!=2)continue;if((bdr2&0200)!=0 && (bdr1&010)==0 && ((bdr1&0100)!=0 &&(bdr1&001)!=0 ||((bdr1&0100)!=0 ||(bdr1 & 001)!=0) && (bdr1&060)!=0 &&(bdr1&06)!=0)){f[kk] = 4;}else if((bdr2&040)!=0 && (bdr1&02)==0 && ((bdr1&020)!=0 && (bdr1&0100)!=0 || ((bdr1&020)!=0 || (bdr1&0100)!=0) && (bdr1&014)!=0 && (bdr1&0201)!=0)){f[kk] = 4;}else if((bdr2&010)!=0 && (bdr1&0200)==0 && ((bdr1&04)!=0 && (bdr1&020)!=0 ||((bdr1&04)!=0 || (bdr1&020)!=0) &&(bdr1&03)!=0 && (bdr1&0140)!=0)){f[kk] = 4;}else if((bdr2&02)!=0 && (bdr1&040)==0 && ((bdr1&01)!=0 && (bdr1&04)!=0 ||((bdr1&01)!=0 || (bdr1&04)!=0) &&(bdr1&0300)!=0 && (bdr1&030)!=0)){f[kk] = 4;}}}for(i=1; i<lx-1; i++){for(j=1; j<ly-1; j++){kk = i*ly + j;if(f[kk]!=2)continue;kk1 = kk - ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[3] = f[kk1];n[2] = f[kk2];n[1] = f[kk3];kk1 = kk - 1;kk2 = kk + 1;n[4] = f[kk1];n[0] = f[kk3];kk1 = kk + ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[5] = f[kk1];n[6] = f[kk2];n[7] = f[kk3];bdr4 = bdr5 =0;for(k=0; k<=7; k++){if(n[k]>=4)bdr4|=0x80>>k;if(n[k]>=5)bdr5|=0x80>>k;}if((bdr4&010) == 0){f[kk] = 5;continue;}if((bdr4&040) == 0 && bdr5 ==0){f[kk] = 5;continue;}if(f[kk]==3||f[kk]==4)f[kk] = c;}}erase = 0;for(i=1; i<lx-1; i++){for(j=1; j<ly-1; j++){kk = i*ly +j;if(f[kk]==2||f[kk] == 5){erase = 1;f[kk] = 0;}}}}}///////////////////////////////////////////////////////////////////////// //Rosenfeld细化算法//功能:对图象进行细化//参数:image:代表图象的一维数组// lx:图象宽度// ly:图象高度// 无返回值void ThinnerRosenfeld(void *image, unsigned long lx, unsigned long ly) {char *f, *g;char n[10];char a[5] = {0, -1, 1, 0, 0};char b[5] = {0, 0, 0, 1, -1};char nrnd, cond, n48, n26, n24, n46, n68, n82, n123, n345, n567, n781; short k, shori;unsigned long i, j;long ii, jj, kk, kk1, kk2, kk3, size;size = (long)lx * (long)ly;g = (char *)malloc(size);if(g==NULL){printf("error in alocating mmeory!\n");return;}f = (char *)image;for(kk=0l; kk<size; kk++){g[kk] = f[kk];}do{shori = 0;for(k=1; k<=4; k++){for(i=1; i<lx-1; i++){ii = i + a[k];for(j=1; j<ly-1; j++){kk = i*ly + j;if(!f[kk])continue;jj = j + b[k];kk1 = ii*ly + jj;if(f[kk1])continue;kk1 = kk - ly -1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[3] = f[kk1];n[2] = f[kk2];n[1] = f[kk3];kk1 = kk - 1;kk3 = kk + 1;n[4] = f[kk1];n[8] = f[kk3];kk1 = kk + ly - 1;kk2 = kk1 + 1;kk3 = kk2 + 1;n[5] = f[kk1];n[6] = f[kk2];n[7] = f[kk3];nrnd = n[1] + n[2] + n[3] + n[4] +n[5] + n[6] + n[7] + n[8];if(nrnd<=1)continue;cond = 0;n48 = n[4] + n[8];n26 = n[2] + n[6];n24 = n[2] + n[4];n46 = n[4] + n[6];n68 = n[6] + n[8];n82 = n[8] + n[2];n123 = n[1] + n[2] + n[3];n345 = n[3] + n[4] + n[5];n567 = n[5] + n[6] + n[7];n781 = n[7] + n[8] + n[1];if(n[2]==1 && n48==0 && n567>0) {if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[6]==1 && n48==0 && n123>0) {if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[8]==1 && n26==0 && n345>0) {if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[4]==1 && n26==0 && n781>0) {if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[5]==1 && n46==0){if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[7]==1 && n68==0){if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[1]==1 && n82==0) {if(!cond)continue;g[kk] = 0;shori = 1;continue;}if(n[3]==1 && n24==0) {if(!cond)continue;g[kk] = 0;shori = 1;continue;}cond = 1;if(!cond)continue;g[kk] = 0;shori = 1;}}for(i=0; i<lx; i++){for(j=0; j<ly; j++){kk = i*ly + j;f[kk] = g[kk];}}}}while(shori);free(g);}///////////////////////////////////////////////////////////////////////////基于索引表的细化细化算法//功能:对图象进行细化//参数:lpDIBBits:代表图象的一维数组// lWidth:图象高度// lHeight:图象宽度// 无返回值BOOL WINAPI ThiningDIBSkeleton (LPSTR lpDIBBits, LONG lWidth, LONG lHeight){//循环变量long i;long j;long lLength;unsigned char deletemark[256] = {0,0,0,0,0,0,0,1, 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,1,0,1,1,1,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1,0,0,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0, 0,0,0,1,0,0,1,1,1,1,0,1,0,0,0,1, 0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,1, 1,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1, 0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0,1,1,1,1,0,0,1,1, 1,1,0,0,1,1,0,0};//索引表unsigned char p0, p1, p2, p3, p4, p5, p6, p7;unsigned char *pmid, *pmidtemp;unsigned char sum;int changed;bool bStart = true;lLength = lWidth * lHeight;unsigned char *pTemp = (unsigned char *)malloc(sizeof(unsigned char) * lWidth * lHeight);// P0 P1 P2// P7 P3// P6 P5 P4while(bStart){bStart = false;changed = 0;//首先求边缘点(并行)pmid = (unsigned char *)lpDIBBits + lWidth + 1;memset(pTemp, (BYTE) 0, lLength);pmidtemp = (unsigned char *)pTemp + lWidth + 1;for(i = 1; i < lHeight -1; i++){for(j = 1; j < lWidth - 1; j++){if( *pmid == 0){pmid++;pmidtemp++;continue;}p3 = *(pmid + 1);p2 = *(pmid + 1 - lWidth);p1 = *(pmid - lWidth);p0 = *(pmid - lWidth -1);p7 = *(pmid - 1);p6 = *(pmid + lWidth - 1);p5 = *(pmid + lWidth);p4 = *(pmid + lWidth + 1);sum = p0 & p1 & p2 & p3 & p4 & p5 & p6 & p7; if(sum == 0){*pmidtemp = 1;}pmid++;pmidtemp++;}pmid++;pmid++;pmidtemp++;pmidtemp++;}//现在开始串行删除pmid = (unsigned char *)lpDIBBits + lWidth + 1;pmidtemp = (unsigned char *)pTemp + lWidth + 1;for(i = 1; i < lHeight -1; i++){for(j = 1; j < lWidth - 1; j++){if( *pmidtemp == 0){pmid++;pmidtemp++;continue;}p3 = *(pmid + 1);p2 = *(pmid + 1 - lWidth);p1 = *(pmid - lWidth);p0 = *(pmid - lWidth -1);p7 = *(pmid - 1);p6 = *(pmid + lWidth - 1);p5 = *(pmid + lWidth);p4 = *(pmid + lWidth + 1);p1 *= 2;p2 *= 4;p3 *= 8;p4 *= 16;p5 *= 32;p6 *= 64;p7 *= 128;sum = p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7; if(deletemark[sum] == 1){*pmid = 0;bStart = true;}pmid++;pmidtemp++;}pmid++;pmid++;pmidtemp++; pmidtemp++; }}return true;}。

相关文档
最新文档