(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx

上传人:李司机 文档编号:6794932 上传时间:2024-02-21 格式:DOCX 页数:16 大小:209.50KB
返回 下载 相关 举报
(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx_第1页
第1页 / 共16页
(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx_第2页
第2页 / 共16页
(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx_第3页
第3页 / 共16页
(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx_第4页
第4页 / 共16页
(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx》由会员分享,可在线阅读,更多相关《(OpenCV+Python)六种算子 Sobel Scharr 拉普拉斯 Laplacian Roberts Prewitt.docx(16页珍藏版)》请在三一办公上搜索。

1、我们在教程顶帽与黑帽操作中留了一个小彩蛋一一形态学的梯度问题,通常情况下,它被用于提取图像的轮廓。今天我们来了解图像边缘的另一种方法,它将比形态学梯度更有效,适用范围也更广。Sobel算子前面的例子,已经接触到了图像卷积运算。最重要的卷积运算之一是用于计算图像的导数(或近似导数)。为什么图像中导数的计算很重要,看下面边缘检测的例子:很容易观察到上面图像中像素灰度值变化没有规律。一种比较好的描述这种变化的方法是采用导数。其中梯度剧烈变化的地方代表图像灰度值变化强烈的地方,也就是边缘。为了更好的说明,以1维图像(也就是图像的1行)为例。边缘出现在灰度值跳变的地方,如下图所示:如果对上面的1维图像求

2、导数,得到下图,可以很明显的看到边缘所在的位置。从上面的解释,我们可以设置一个阈值,根据局部像素变化强烈程度获取图像边缘。Sobel算子是一个离散微分算子,计算得到的是图像梯度的近似值。SobeI算子结合了高斯平滑和微分。假设输入图像是L,核大小为3,通过下面运算分别计算水平方向和垂直方向的微分:a.水平方向:b.垂直方向:-1-2-1Gy=000*I.+1+2+1.具体运算为:Gx=(-1)f(-ly-1)+0f(x,y-1)+7f(x+1,yT)+(-2)依-7M+(,y)2*f(x1,y)Sf(x-1,y+1)+(fy+1)f(x+1,y1)=f(xLyT)+2行,行,yra(xT,y)

3、+f(x1y+1)lGy=f(x-1,y-1)2加W7f(x1,y-1)7f(xT,y)+0*f(x1,y)+(-1)-f(x-1,y+1)+(-2)-f(x,y1)(-1)f(1,y1)=(f(x-ly-l)+2f(x,y-1)+f(x1,y-1)-f(-l,y+1)2*f(x,y+1)+f(x+l,y+1)结合上面结果可以计算出图像中一个点的近似梯度:G=yGl+Gl或者表示为:G=田+IGyl需要注意的是,当核的大小为3时,也就是上面所示的SObel核可能会产生明显的误差(毕竟Sobel只是微分的近似值)。在C)PenCV-PythOn中,使用Sobel的算子的函数原型如下:dst=cv

4、2.Sobel(src,ddepth,dx,dy,dst,ksize,scale,delta,borderTypeJ)(1)前四个是必须的参数:第一个参数是需要处理的图像。第二个参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度。dx和dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0、1、2o(2)其后是可选的参数:dst不用解释了。ksize是SObel算子的大小,必须为1、3、5、7。scale是缩放导数的比例常数,默认情况下没有伸缩系数。delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中。bor

5、defype是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULTo现在我们来看实验图像:实战代码:importcv2importnumpyasnpimg=cv2.imread(,pie.png,0)x=cv2.Sobel(img,cv2.CV_l6S,1,0)cv2.imshow(x,x)cv2.waitKey(0)cv2.destroyAIlWindows()我们发现没有输出,原因在于图像格式的问题,在SObel函数的第二个参数这里使用了cv2.CV_16So因为OPenCV文档中对Sobel算子的介绍中有这么一句:“inthecaseof8-bitinputimage

6、sitwillresultintruncatedderivatives,oBRSobel函数求完导数后会有负值,还有会大于255的值。而原图像是uint8,即8位无符号数,所以SObel建立的图像位数不够,会有截断。因此要使用16位有符号的数据类型,即cv2.CV6S。在经过处理后,别忘了用ConVertSCaIeAbSO函数将其转回原来的Uint8形式。否则将无法显示图像,而只是一副灰色的窗口。COnVertSCaIeAbS()的原型为:dst=cv2.convertScaleAbs(src,dst,alpha,beta)其中可选参数alpha是伸缩系数,beta是加到结果上的一个值。结果返

7、回uint8类型的图片。由于Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted。.)函数将其组合起来。其函数原型为:dst=cv2.addWeighted(src1,alpha,src2,beta,gamma,dst,dtypeJ)当然,这个函数我们在前面已经讲述过在这里就不多讲述了。我们再来看代码:importcv2importnumpyasnpimg=cv2.imread(,pie.png,0)x=cv2.Sobel(img,cv2.CV_16S,1,0)y=cv2.Sobel(img,cv2.CV_16S,0,1)absX=cv2.convertScaleAbs

8、(x)absY=cv2.convertScaleAbs(y)dst=cv2.addWeighted(absX,0.5,absY,0.5,0)cv2.imshow(x,absX)cv2.imshow(,y,absY)cv2.imshow(,res,dst)cv2.waitKey(0)cv2.destroyAllWindows()先分别来看下,x,y两个方向上的:再看看最终相加在一起的:由于Sobel算子是滤波算子的形式,用于提取边缘,可以利用快速卷积函数,简单有效,因此应用广泛。美中不足的是,Sobel算子并没有将图像的主体与背景严格地区分开来,即SobeI算子没有严格地模拟人的视觉生理特征,所

9、以提取的图像轮廓有时并不能令人满意。Scharr算子ScharrO函数提供了比标准SObeI函数更精确的计算结果。它使用了下面的核:-3O+3-3-10-3GX=-10O+10和Gy=OOO-3O+3.,+3+10+3除了卷积核与SobeI不同,在其余方面它与SObel基本一致,我们来看它的函数原型:dst=cv2.Scharr(src,ddepth,dx,dy,dst,ksize,scale,delta,borderTypel)参数就不再介绍了,与SObel是完全一致的,我们来看看代码演示:importcv2importnumpyasnpimg=cv2.imread(pie.png,0)x=

10、cv2.Scharr(img,cv2.CV_16S,1,0)y=cv2.Scharr(img,cv2.CV_16S,0,1)absX=cv2.convertScaleAbs(x)absY=cv2.convertScaleAbs(y)dst=cv2.addWeighted(absX,0.5,absY,0.5,0)cv2.imshow(,res,dst)cv2.waitKey(0)cv2.destroyAHWindows()本次教程所讲述的Sobel算子与Scharr算子在图形的边缘检测方面有些缺陷,想必大家也看到了,不过在下面我们将会讲述这个问题。拉普拉斯算子我们在上面教程中的例子学习了使用So

11、bel边缘检测。原理是利用边缘区域像素值的跳变。通过求一阶导数,可以使边缘值最大化。如下图所示:那么,如果求二阶导数会得到什么呢?可以观察到二阶导数为O的地方。因此,可以利用该方法获取图像中的边缘。然而,需要注意的是二级导数为O的不只出现在边缘地方,还可能是一些无意义的位置,根据需要通过滤波处理该情况。二阶微分现在我们来讨论二阶微分,它是拉普拉斯算子的基础,与微积分中定义的微分略有不同,数字图像中处理的是离散的值,因此对于一维函数的一阶微分的基本定义是差值:察=胆+1)-加C/Jb类似的,二阶微分定义为:=(x+l)+(rr-l)-2(x)将一维函数扩展到二维:废=胆+1,y)+f(Ll,y)

12、-2f(x,y)2f二阶微分的定义保证了以下几点:在恒定灰度区域的微分值为零。在灰度台阶或斜坡的起点处微分值非零。可以看出,二阶微分可以检测出图像的边缘、增强细节。拉普拉斯算子从上面的解释,可以看出二阶导数可以拥有边缘检测。由于图像是二维的,因此需要分别获取两个方向的导数。这里使用的是拉普拉斯算子来进行近似。拉普拉斯算子用下面公式定义:,、92f2f1.aplace(f=-其中:E=/x+L川-2x,+x-LyOXTTT=/xJ+1-2用+-16y可以用多种方式将其表示为数字形式。对于一个3*3的区域,一般情况下被推荐最多的形式是:V2/=4=(z+Ly)+(-i,y)+/(&y+i)+/(*

13、-1)一V(y)实现上式的滤波器模板为:O101-41010_我们可以发现,拉普拉斯算子不需要向Sobel算子那样分别对X,y方向进行处理,它可以直接处理,现在我们来看看OPenCV中的拉普拉斯算子的函数原型:dst=cv2.Laplacian(src,ddepth,dst,ksize,scale,delta,borderType)(1)前两个是必须的参数:第一个参数是需要处理的图像。第二个参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度。(2)其后是可选的参数:dst不用解释了。ksize是算子的大小,必须为1、3、5、7o默认为1。SCale是缩

14、放导数的比例常数,默认情况下没有伸缩系数。delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中。borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULTo我们来看代码:importcv2importnumpyasnpimg=cv2.imread(,pie.png,)dst=cv2.Laplacian(img,cv2.CV_16S,ksize=3)dst=cv2.convertScaleAbs(dst)cv2.imshow(uimg,img)cv2.imshow(nres,dst)cv2.waitKey(0)cv2.d

15、estroyAllWindows()现在可以拿这个结果对比上一个教程的结果了,我们发现,这个结果要比上一个教程的结果好的多,对于边缘检测没有大的偏差。然而事实上,这只是对于简单的图像而言,而对于一幅复杂的图像,那么边缘提取就有点爱莫能助了,我们来看代码:importcv2importnumpyasnpimg=cv2.imread(cat.jpg,)dst=cv2.Laplacian(img,cv2.CV_16S,ksize=3)dst=cv2.convertScaleAbs(dst)cv2.imshow(uimg,img)cv2.imshow(,res,dst)cv2.waitKey(0)cv

16、2.destroyAllWindows()可以看到,对于较为复杂的图像,拉普拉斯算子的效果也并不是很好,由于二阶微分一定的局限性,目前的边缘检测还不够完美,我们需要一种综合的算法,而这将在下一个教程中介绍到。1.aplacian算子拉普拉斯(LaPIaCian)算子是n维欧几里德空间中的一个二阶微分算子,常用于图像增强领域和边缘提取。它通过灰度差分计算邻域内的像素,基本流程是:判断图像中心像素灰度值与它周围其他像素的灰度值;如果中心像素的灰度更高,则提升中心像素的灰度;反之降低中心像素的灰度,从而实现图像锐化操作。在算法实现过程中,Laplacian算子通过对邻域中心像素的四方向或八方向求梯度

17、,再将梯度相加起来判断中心像素灰度与邻域内其他像素灰度的关系,最后通过梯度运算的结果对像素灰度进行调整12o一个连续的二元函数f(x,y),其拉普拉斯运算定义为:a+亚x221.aplacian算子分为四邻域和八邻域,四邻域是对邻域中心像素的四方向求梯度,八邻域是对八方向求梯度。其中,四邻域模板如公式(5)所示:0-1O-H=-14-1。-1Q其像素的计算公式可以简化为:通过模板可以发现,当邻域内像素灰度相同时,模板的卷积运算结果为0;当中心像素灰度高于邻域内其他像素的平均灰度时.,模板的卷积运算结果为正数;当中心像素的灰度低于邻域内其他像素的平均灰度时,模板的卷积为负数。对卷积运算的结果用适

18、当的衰弱因子处理并加在原中心像素上,就可以实现图像的锐化处理。Laplacian算子的八邻域模板如下:- 1-1-1H=-18-1- 1-1-1其像素的计算公式可以简化为:g)=8)-(+,-i)-(z+,7)-(+,y+i)- ,-n-fa./+n-f(i,/-n-fa、/)-L+nPython和OpenCV将Laplacian算子封装在Laplacian()函数中,其函数原型如下所示:dst=Laplacian(src,ddepth,dst1,ksize,scale,delta,borderTypeJ)-src表示输入图像-dst表示输出的边缘图,其大小和通道数与输入图像相同-ddepth

19、表示目标图像所需的深度-ksize表示用于计算二阶导数的滤波器的孔径大小,其值必须是正数和奇数,且默认值为1,更多详细信息查阅getDerivKernels-scale表示计算拉普拉斯算子值的可选比例因子。默认值为1,更多详细信息查阅getDerivKernels-delta表示将结果存入目标图像之前,添加到结果中的可选增量值,默认值为O-borderType表示边框模式,更多详细信息查阅BorderTypes注意,Laplacian算子其实主要是利用Sobel算子的运算,通过加上Sobel算子运算出的图像X方向和y方向上的导数,得到输入图像的图像锐化结果。同时,在进行Laplacian算子处

20、理之后,还需要调用ConvertScaleAbs()函数计算绝对值,并将图像转换为8位图进行显示。其算法原型如下:dst=convertScaleAbs(src,dst,alpha,beta)-src表示原数组-dst表示的出数组,深度为8位-alpha表示比例因子-beta表示原数组元素按比例缩放后添加的值当ksize=lW,LaplacianO函数采用33的孔径(四邻域模板)进行变换处理。下面的代码是采用ksize=3的Laplacian算子进行图像锐化处理,其代码如下:# -*-coding:utf-8-*-# By:Eastmountimportcv2importnumpyasnpim

21、portmatplotlib.pyplotaspit# 读取图像img=cv2.imread(luo.png,)lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)# 灰屋化处理图像grayimage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 拉普拉斯算法dst=cv2.Laplacian(graylmage,cv2.CV_16S,ksize=3)1.aplacian=cv2.convertScaleAbs(dst)#用来正常显示中文标签plt.rcParamsfont.sans-serif=,SimHei,#显示图形ti

22、tles=原始图像,Laplacian算子1images=lenna_img,Laplacianforiinrange(2):plt.subplot(l,2,i+l),plt.imshow(imagesi,gray)plt.title(titlesi)plt.xticks(),plt.yticks()plt.show()其运行结果如图2所示:KFigure1原始图像LaPliCian算子By:Eastmountw*Q闰倒边缘检测算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此需要采用滤波器来过滤噪声,并调用图像增强或阈值化算法进行处理,最后再进行边缘检测。下面是采用高斯滤波

23、去噪和阈值化处理之后,再进行边缘检测的过程,并对比了四种常见的边缘提取算法。# -*-coding:utf-8-*-# ByiEastmountimportcv2importnumpyasnpimportmatplotlib.pyplotaspit# 读取图像img=cv2.imread(luo.png)lenna_img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)# 灰氤处理图像grayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 局斯滤波gaussianBlur=cv2.GaussianBlur(grayImage,(3

24、,3),)# 阈值处理ret,binary=cv2.threshold(gaussianBlur,127,255,cv2.THRESH_BINARY)#Roberts算子kernelx=np.array(-1,0,0,1,dtype=int)kernely=np.array(O,-1,1,0J,dtype=int)x=cv2.filter2D(binary,cv2.CV_16S,kernelx)y=cv2.filter2D(binary,cv2.CV_16S,kernely)absX=cv2.convertScaleAbs(x)absY=cv2.convertScaleAbs(y)Robert

25、s=cv2.addWeighted(absX,0.5,absY,0.5,0)#Prewitt算子kernelx=np.array(1,1,1,0,0,0,-1,-1,-1,dtype=int)kernely=np.array(l-1,0,1JJ-1,0,1,l-1,0,1,dtype=int)x=cv2.filter2D(binary,cv2.CV_16S,kemelx)y=cv2.filter2D(binary,cv2.CV_16S,kemely)absX=cv2.convertScaleAbs(x)absY=cv2.convertScaleAbs(y)Prewitt=cv2.addWeig

26、hted(absX,0.5,absY,0.5,0)#Sobel算子x=cv2.Sobel(binary,cv2.CV_16S,1,0)y=cv2.Sobel(binary,cv2.CV_16S,0,1)absX=cv2.convertScaleAbs(x)absY=cv2.convertScaleAbs(y)Sobel=cv2.addWeighted(absX,0.5,absY,0.5,0)# 拉普拉斯算法dst=cv2.Laplacian(binary,cv2.CV_16S,ksize=3)1.aplacian=cv2.convertScaleAbs(dst)# 效果图titles=,Sou

27、rceImage*,BinaryImage,RobertsImage,PrewittImage,SobelImage1,LaplacianImage1images=lenna_img,binary,Roberts,Prewitt,Sobel,Laplacianforiinnp.arange(6):plt.subplot(2,34l),plt.imshow(imagesi,gray,)plt.title(titlesi)plt.xticks(),plt.yticks()plt.show()输出结果如图3所示。其中,Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边

28、缘像素位于图像的明区或暗区,很少用于边缘检测;Robert算子对陡峭的低噪声图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响;Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。Source Image三、总结Prewitt ImageLaplacian Image本文主要介绍图像锐化和边缘检测知识,详细讲解了Sobel算子和Laplacian算子,并通过小珞珞图像进行边缘轮廓提取。图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提

29、供基础。参考文献:Ul冈萨雷斯著,阮秋琦译。数字图像处理(第3版)MJ.北京:电子工业出版社,2013.12阮秋琦。数字图像处理学(第3版)M.北京:电子工业出版社,2008.引杨秀璋,于小民,范郁锋,李娜。基于苗族服饰的图像锐化和边缘提取技术研究JJ.现代计算机,2018-10.141Eastmount.Python图像处理四。图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波EBOL.(2018-09-02)15 EaStmoUnt.数字图像处理七.MFC图像增强之图像普通平滑、高斯平滑、LaplacianSobeRPrewitt锐化详解EBOL.(2015-06-08).16 DSQiu.

30、图像锐化(增强)和边缘检测EBOL.(2012-08-20).C.rbmasi,RManduchi.BilateralFilteringforGrayandColorimagesC.ProceedingsoftheIEEEInternationalConferenceonComputerVision,Bombay,India.1998:839-846.Roberts算子Roberts算子,又称罗伯茨算子,是一种最简单的算子,是一种利用局部差分算子寻找边缘的算子。他采用对角线方向相邻两象素之差近似梯度幅值检测边缘。检测垂直边缘的效果好于斜向边缘,定位精度高,对噪声敏感,无法抑制噪声的影响。196

31、3年,Roberts提出了这种寻找边缘的算子。Roberts边缘算子是一个2x2的模版,采用的是对角方向相邻的两个像素之差。Roberts算子的模板分为水平方向和垂直方向,如下所示,从其模板可以看出,Roberts算子能较好的增强正负45度的图像边缘。Roberts算子在水平方向和垂直方向的计算公式如下:Roberts算子像素的最终计算公式如下:今天的公式都是小学生水平,千万别再说看不懂了。实现Roberts算子,我们主要通过OPenCV中的filter2D()这个函数,这个函数的主要功能是通过卷积核实现对图像的卷积运算:deffilter2D(src,ddepth,kernel,dst=No

32、ne,anchor=None,delta=None,borderType=None)src:输入图像ddepth:目标图像所需的深度kernel:卷积核接下来开始写代码,首先是图像的读取,并把这个图像转化成灰度图像,这个没啥好说的:# 读取图像img=cv.imread(maliao.jpg,cv.COLOR_BGR2GRAY)rgb_img=cv.cvtColor(img,cv.COLOR_BGR2RGB)# N度化处理图像grayImage=cv.cvtColor(img,cv.COLOR_BGR2GRAY)然后是使用Numpy构建卷积核,并对短度图像在X和y的方向上做一次卷积运算:# R

33、oberts算子kernelx=np.array(l-l,0,0,1,dtype=int)kernely=np.array(l,-1,1,0J,dtype=int)X=cv.filter2D(grayImage,cv.CV_16S,kernelx)y=cv.filter2D(grayImage,cv.CV_16S,kernely)注意:在进行了Roberts算子尿理之后,还需要调用ConVertSCaleAbS()函数计算绝对值,并将图像转换为8位图进行显示,然后才能进行图像融合:# 转Uint8,图像融合absX=cv.convertScaleAbs(x)absY=cv.convertSca

34、leAbs(y)Roberts=cv.addWeighted(absX,0.5,absY,0.5,0)最后是通过pyplot将图像显示出来:# 显示图形titles=原始图像RObertS算子images=rgb_img,Robertsforiinrange(2):plt.subplot(l,2,i+1),plt.imshow(imagesi,gray,)plt.title(titlesi)plt.xticks(l),plt.yticks(l)plt.show()最终结果如下:Prewitt算子Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检

35、测边缘,去掉部分伪边缘,对噪声具有平滑作用。由于Prewitt算子采用3*3模板对区域内的像素值进行计算,而Robert算子的模板为2*2,故Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显Prewitt算子适合用来识别噪声较多、灰度渐变的图像。Prewitt算子的模版如下:在代码实现上,Prewitt算子的实现过程与Roberts算子比较相似,我就不多介绍,直接贴代码了:importcv2ascvimportnumpyasnpimportmatplotlib.pyplotaspit# 读取图像img=cv.imread(maliao.jpg,cv.COLOR_

36、BGR2GRAY)rgb_img=cv.cvtColor(img,cv.COLOR_BGR2RGB)#灰度化处理图像grayimage=cv.cvtColor(img,cv.COLOR_BGR2GRAY)#Prewitt算子kernelx=np.array(H1,1,1,0,0,0,-1,-1,-1,dtype=int)kernely=np.array(-1,0,1,-1,0,1,-1,0,1,dtype=int)x=cv.filter2D(grayImage,cv.CV_16S,kernelx)y=cv.filter2D(grayImage,cv.CV_16S,kernely)# 转uint

37、8,图像融合absX=cv.convertScaleAbs(x)absY=cv.convertScaleAbs(y)Prewitt=cv.addWeighted(absX,0.5,absY,0.5,0)# 用来正常显示中文标签plt.rcParamsfbnt.sans-serif=I1SimHei1J# 显示图形titles二原始图像PreWitt算子?images=rgb_img,Prewittforiinrange(2):plt.subplot(1,2,i+1),plt.imshow(imagesij,gray,)plt.title(titlesi)plt.xticks(l),plt.yticks(U)plt.show()Prewitt 算子从结果上来看,Prewitt算子图像锐化提取的边缘轮廓,其效果图的边缘检测结果比Robert算子更加明显。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号