openCV入门学习基础教程第二篇

2022-11-21 68阅读 0评论

?=1. HSV

由我们上一章所学,导入图片将其转化灰度图并定义显示图片函数cv_show()。

import cv2 #OpenCV读取格式是BGR imPort numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB %matplotlib inline    def cv_show(name,img): cv2.imshow(name,img) cv2.waitKey(0) cv2.destroyAllWindows()    img = cv2.imread('./data/gd01.jpg') img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # img_gray.shape 为 (300,400)
cv_show('win1',img_gray)

openCV入门学习基础教程第二篇

HSV:

H - 色调(主波长)。S - 饱和度(纯度/颜色的阴影)。V值(强度
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # 转换成RGB cv_show('win',hsv)

openCV入门学习基础教程第二篇

2. 图像阈值

上章所学我们得知,矩阵中unit8值(0-255)越大表示越亮,我们可以设定一个阈值thresh,比它大的做什么什么操作,比它小的做什么什么操作。

ret, dst = cv2.threshold(src, thresh, maxval, type) src: 输入图,只能输入单通道图像,通常来说为灰度图

dst: 输出图thresh: 阈值(0-255我们一般取127。)maxval: 当像素值超过了阈值(或者小于阈值,根据Type来决定),所赋予的值。type:二值化操作的类型含以下5种型:cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0。cv2.THRESH_BINARY_INV , THRESH_BINARY的反转。cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变。cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0。cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转。
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV) ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC) ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO) ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV) # ps: ret为127 thresh1-5为图片矩阵 titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV'] images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]   for i in range(6): plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.show()

openCV入门学习基础教程第二篇

可以看到,与原始图片对比,(阈值127)情况下BINARY在亮的地方更亮了(变为255),暗的地方更暗了(变为了0)。BINART_INV与其相反。后三种方法同理如上面所解释。

3. 图像平滑

对图像数据进行滤波操作。

在这之前我们先来学习一下如何给图片加入噪声,变成以下这种。

openCV入门学习基础教程第二篇

可以看到其实就是在这个矩阵随机位置的像素点变成了白色,255。

img = cv2.imread('./data/gd07.jpg')   #获取图片行、列、通道数 rows,cols,channels = img.shape   for i in range(0,5000): #根据在0和行-1之间获取随机整数 x = np.random.randint(0,rows-1) #根据在0和列-1之间获取随机整数 y = np.ranDOM.ranDInt(0,cols-1)   #将通道颜色改为255, (255,255,255) img[x,y][0] = 255 img[x,y][1] = 255 img[x,y][2] = 255   cv_show('win',img)

那么现在我们有了这种图像,该学习如何去掉噪音点了~

blur = cv2.blur(img, (3, 3))均值滤波box = cv2.boxFilter(img,-1,(3,3), nORMalize=True) 方框滤波box = cv2.boxFilter(img,-1,(3,3), normalize=False)方框滤波aussian = cv2.GaussianBlur(img, (5, 5), 1) 高斯滤波median = cv2.medianBlur(img, 5)中值滤波

均值滤波--简单的平均卷积操作(卷积核大小3*3内部值都是1,下方参数是3*3矩阵均值)

blur = cv2.blur(img, (3, 3)) cv_show('win',blur)

openCV入门学习基础教程第二篇

方框滤波--基本和均值一样,可以选择归一化(-1表示颜色通道一致,3*3同上,normalize=True做归一化,此时与上方均值滤波是一样的。)

box = cv2.boxFilter(img,-1,(3,3), normalize=True)   cv_show('win',box)

openCV入门学习基础教程第二篇

方框滤波--基本和均值一样,可以选择归一化,容易越界。(不再均值除以9,和大于255按255赋值。)

box = cv2.boxFilter(img,-1,(3,3), normalize=False)   cv_show('win',box)

openCV入门学习基础教程第二篇

高斯滤波--高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的。(此时卷积核不再全是1,而是离的近的相对较大,离得远的相对较小。)

aussian = cv2.GaussianBlur(img, (5, 5), 1)   cv_show('win',aussian)

openCV入门学习基础教程第二篇

中值滤波--相当于用中值代替(5*5的矩阵25个数,中间值为处理结果。)

median = cv2.medianBlur(img, 5)  # 中值滤波 cv_show('win',median)

openCV入门学习基础教程第二篇

均值、高斯、中值滤波对比:

res = np.hstack((blur,aussian,median)) #print (res) cv_show('median VS average', res)

openCV入门学习基础教程第二篇

4. 形态学-腐蚀操作

所谓腐蚀操作,就是一点点侵蚀图片中的内容,如我刚刚挥笔写下的“帅”字,它长了很多“毛”,我们要把他侵蚀掉:

openCV入门学习基础教程第二篇

img = cv2.imread('./data/s.jpg', cv2.IMREAD_GRAYSCALE) kernel = np.ones((3,3),np.UInt8)  erosiON = cv2.erode(img,kernel,iterations = 1) cv_show('win',erosion)

erosion = cv2.erode(img,kernel,iterations = 1)

kernel 卷积核iterations 迭代次数

这不比之前更帅了(被腐蚀得线条也变瘦了)

openCV入门学习基础教程第二篇

关于卷积核选取和迭代次数:

上面选用3*3,以帅字为例,当3*3区域出现不同值(如这里0和255),那么就把这个点腐蚀掉。

卷积核如果选择太大,可能会直接被侵蚀没掉。

pie = cv2.imread('./data/pie.png') kernel = np.ones((30,30),np.uint8)  erosion_1 = cv2.erode(pie,kernel,iterations = 1) erosion_2 = cv2.erode(pie,kernel,iterations = 3) erosion_3 = cv2.erode(pie,kernel,iterations = 5) res = np.hstack((erosion_1,erosion_2,erosion_3)) cv_show('win',res)

openCV入门学习基础教程第二篇

5. 形态学-膨胀操作

我们上面不仅把“帅”边上长的“毛”去掉了,由于我们选择3*3卷积核,还顺便让它变瘦了,我们就以它变瘦之后的图片为例,再让它胖起来。

img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE) kernel = np.ones((3,3),np.uint8)  shuai = cv2.erode(img,kernel,iterations = 1) kernel = np.ones((3,3),np.uint8)  shuai_PLUS = cv2.dilate(shuai,kernel,iterations = 1) cv_show('win',shuai_PLUS )

shuai_PLUS = cv2.dilate(shuai,kernel,iterations = 1)

openCV入门学习基础教程第二篇

同理

pie = cv2.imread('./data/pie.png')   kernel = np.ones((30,30),np.uint8)  dilate_1 = cv2.dilate(pie,kernel,iterations = 1) dilate_2 = cv2.dilate(pie,kernel,iterations = 2) dilate_3 = cv2.dilate(pie,kernel,iterations = 3) res = np.hstack((dilate_1,dilate_2,dilate_3)) cv_show('win',res)

openCV入门学习基础教程第二篇

6. 开运算与闭运算

开:先腐蚀,再膨胀

img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE)   kernel = np.ones((5,5),np.uint8)  opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)   cv_show('win',opening)

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

openCV入门学习基础教程第二篇

闭:先膨胀,再腐蚀

img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE)   kernel = np.ones((5,5),np.uint8)  closing = cv2.morphologyEx(img, cv2.MORPH_Close, kernel)   cv_show('win',closing)

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

openCV入门学习基础教程第二篇

7. 梯度运算

梯度=膨胀-腐蚀

pie = cv2.imread('./data/pie.png',cv2.IMREAD_GRAYSCALE) kernel = np.ones((7,7),np.uint8)  dilate = cv2.dilate(pie,kernel,iterations = 5) erosion = cv2.erode(pie,kernel,iterations = 5)   res = np.hstack((dilate,erosion))   cv_show('win',res)

以下是经过5次腐蚀和5次膨胀后的图像:

openCV入门学习基础教程第二篇

获得边界信息:梯度运算

gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)   cv_show('win',gradient)

gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)

openCV入门学习基础教程第二篇

8.礼帽与黑帽

礼帽 = 原始输入-开运算结果黑帽 = 闭运算-原始输入
# 礼帽 img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE) tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) cv_show('win',tophat)

(只剩下“毛”了)

openCV入门学习基础教程第二篇

# 黑帽 img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE) blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel) cv_show('win',blackhat)

(只剩下小轮廓了)

openCV入门学习基础教程第二篇

9. 图像梯度-Sobel算子

我们依旧引入图像pie

img = cv2.imread('./data/pie.png',cv2.IMREAD_GRAYSCALE) cv_show('win',img)

openCV入门学习基础教程第二篇

可见在边缘部分(黑白交界),梯度比较大。

openCV入门学习基础教程第二篇

定义Gx,Gy处理水平和竖直方向上的梯度。

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)   cv_show('sobelx',sobelx)

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

ddepth:图像的深度(一般-1)dx和dy分别表示水平和竖直方向ksize是Sobel算子的大小cv2.CV_64F处理差为负数情况。

openCV入门学习基础教程第二篇

为什么只有一半呢?

我们定义的矩阵计算时是右-左,白-黑>0正常显示,黑-白<0进行了截断为0,

白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值。

我们需要对其进行一下转换:

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) sobelx = cv2.converTScaleAbs(sobelx) cv_show('sobelx',sobelx)

sobelx = cv2.convertScaleAbs(sobelx)

openCV入门学习基础教程第二篇

上面是水平方向,下面是竖直方向:

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobely = cv2.convertScaleAbs(sobely)   cv_show('sobelx',sobely)

openCV入门学习基础教程第二篇

分别计算x和y,再求和:

sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) cv_show('sobelxy',sobelxy)

openCV入门学习基础教程第二篇

但不建议都是设置成1,效果可能不好。

sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) sobelxy = cv2.convertScaleAbs(sobelxy)  cv_show('sobelxy',sobelxy)

openCV入门学习基础教程第二篇

建议:分别算Gx,Gy自己进行求和操作:

img = cv2.imread('./data/gd01.jpg',cv2.IMREAD_GRAYSCALE) sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) sobelx = cv2.convertScaleAbs(sobelx) sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobely = cv2.convertScaleAbs(sobely) sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)   sobelxy2=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) sobelxy2 = cv2.convertScaleAbs(sobelxy2) res = np.hstack((sobelxy,sobelxy2)) cv_show('res',res)

openCV入门学习基础教程第二篇

10. 图像梯度-Scharr算子和laplacian算子

Scharr算子

openCV入门学习基础教程第二篇

laplacian算子

openCV入门学习基础教程第二篇

核中数值有差异,Scharr敏感些。

laplacian算子涉及二阶导,更加敏感同时对噪声也更加敏感,一般和其他方法配合使用

原理同上,我们来对比一下这三种算子效果:

img = cv2.imread('./data/gd01.jpg',cv2.IMREAD_GRAYSCALE) sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobelx = cv2.convertScaleAbs(sobelx)    sobely = cv2.convertScaleAbs(sobely)   sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)     scharrx = cv2.Scharr(img,cv2.CV_64F,1,0) scharry = cv2.Scharr(img,cv2.CV_64F,0,1) scharrx = cv2.convertScaleAbs(scharrx)    scharry = cv2.convertScaleAbs(scharry)   scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)    laplacian = cv2.Laplacian(img,cv2.CV_64F) laplacian = cv2.convertScaleAbs(laplacian)      res = np.hstack((sobelxy,scharrxy,laplacian)) cv_show('res',res)

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)

laplacian = cv2.Laplacian(img,cv2.CV_64F)

openCV入门学习基础教程第二篇

10. 知识点总结*

图像阈值:

ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY) ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV) ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC) ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO) ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV) # ps: ret为127 thresh1-5为图片矩阵 titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV'] images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]   for i in range(6): plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]), plt.yticks([]) plt.show()

图像平滑

# 加入噪声 img = cv2.imread('./data/gd07.jpg')   #获取图片行、列、通道数 rows,cols,channels = img.shape   for i in range(0,5000): #根据在0和行-1之间获取随机整数 x = np.random.randint(0,rows-1) #根据在0和列-1之间获取随机整数 y = np.random.randint(0,cols-1)   #将通道颜色改为255, (255,255,255) img[x,y][0] = 255 img[x,y][1] = 255 img[x,y][2] = 255   cv_show('win',img)
blur = cv2.blur(img, (3, 3)) box = cv2.boxFilter(img,-1,(3,3), normalize=True)   aussian = cv2.GaussianBlur(img, (5, 5), 1)   median = cv2.medianBlur(img, 5)    res = np.hstack((blur,aussian,median)) cv_show('median vs average', res)

形态学-腐蚀

img = cv2.imread('./data/s.jpg', cv2.IMREAD_GRAYSCALE) kernel = np.ones((3,3),np.uint8)  erosion = cv2.erode(img,kernel,iterations = 1) cv_show('win',erosion)

形态学-膨胀

img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE) kernel = np.ones((3,3),np.uint8)  shuai = cv2.erode(img,kernel,iterations = 1) kernel = np.ones((3,3),np.uint8)  shuai_PLUS = cv2.dilate(shuai,kernel,iterations = 1) cv_show('win',shuai_PLUS )

开运算与闭运算

img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE)   kernel = np.ones((5,5),np.uint8)  opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)   cv_show('win',opening)

梯度运算

gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)   cv_show('win',gradient)

礼帽与黑帽

# 礼帽 img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE) tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) cv_show('win',tophat)     # 黑帽 img = cv2.imread('./data/s.jpg',cv2.IMREAD_GRAYSCALE) blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel) cv_show('win',blackhat)

Sobel、Scharr、Laplacian算子

img = cv2.imread('./data/gd01.jpg',cv2.IMREAD_GRAYSCALE) sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobelx = cv2.convertScaleAbs(sobelx)    sobely = cv2.convertScaleAbs(sobely)   sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)     scharrx = cv2.Scharr(img,cv2.CV_64F,1,0) scharry = cv2.Scharr(img,cv2.CV_64F,0,1) scharrx = cv2.convertScaleAbs(scharrx)    scharry = cv2.convertScaleAbs(scharry)   scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0)    laplacian = cv2.Laplacian(img,cv2.CV_64F) laplacian = cv2.convertScaleAbs(laplacian)      res = np.hstack((sobelxy,scharrxy,laplacian)) cv_show('res',res)

总结

到此这篇关于opencv入门学习基础教程第二篇的文章就介绍到这了,更多相关Opencv第二篇内容请搜索云初冀北以前的文章或继续浏览下面的相关文章希望大家以后多多支持云初冀北!

免责声明
本站提供的资源,都来自网络,版权争议与本站无关,所有内容及软件的文章仅限用于学习和研究目的。不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,我们不保证内容的长久可用性,通过使用本站内容随之而来的风险与本站无关,您必须在下载后的24个小时之内,从您的电脑/手机中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。侵删请致信E-mail:Goliszhou@gmail.com
$

发表评论

表情:
评论列表 (暂无评论,68人围观)

还没有评论,来说两句吧...