形态学图像处理

预备知识

(一) 集合论中的基本概念

如果(x,y)是来自 Z 2 Z^2 Z2的整数,f是分配给每个不同坐标对(x,y)的亮度值的映射,那么函数f(x,y)被称为数字图像。令A是 Z 2 Z^2 Z2中的集合,A中的元素是坐标(x,y)处的像素。
若w=(x,y)属于 A中的元素,则表示为:
在这里插入图片描述
若w 不属于 A中的元素,表示为:

在这里插入图片描述
若满足一定条件的像素坐标集合B,表示为:
在这里插入图片描述
若像素坐标的集合均不属于集合A,则表示为 A c A^c Ac
在这里插入图片描述
若集合C同属于集合A和集合B,交集表示为:
在这里插入图片描述
集合A和集合B的并集C,表示为:

在这里插入图片描述
集合A和集合B的差集(属于A但不属于B的所有像素坐标),表示为:

在这里插入图片描述
集合B的反射表示为:

在这里插入图片描述
点z=(z1,z2)对集合A的平移表示为:

在这里插入图片描述

(二)二值图像、集合及逻辑算子

二值图像是指在图像中,任意像素的值只有两种情况0或者1,0表示背景,1表示前景。形态学理论把二值图像看做前景(1 值)像素的集合, 集合的元素属于 Z 2 Z^2 Z2
在这里插入图片描述
图 9-1 中定义的集合操作可以用MATLAB的逻辑算子 OR(| )、AND(&)和NOT( )在二值 图像中执行,如表 9-1 所示:

在这里插入图片描述

f = rgb2gray(imread('two1.jpg'));
g = rgb2gray(imread('two2.jpg'));
subplot(2,3,1), imshow(f);title('(a)二值图像 A:');
subplot(2,3,2), imshow(g);title('(b)二值图像 B:');
subplot(2,3,3), imshow(~f);title('(c)A的补集~A:');
subplot(2,3,4), imshow(f|g);title('(d) A和B的交集 A & B:');
subplot(2,3,5), imshow(f&g);title('(e)A和B的并集 A|B:');
subplot(2,3,6), imshow(f&~g);title('(f)A和B的差集 A&~B');

在这里插入图片描述

膨胀和腐蚀

(1)膨胀

膨胀:膨胀是在二值图像中“加长”或“变粗”的操作。这种特殊的方式和变粗的程度由一个称为结构元素的集合控制。(实际就是将结构元素的原点与二值图像中的1重叠,将二值图像中重叠部分不是1的值变为1,完成膨胀)。

A和B是两个集合,A被B膨胀定义为:
在这里插入图片描述
其中,A是图像,B是结构元,结构元通常比图像小得多。膨胀满足结合律和交换律。

使用函数imdilate进行膨胀,语法为:

D = imdilate(A,B)  %A是图像,B是结构元

示例:

A = imread('keyb1.jpg');
B = [0 1 0;1 1 1;0 1 0];
subplot(121),imshow(A),title('原图像')
D = imdilate(A,B);
subplot(122),imshow(D),title('执行膨胀后')

在这里插入图片描述
在这里插入图片描述
实验分析:膨胀的模板是[0 1 0;1 1 1;0 1 0],因此在值为1出的周围膨胀为1,可以看出第一张图片的文字变粗了,但是也变模糊了不是我们想要的结果所以将模板改为[0 0 0;1 1 0;0 0 0];,测试下下过如下图:在这里插入图片描述
可以明显看出比之前的模板清晰了,但是膨胀知识单侧,膨胀的幅度并不多。

(2)结构元的分解

结构元B可以描述为结构元B1和B2的膨胀:B=B1⊕B2。由于膨胀满足结合律,所以A⊕B=A⊕(B1⊕B2)=(A⊕B1)⊕B2,这样B就可以分解为B1和B2两个结构元。

进行结构元的分解是使膨胀的速度增加,减少其他不必要的开销。 比如说:

在这里插入图片描述
这样的矩阵操作膨胀需要对25个元素进行膨胀,若将其分解成如下形式:

在这里插入图片描述

这样的操作速度就会从膨胀25个元素变成操作10个元素即可。

(3)strel函数

strel函数是用于构造各种形状和大小的结构元,语法为:

se = strel(shape,parameters) %shape是用于指定希望形状的字符串,parameters是形状信息的参数

在这里插入图片描述
示例:

se = strel('diamond',5)  %构造菱形结构元,水平和垂直均扩展5个像素
decomp = getsequence(se);    %提取并检查分解中单独的结构元
whos
into decomp:
decomp(1).Neighborhood
decomp(2).Neighborhood
decomp(3).Neighborhood
decomp(4).Neighborhood

(4)腐蚀

腐蚀是膨胀的反操作,是将图像中的目标进行“细化”的操作,收缩的方法和程度也由结构元控制。A被B腐蚀表示为AΘB,集合操作表示为:

在这里插入图片描述

在matlab工具中,运用函数imerode进行腐蚀操作,编写代码如下:

A = imread('car.jpg');
subplot(221),imshow(A),title('原始图像')
se = strel('disk',10);
E10 = imerode(A,se);
subplot(222),imshow(E10),title('半径为10进行腐蚀')

se = strel('disk',5);
E5 = imerode(A,se);
subplot(223),imshow(E5),title('半径为5进行腐蚀')

se = strel('disk',20);
E20 = imerode(A,se);
subplot(224),imshow(E20),title('半径为20进行腐蚀')

在这里插入图片描述
实验分析: 腐蚀相当于膨胀的反操作,将内部图像进行腐蚀,黑色边缘就变得越来越粗,当我们使用半径不同的结构元时,可以得到不一样的腐蚀结果。腐蚀可以用于弥补小裂缝的。假设把叮当猫的眼睛当成孔洞,用半径为20的圆形结构元进行腐蚀,结果显示可以将腐蚀操作可以眼睛填充,作用弥合裂缝孔洞等。

(三)膨胀与腐蚀的结合

3.1 开操作和闭操作
开操作:

  1. 使图像的轮廓变得光滑,断开狭窄的间断和消除细的突出物。

  2. 使用结构元素B对集合A进行开操作,定义为:

  3. 先用B对A腐蚀,然后用B对结果膨胀。
    与开操作等价的数学表达式为:
    在这里插入图片描述

  4. A o B 的边界通过B中的点完成。

  5. B在A的边界内转动时,B中的点所能到达的A的边界的最远点。

在这里插入图片描述

  1. A o B 是 A的子集合。
  2. 如果C是D的子集,则 C o B是 D o B的子集。
  3. (A o B) o B = A o B

闭操作:

  1. 同样使图像的轮廓变得光滑,但与开操作相反,它能消除狭窄的间断和长细的鸿沟,消除小的孔洞,并填补轮廓线中的裂痕。

  2. 使用结构元素B对集合A进行闭操作,定 义为:在这里插入图片描述
    先用B对A膨胀,然后用B对结果腐蚀。

  3. A . B的边界通过B中的点完成 。

  4. B在A的边界外部转动 :在这里插入图片描述

  5. A 是 A . B的子集合。

  6. 如果C 是 D 的子集 , 则C . B 是 D . B的子集。

  7. (A . B) . B = A . B

工具箱函数:

C = imopen(A, B)

闭操作:

C = imclose(A, B)

A为二值图像,B为0,1矩阵组成,并且是指定结构元素。

函数imopen 和 imclose 的应用:

f = imread('kai.png');
se = strel('square', 40);
fo = imopen(f, se);
fc = imclose(f, se);
foc = imclose(fo, se);
subplot(2,2,1), imshow(f), title('(a)原图');
subplot(2,2,2), imshow(fo), title('(b)开操作');
subplot(2,2,3), imshow(fc), title('(c)闭操作');
subplot(2,2,4), imshow(foc), title('(d) (b)的闭操作结果');

在这里插入图片描述

实验分析:

  1. 图(a)中的图像设计了一些用于演示开操作和闭操作的特征,比如细小突起、细的桥接点、几个弯口、孤立的小洞、 小的孤立物和齿状边缘。
  2. 图 (b)显示了结果。注意,从图中可以看出,细的突出和外部点的边缘的不规则部分被去除掉了,细的桥接和小的孤立物也被去除了。
  3. 图 ©中的结果: 这里,细的弯口、内部的不规则边缘和小洞都被去除了。先做开操作的闭操作的结果有平滑效果.
  4. 图 (d)显示了平滑过的物体。

噪声滤波器:

示例代码:

f = imread('att.jpg');
se = strel('square', 6);
fo = imopen(f, se);
foc = imclose(fo, se);
subplot(1,3,1), imshow(f), title('(a)带噪声的指纹图像');
subplot(1,3,2), imshow(fo), title('(b)图像的开操作');
subplot(1,3,3), imshow(foc), title('(c)先用开操作,再用闭操作');

在这里插入图片描述

实验分析:我们可以将图中细小的点看作为噪声,再经过开操作与比操作之后,噪声被过滤之后效果还比较理想。

3.2 击中或击不中变换

击中击不中变换(HMT),HMT变换可以同时探测图像的内部和外部。研究解决目标图像识别模式识别等领域,在处理目标图像和背景的关系上能够取得更好的效果。

作用:形状检测的基本工具。

A中对B进行的匹配(击中)表示为:

在这里插入图片描述

B1是由与一个对象相联系的B元素构成的集合,

在这里插入图片描述
使用函数bwhitmiss实现,语法为:

C = bwhitmiss(A,B1,B2)

示例:

f =  rgb2gray(imread('att.jpg'));
subplot(121),imshow(f),title('原始图像')
B1 = strel([0 0 0;0 1 1;0 1 0]);
B2 = strel([1 1 1;1 0 0;1 0 0]);
g = bwhitmiss(f,B1,B2);
subplot(122),imshow(g,[]),title('击中或击不中变换')
interval = [-1 -1 -1;-1 1 1;-1 1 0]  %间隔矩阵

在这里插入图片描述

执行击中或击不中变换的图像,仔细一看,是将原图像中符合匹配的点提取出来,显示在上面,由于图像比较暗,所以不是很明显。击中或击不中变换就是当符合的点提取,用来查找局部内容的形态学操作。

3.3 bwmorph函数

工具箱函数 bwmorph 执行许多以膨胀、腐蚀和查找表运算相结合为基础的形态学操作, 调用语法为:

g = bwmorph(f, operation, n);

f 是输入的二值图像,operation 是指定所希望运算的字符串,n 是指定重复次数的正整数。

示例:

f = rgb2gray(imread('fig.tif'));
g1 = bwmorph(f, 'thin',1);
g2 = bwmorph(f, 'thin',2);
ginf = bwmorph(f,'thin', Inf);
subplot(1,4,1),imshow(f);title('(a)指纹图像:');
subplot(1,4,2),imshow(g1);title('(b)细化一次后的指纹图像:');
subplot(1,4,3),imshow(g2);title('(c)细化两次后的图像:');
subplot(1,4,4),imshow(ginf);title('(d)一直细化到稳定状态的图像:');

在这里插入图片描述
在这里插入图片描述
**分析:**进行去除“毛刺”操作,得到的图像与上面骨骼化后的图像基本一致。虽然所运用的算法操作不同,但是结果会可能基本一致。这个去除“毛刺”的操作被称为裁剪,可以使用endpoints来获得,其原因是进行反复确认并去除端点。通过3次去除端点的迭代,变成了骨骼化的结果。

(四)标记连通分量

工具箱函数:

[L, num] = bwlabel (f, conn)

f 是输入二值图像,coon指定希望的连接方式(不是4连接就是8连接),输出L叫做标记矩阵,函数num则给出找到的连通分量总数。

计算和显示连通分量的质心:

f = rgb2gray(imread('zimu.tif'));
imshow(f);title('(a)标注连通分量原始图像:');
[L,n]=bwlabel(f);        %L为标记矩阵,n为找到连接分量的总数
[r,c]=find(L==3);        %返回第3个对象所有像素的行索引和列索引 
rbar=mean(r);
cbar=mean(c);
figure,imshow(f);title('(b)标记所有对象质心后的图像:');
hold on            %保持当前图像使其不被刷新
for k=1:n
   [r,c]=find(L==k);
   rbar=mean(r);
   cbar=mean(c);
   plot(cbar,rbar,'Marker','o','MarkerEdgeColor','k',...
        'MarkerFaceColor','k','MarkerSize',10);
   plot(cbar,rbar,'Marker','*','MarkerFaceColor','w'); %其中的marker为标记
end

在这里插入图片描述

(五)形态学重建

概述:重构是一种涉及到两幅图像和一个结构元素的形态学变换。一幅图像,即标记,是变换的开始点。另一幅图像是掩膜,用来约束变换过程。结构元素用于定义连接性。

定义:若G是掩膜,f为标记,则从f重构g可以记为 R g R_g Rg(f),由下列的迭代过程定义:

  1. 将h1初始化为标记图像f。
  2. 创建结构元素 :B = ones(3)。
  3. 重复在这里插入图片描述
    直到 h k + 1 h_{k+1} hk+1 = h k h_k hk
    其中,标记f必须是g的一个子集。

以上是理论的方法,但实际会使用更快的计算方法,在matlab中使用函数imreconstruct用于快速混合重建算法,编写为:

out = imreconstruct(marker,mask)

5.1 通过重建进行开操作

在形态学开操作中,腐蚀典型地去除小的物体,且随后的膨胀趋向于恢复保留的物体形状。但这个恢复的精确度取决于形状和结构元之间的相似性,说明并不是所有情况都是适用的。现在,用一种比较好的方式来解决这个问题,那就是通过重建进行开操作能准确地恢复腐蚀之后的物体形状。

其集合表示为:

R G R_G RG(G-B)

编写实验代码:

f =  imread('info.jpg');
fe = imerode(f,ones(51,1));
fo = imopen(f,ones(51,1));
fobr = imreconstruct(fe,f);
subplot(221),imshow(f),title('原始图像');
subplot(222),imshow(fe),title('用竖线腐蚀后图像');
subplot(223),imshow(fo),title('用竖线进行开操作图像');
subplot(224),imshow(fobr),title('用竖线重建后图像');

在这里插入图片描述
分析:实验结果不是很清楚,但是放大可以看出处理后的结果,我们可以通过imhist函数看下:

在这里插入图片描述
可以看出灰度值出现了两个峰,一个大一个小,可以判断出图片中应该是有文字的。

5.2 填充孔洞

令I表示二值图像,假设我们选择标记图像F,除了图像边缘外,其余部分都为 0, 边缘部分设值为 1-I:
在这里插入图片描述
函数:g = imfill(f,‘holes’);

5.3 清除边界物体

定义标记图像F为:

在这里插入图片描述
其中,/是原始图像,然后以/作为模板图像,重建
在这里插入图片描述
得到一幅图像H, 其中仅包含与边界接触的物体。

在MATLAB工具箱中可以使用函数imclearborder将图像边缘接触的物体清除:

g = imclearborder(f,4); %conn的值默认是8,也可以选择4

在这里插入图片描述
清楚边界之后的图像清晰了许多。

(六)灰度级形态学

6.1 膨胀和腐蚀

灰度图像的形态学梯度定义为膨胀运算与腐蚀运算的结果之间的差值。

用结构元b对灰度图像f的灰度进行膨胀,表示为:

在这里插入图片描述

可以将灰度膨胀简化为如下形式,这是使用平的结构元进行计算的:

在这里插入图片描述
在实验中,非平的结构元通过两个矩阵使用strel函数进行构造。这两个矩阵包括由结构元的域指定的0和1的矩阵和由高度值指定的矩阵,编写代码:

b = strel([1 1 1],[1 2 1])

在这里插入图片描述

然而平坦的结构元也是通过函数strel构造的,编写实验代码:

f =  imread('zimu.tif');
subplot(121),imshow(f),title('原始图像');
se = strel('square',3);
gd = imdilate(f,se);
subplot(122),imshow(gd),title('膨胀后图像');

在这里插入图片描述

用结构元b对灰度图像f的灰度进行腐蚀,表示为:

在这里插入图片描述

同理,通常灰度腐蚀使用的结构元时平的结构元,简化为:

在这里插入图片描述

编写实验代码:

f =  imread('zimu.tif');
subplot(121),imshow(f),title('原始图像');
ge = imerode(f,se);
subplot(122),imshow(ge),title('腐蚀后图像');

在这里插入图片描述
在这里插入图片描述

morph_grad = gd-ge;   %用于计算形态学的梯度
imshow(morph_grad),title('形态学梯度')

在这里插入图片描述

6.2 开操作和闭操作

  1. 在灰度图像中,开操作的表达式与二值图像拥有相同的形式。在这里插入图片描述

  2. 把一幅图像看做是一个三维表明,其亮度值代表xy平面上的高度值,则当结构元素b在f下面活动时,结构元素的任何部分的最高值构成了开运算的结果。

  3. 先进行腐蚀操作可以除去小的亮的图像细节,但这样会使图像变暗,接下来进行膨胀操作增强图像的整体亮度。

图像闭运算:

  1. 在灰度图像中,闭操作的表达式与二值图像拥有相同的形式。在这里插入图片描述

  2. 当结构元素b在f的上面活动时,结构元素的任何部分的最低值构成了闭运算的结果 。

  3. 先通过膨胀操作除去图像中的暗细节,同时增加图像的亮度,接下来对图像进行腐蚀,而不会将膨胀操作除去的部分重新引入图像中。

用开操作和闭操作做形态学平滑 :

f = imread('att.jpg');
subplot(3,2,1),imshow(f);  
title('(a)木钉图像原图');   
se=strel('disk',5);     %disk其实就是一个八边形  
fo=imopen(f,se);        %经过开运算  
subplot(3,2,2),imshow(f);  
title('(b)使用半径5的disk开运算后的图像');   
foc=imclose(fo,se);  
subplot(3,2,3),imshow(foc);  
title('(c)先开后闭的图像'); 
focd=imclose(f,se);  
subplot(3,2,4),imshow(focd);  
title('(d)原始图像的闭操作'); 
foce=imopen(focd,se);  
subplot(3,2,5),imshow(foce);  
title('(e)先闭后开的图像'); 
fasf=f;  
for i=2:5  
    se=strel('disk',i);  
    fasf=imclose(imopen(fasf,se),se);  
end  
subplot(3,2,6),imshow(fasf);  
title('(f)使用开闭交替滤波后图像'); 


在这里插入图片描述
分析:

  1. 图 (b)显示了开操作的图像 fo, 在这里,我们看到,亮区域己经被调低了(平滑),木钉上的暗条文几乎没有受影响。
  2. 图 (c )显示了开操作的闭操作 foe。现在我们注意到,暗区域已经被平滑得很好了,结果是整个图像得到全部平滑。这种过程通常叫做开-闭滤波。先开运算后闭运算构成噪声滤波器,用来平滑图像并去除噪声。
  3. 图 (d)显示了原始图像的闭操作结果。木钉上的暗条文已经被平滑掉了,主要留下了亮的细节(注意背景中的亮条文)。
  4. 图 (e)显示了这些条文的平滑和木钉表面的进一步平滑效果。最终结果是原始图像得到全部平滑。
  5. 图(f)是交替顺序滤波,交替顺序滤波的一种形式是用不断增大的一系列结构元执行开-闭滤波,刚开始用小的结构元,增加大小,直到与图 (b)和©中结构元的大小相同为止。交替顺序滤波与单个开-闭滤波相比,处理图像更平滑一些。

非均匀背景的补偿 :

f = rgb2gray(imread('mi.tif'));
g = f>=(255*graythresh(f));
se=strel('disk',100);
fo=imopen(f,se);
f2=imsubtract(f,fo); 
g1 = f2>=(255*graythresh(f2));
subplot(2,3,1),imshow(f);  
title('(a)原始图像');  
subplot(2,3,2),imshow(g);  
title('(b)经过阈值处理后的图像');   
subplot(2,3,3),imshow(f);  
title('(c)原图开运算后的图像');  
subplot(2,3,4),imshow(f2);  
title('(d)原图减去开运算');  
subplot(2,3,5),imshow(g1);  
title('(e)最终结果');  

在这里插入图片描述

分析:

  1. 图 (a) :显示了一幅米粒的图像f,图像下部的背景比上部的黑。这样的话,对不平坦的亮度进行阈值处理会很困难。
  2. 图 (b) "是阈值处理方案,图像顶端的米粒被很好地从背景中分离开来,但是图像底部的米粒没有从背景中正确地提取出来。
  3. 图(c ):对图像进行开操作,可以产生对整个图像背景的合理估计。
  4. 图(d) :把图(c )从原始图像中减去,生成一幅拥有合适的均勾背景的米粒图像.
  5. 图(e):显示了新的经阈值处理后的图像。注意,改进效果超过了图 (b)。

6.3 重建

重建

  1. h极小值变换:标记图像是由掩膜挑选ing减去常量所得。
  2. 开运算重建:先腐蚀后重建。
  3. 闭运算重建:对图像求补、计算其开操作重建并对结果求补。

重建移去复杂的背景 :

f = imread('keyb1.jpg');
subplot(3,3,1),imshow(f);  
title('(a)原图像');    
f_obr=imreconstruct(imerode(f,ones(1,71)),f);  
subplot(3,3,2),imshow(f_obr);  
title('(b)重建的开操作');   
f_o=imopen(f,ones(1,71));    
subplot(3,3,3),imshow(f_o);  
title('(c)开操作');    
f_thr=imsubtract(f,f_obr);    %顶帽重构
subplot(3,3,4),imshow(f_thr);  
title('(d)重建的顶帽操作');  
f_th=imsubtract(f,f_o)    %标准顶帽运算,方便比较
subplot(3,3,5),imshow(f_th);  
title('(e)顶帽操作');  
g_obr=imreconstruct(imerode(f_thr,ones(1,11)),f_thr);  
subplot(3,3,6),imshow(g_obr);  
title('(f)用水平线对(b)经开运算后重建图');   
g_obrd=imdilate(g_obr,ones(1,2));  
subplot(3,3,7),imshow(g_obrd);  
title('(g)使用水平线对(f)进行膨胀');  
f2=imreconstruct(min(g_obrd,f_thr),f_thr);  
subplot(3,3,8),imshow(f2);  
title('(h)最后的重建结果');  

在这里插入图片描述
为了消除每个键盘上方的水平反射光,利用这些反射比图像中任何文本字符都要宽的这个事实。用长水平线的结构元执行重建的开操作,重建的开操作(f_obr) 显示于图(b)中。为了进行对比,图(c )显示了标准的开操作 (f_o) 。重建的开操作在提取水平的相邻键之间的背景方面的确较好。从原始图像中减去重建的开操作被称为顶帽重建 , 结果示于图 (d)中。消除图 (d)中键右边的垂直反射光。这可以通过用短的水平线执行重建的开操作来完成,在这个结果中(见图 (f)),垂直的反射光不见了。但是,包括字母的垂直的细笔画也不见了。我们利用了那些已被错误消除的字母非常接近第一次膨胀(见图 (g))后还存在的其他字符这一事实,以 f_thr 作为模板,以 min(g_obrd,f_thr) 作为标记,图 (h)显示了最后的结果。注意,背景上键盘的阴影和反射光都成功去除了。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
形态学图像处理是一种基于数学形态学原理的图像处理方法,可以用于图像的特征提取、边缘检测、形状分析等。在Python中,有多种库可以进行形态学图像处理,如OpenCV和scikit-image。 在OpenCV中,可以使用cv2.morphologyEx函数进行形态学图像处理。其中,可以使用cv2.MORPH_GRADIENT参数来进行形态学梯度操作,即膨胀图与腐蚀图之差。下面是一个使用OpenCV进行形态学梯度操作的示例代码: ```python import numpy as np import cv2 # 读取输入图像 img = cv2.imread('g1.png') # 定义卷积核 kernel = np.ones((6,6), dtype="uint8")/9 # 进行形态学梯度操作 gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) # 保存结果图像 cv2.imwrite('gradient.jpg', gradient) ``` 另外,scikit-image库也提供了一些形态学图像处理的函数。可以使用skimage.morphology模块中的函数进行膨胀、腐蚀等操作。下面是一个使用scikit-image进行膨胀与腐蚀操作的示例代码: ```python from skimage.morphology import erosion, dilation from skimage.morphology import square from skimage.color import rgb2gray from skimage.io import imread # 读取输入图像并转为灰度图像 im = imread('zebras.jpg', as_gray=True) # 进行腐蚀操作 selem = square(5) eroded = erosion(im, selem) # 进行膨胀操作 dilated = dilation(im, selem) ``` 以上是使用OpenCV和scikit-image库进行形态学图像处理的示例代码,你可以根据自己的需求选择合适的库和函数进行图像处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值