opencv-python基础知识学习笔记

原博地址:https://www.cnblogs.com/silence-cho/p/10926248.html

目录:

opencv-python基础知识学习笔记


1.图像的读入和存储

2.图像像素获取和编辑

3.添加边界

4.像素算术运算

5.图像位运算

6.图像颜色空间转换

7.性能评价

8.绑定TrackBar到图像

9.图像阈值分割

10.图像缩放

11.仿射变换

12.透视变换

13:直方图绘制

14.对比度增强

15.二维离散卷积

16.图像平滑

17.腐蚀处理

18.膨胀处理

19.开运算/闭运算/形态学梯度/顶帽/底帽

20.直线、圆、矩形、文字的绘制

21.边缘检测

22.模版匹配

23.凸包

24.计算轮廓特征

25.霍夫变换

26.图像梯度提取

27.角点检测

28.图像通道分离与合并

27.角点检测

28.图像通道分离与合并

29.图像算术运算

30.像素的均值和方差

31.漫水填充

32.K近邻

33.拟合

34.图像连通域

35.骨架提取

36.SVM

37.频域处理

38.图像数据类型转换

39.生成随机颜色

40.图像掩码处理

1.图像的读入和存储:

(1)函数格式:

#【1】读取图片,返回图片对象
imread(img_path,flag) img_path: 图片的路径,即使路径错误也不会报错,但打印返回的图片对象为Noneflag:cv2.IMREAD_COLOR,读取彩色图片,图片透明性会被忽略,为默认参数,也可以传入1cv2.IMREAD_GRAYSCALE,按灰度模式读取图像,也可以传入0cv2.IMREAD_UNCHANGED,读取图像,包括其alpha通道,也可以传入-1#【2】
# (1)显示图片,窗口自适应图片大小
imshow(window_name,img):window_name: 指定窗口的名字img:显示的图片对象可以指定多个窗口名称,显示多个图片# (2)键盘绑定事件,阻塞监听键盘按键,返回一个数字(不同按键对应的数字不同)
waitKey(millseconds)  millseconds: 传入时间毫秒数,在该时间内等待键盘事件;传入0时,会一直等待键盘事件# (3)关闭窗口
destroyAllWindows(window_name) window_name: 需要关闭的窗口名字,不传入时关闭所有窗口#【3】保存图像
imwrite(img_path_name,img)img_path_name:保存的文件名img:文件对象

(2)应用举例:

import cv2
img = cv2.imread("2.jpg")
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img_threshold = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
cv2.imshow("img",img)
cv2.imshow("thre",img_threshold)key = cv2.waitKey(0)
if key==27:                    #按esc键时,关闭所有窗口print(key)cv2.destroyAllWindows()
cv2.imwrite("2-1.jpg", img_threshold)

2.图像像素获取和编辑:

img = cv2.imread("2.jpg")# 【1】像素值获取
(1)
pixel = img[100,100]           #[57 63 68],获取(100,100)处的像素值
img[100,100]=[57,63,99]        #设置像素值
b = img[100,100,0]             #57, 获取(100,100)处,blue通道像素值
g = img[100,100,1]             #63
r = img[100,100,2]             #68
r = img[100,100,2]=99          #设置red通道值(2)
piexl = img.item(100,100,2)
img.itemset((100,100,2),99)# 【2】图像性质获取
img.shape   #返回(280, 450, 3), 宽280(rows),长450(cols),3通道(channels)
img.size    #返回378000,所有像素数量,=280*450*3
img.dtype   #dtype('uint8')# 【3】ROI截取:
roi = img[100:200,300:400]  #截取100行到200行,列为300到400列的整块区域
img[50:150,200:300] = roi   #将截取的roi移动到该区域 (50到100行,200到300列)
b = img[:,:,0]              #截取整个蓝色通道
b,g,r = cv2.split(img)      #截取三个通道,比较耗时
img = cv2.merge((b,g,r))

3.添加边界:

(1)函数格式:

cv2.copyMakeBorder()参数:img:图像对象top,bottom,left,right: 上下左右边界宽度,单位为像素值borderType:cv2.BORDER_CONSTANT, 带颜色的边界,需要传入另外一个颜色值cv2.BORDER_REFLECT, 边缘元素的镜像反射做为边界cv2.BORDER_REFLECT_101/cv2.BORDER_DEFAULTcv2.BORDER_REPLICATE, 边缘元素的复制做为边界CV2.BORDER_WRAPvalue: borderType为cv2.BORDER_CONSTANT时,传入的边界颜色值,如[0,255,0]

(2)应用举例:

import cv2 as cv
import matplotlib.pyplot as pltimg2 = cv.imread("2.jpg")
img = cv.cvtColor(img2,cv.COLOR_BGR2RGB)  #matplotlib的图像为RGB格式constant = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_CONSTANT,value=[0,255,0]) #绿色
reflect = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_REFLECT)
reflect01 = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_REFLECT_101)
replicate = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_REPLICATE)
wrap = cv.copyMakeBorder(img,20,20,20,20,cv.BORDER_WRAP)
titles = ["constant","reflect","reflect01","replicate","wrap"]
images = [constant,reflect,reflect01,replicate,wrap]for i in range(5):plt.subplot(2,3,i+1),plt.imshow(images[i]),plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

4.像素算术运算:

(1)函数格式:

# 【1】注意:图像相加时应该用cv2.add(img1,img2)代替img1+img2
cv2.add()参数:img1:图片对象1img2:图片对象2mask:None (掩膜,一般用灰度图做掩膜,img1和img2相加后,和掩膜与运算,从而达到掩盖部分区域的目的)dtype:-1# 【2】两张图片相加,分别给予不同权重,实现图片融合和透明背景等效果
cv2.addWeighted() 参数:img1:图片对象1alpha:img1的权重img2:图片对象2beta:img1的权重gamma:常量值,图像相加后再加上常量值dtype:返回图像的数据类型,默认为-1,和img1一样(img1*alpha+img2*beta+gamma)

(2)应用举例:

# 【1】
import cv2 as cv
import numpy as npimg1 = cv.imread("2.jpg",0)
roi_img  = np.zeros(img1.shape[0:2],dtype=np.uint8)
roi_img[100:280,400:550] = 255img_add = cv.add(img1,img1)
img_add_mask = cv.add(img1,img1,mask=roi_img)
cv.imshow("img_add",img_add)
cv.imshow("img_add_mask",img_add_mask)cv.waitKey(0)
cv.destroyAllWindows()# 【2】
import cv2 as cvimg1 = cv.imread("1.jpg")
img = img1[0:426,43:683]
img2 = cv.imread("2.jpg")
blend = cv.addWeighted(img,0.5,img2,0.9,0)  #两张图的大小和通道也应该相同
cv.imshow("blend",blend)cv.waitKey()
cv.destroyAllWindows()

5.图像位运算:

(1)函数格式:

# 【1】与运算
cv2.btwise_and(): 参数:img1:图片对象1img2:图片对象2mask:掩膜# 【2】或运算
cv2.bitwise_or():参数:img1:图片对象1img2:图片对象2mask:掩膜# 【3】非运算
cv2.bitwise_not():img1:图片对象1mask:掩膜# 【4】异或运算,相同为1,不同为0(1^1=0,1^0=1)
cv2.bitwise_xor():img1:图片对象1img2:图片对象2mask:掩膜

(2)应用举例:

import cv2 as cv
import matplotlib.pyplot as pltimg1 = cv.imread("1.png")
rows,cols = img1.shape[0:2]
img2 = cv.imread("2.jpg")
roi = img2[0:rows,0:cols]
img1_gray = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)ret,img1_thres = cv.threshold(img1_gray,200,255,cv.THRESH_BINARY_INV)
img1_fg =cv.add(img1,img1,mask=img1_thres)        #logo图案的前景img1_thres_inv = cv.bitwise_not(img1_thres)
roi_bg = cv.add(roi,roi,mask=img1_thres_inv)      #roi图案的背景img_add = cv.add(img1_fg,roi_bg)                  #背景和前景相加
img2[0:rows,0:cols] = img_addcv.imshow("gray",img1_gray)
cv.imshow("thres",img1_thres)
cv.imshow("fg",img1_fg)
cv.imshow("tinv",img1_thres_inv)
cv.imshow("roi_bg",roi_bg)
cv.imshow("img_add",img_add)
cv.imshow("img2",img2)
cv.waitKey(0)
cv.destroyAllWindows()

6.图像颜色空间转换:

# 【1】
cv2.cvtColor()参数:img: 图像对象code:cv2.COLOR_RGB2GRAY: RGB转换到灰度模式cv2.COLOR_RGB2HSV: RGB转换到HSV模式(hue,saturation,Value)# 【2】
cv2.inRange()参数:img: 图像对象/arraylowerb: 低边界array,  如lower_blue = np.array([110,50,50])upperb:高边界array, 如 upper_blue = np.array([130,255,255])
mask = cv2.inRange(hsv, lower_green, upper_green)# 【3】将arr从fromspace颜色空间转换到tospace颜色空间
import skimage
skimage.color.convert_colorspace(arr, fromspace, tospace)

7.性能评价:

import cv2img1 = cv2.imread("1.png")
e1 = cv2.getTickCount()
for i in xrange(5,49,2):img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print(t)

8.绑定TrackBar到图像:

(1)函数格式:

# 【1】为窗口添加trackbar
cv2.createTrackbar() 参数:trackbarname: trackbar的名字winname: 窗口的名字value: trackbar创建时的值count:trackbar能设置的最大值,最小值总为0onChange:trackbar值发生变化时的回调函数,trackbar的值作为参数传给onchange# 【2】获取某个窗口中trackbar的值
cv2.getTrackbarPos() 参数:trackbarname: trackbar的名字winname: 窗口的名字

(2)应用举例:

import cv2 as cv
import numpy as npdef nothing(args):passimg = cv.imread("1.png")
img_hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
cv.namedWindow('tracks')
cv.createTrackbar("LH","tracks",0,255,nothing)
cv.createTrackbar("LS","tracks",0,255,nothing)
cv.createTrackbar("LV","tracks",0,255,nothing)cv.createTrackbar("UH","tracks",255,255,nothing)
cv.createTrackbar("US","tracks",255,255,nothing)
cv.createTrackbar("UV","tracks",255,255,nothing)while(1):l_h = cv.getTrackbarPos("LH","tracks")l_s = cv.getTrackbarPos("LS","tracks")l_v = cv.getTrackbarPos("LV","tracks")u_h = cv.getTrackbarPos("UH","tracks")u_s = cv.getTrackbarPos("US","tracks")u_v = cv.getTrackbarPos("UV","tracks")lower_b = np.array([l_h,l_s,l_v])upper_b = np.array([u_h,u_s,u_v])mask = cv.inRange(img_hsv,lower_b,upper_b)res = cv.add(img,img,mask=mask)cv.imshow("img",img)cv.imshow("mask",mask)cv.imshow("res",res)k = cv.waitKey(1)if k==27:breakcv.destroyAllWindows()

9.图像阈值分割:

(1)函数格式:

# 【1】
cv2.threshold():
参数:img:图像对象,必须是灰度图thresh:阈值maxval:最大值type:cv2.THRESH_BINARY:     小于阈值的像素置为0,大于阈值的置为maxvalcv2.THRESH_BINARY_INV: 小于阈值的像素置为maxval,大于阈值的置为0cv2.THRESH_TRUNC:      小于阈值的像素不变,大于阈值的置为threshcv2.THRESH_TOZERO       小于阈值的像素置0,大于阈值的不变cv2.THRESH_TOZERO_INV   小于阈值的不变,大于阈值的像素置0
返回值:ret:阈值img:阈值化处理后的图像# 【2】
cv2.adaptiveThreshold() 自适应阈值处理,图像不同部位采用不同的阈值进行处理
参数:img: 图像对象,8-bit单通道图maxValue:最大值adaptiveMethod: 自适应方法cv2.ADAPTIVE_THRESH_MEAN_C     :阈值为周围像素的平均值cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 阈值为周围像素的高斯均值(按权重)threshType:cv2.THRESH_BINARY:     小于阈值的像素置为0,大于阈值的置为maxValuelcv2.THRESH_BINARY_INV:  小于阈值的像素置为maxValue,大于阈值的置为0blocksize: 计算阈值时,自适应的窗口大小,必须为奇数 (如3:表示附近3个像素范围内的像素点,进行计算阈值)C: 常数值,通过自适应方法计算的值,减去该常数值

(2)应用举例:

import cv2 as cv
import matplotlib.pyplot as pltimg = cv.imread("1.png",0)ret,thre1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
adaptive_thre1 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,7,2)
adaptive_thre2 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,7,2)titles = ["img","thre1","adaptive_thre1","adaptive_thre2"]
imgs = [img,thre1,adaptive_thre1,adaptive_thre2 ]for i in range(4):plt.subplot(2,2,i+1), plt.imshow(imgs[i],"gray")plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

10.图像缩放:

(1)函数格式:

#  放大和缩小图像
cv2.resize()参数:src: 输入图像对象dsize:输出矩阵/图像的大小,为0时计算方式如下:dsize = Size(round(fx*src.cols),round(fy*src.rows))fx: 水平轴的缩放因子,为0时计算方式:  (double)dsize.width/src.colsfy: 垂直轴的缩放因子,为0时计算方式:  (double)dsize.heigh/src.rowsinterpolation:插值算法cv2.INTER_NEAREST : 最近邻插值法cv2.INTER_LINEAR   默认值,双线性插值法cv2.INTER_AREA        基于局部像素的重采样(resampling using pixel area relation)。对于图像抽取(image decimation)来说,这可能是一个更好的方法。但如果是放大图像时,它和最近邻法的效果类似。cv2.INTER_CUBIC        基于4x4像素邻域的3次插值法cv2.INTER_LANCZOS4     基于8x8像素邻域的Lanczos插值其中cv2.INTER_AREA 适合于图像缩小, cv2.INTER_CUBIC (slow) & cv2.INTER_LINEAR 适合于图像放大

(2)应用举例 :

import cv2
import numpy as npimg = cv2.imread('1.jpg')
res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)height, width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

11.仿射变换:

(1)函数格式 :

# 【1】仿射变换(从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切)
cv2.warpAffine()   参数:img: 图像对象M:2*3 transformation matrix (转变矩阵)dsize:输出矩阵的大小,注意格式为(cols,rows)  即width对应cols,height对应rowsflags:可选,插值算法标识符,有默认值INTER_LINEAR,如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转dst(x,y)=src(M11*x+M12*y+M13,M21*x+M22*y+M23)borderMode:可选, 边界像素模式,有默认值BORDER_CONSTANT borderValue:可选,边界取值,有默认值Scalar()即0# 【2】返回2*3的转变矩阵(浮点型)
cv2.getRotationMatrix2D()  参数:center:旋转的中心点坐标angle:旋转角度,单位为度数,证书表示逆时针旋转scale:同方向的放大倍数# 【3】仿射变换矩阵的计算,返回2*3的转变矩阵
cv2.getAffineTransform()  参数:src:原图像中的三组坐标,如np.float32([[50,50],[200,50],[50,200]])dst: 转换后的对应三组坐标,如np.float32([[10,100],[200,50],[100,250]])

(2)应用举例 :

# 【1】
import cv2
import numpy as npimg = cv2.imread('1.jpg',0)
rows,cols = img.shapeM = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()# 【2】
import cv2
import numpy as np
import matplotlib.pylab as pltimg = cv2.imread('2.jpg', 0)
rows, cols= img.shapepts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
dst = cv2.warpAffine(img,M,(cols,rows))plt.subplot(121),plt.imshow(img)
plt.subplot(122),plt.imshow(dst)
plt.show()

12.透视变化:

(1)函数格式 :

# 【1】
cv2.getPerspectiveTransform()   返回3*3的转变矩阵参数:    src:原图像中的四组坐标,如 np.float32([[56,65],[368,52],[28,387],[389,390]])dst: 转换后的对应四组坐标,如np.float32([[0,0],[300,0],[0,300],[300,300]])# 【2】
cv2.wrapPerspective()参数:    src: 图像对象M:3*3 transformation matrix (转变矩阵)dsize:输出矩阵的大小,注意格式为(cols,rows)  即width对应cols,height对应rowsflags:可选,插值算法标识符,有默认值INTER_LINEAR,如果插值算法为WARP_INVERSE_MAP, warpAffine函数使用如下矩阵进行图像转dst(x,y)=src(M11*x+M12*y+M13,M21*x+M22*y+M23)borderMode:可选, 边界像素模式,有默认值BORDER_CONSTANT borderValue:可选,边界取值,有默认值Scalar()即0

(2)应用举例:

img = cv2.imread('1.png')
rows,cols,ch = img.shapepts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

13:直方图绘制:

灰度直方图绘制:

    1)可以利用opencv的calcHist()统计像素值出现次数,通过matploblib的plot()绘制;

    2)可以直接利用matploblib的hist()方法。

(1)函数格式 :

# 【1】
cv2.calcHist()参数:    img:输入图像,为列表,如[img]channels: 计算的通道,为列表,如[0]表示单通道,[0,1]统计两个通道mask: 掩模,和输入图像大小一样的矩阵,为1的地方会进行统计(与图像逻辑与后再统计);无掩模时为NonehistSize: 每一个channel对应的bins个数,为列表,如[256]表示256个像素值ranges: bins的边界,为列表,如[0,256]表示像素值范围在0-256之间accumulate: Accumulation flag 

(2)应用举例 :

# 【1】cv.calcHist
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg",0)
hist = cv.calcHist([img],[0],None,[256],[0,256])plt.subplot(1,3,1),plt.plot(hist,color="r"),plt.axis([0,256,0,np.max(hist)])
plt.xlabel("gray level")
plt.ylabel("number of pixels")plt.subplot(1,3,2),plt.hist(img.ravel(),bins=256,range=[0,256]),plt.xlim([0,256])
plt.xlabel("gray level")
plt.ylabel("number of pixels")plt.subplot(1,3,3)
plt.plot(hist,color="r"),plt.axis([0,256,0,np.max(hist)])
plt.hist(img.ravel(),bins=256,range=[0,256]),plt.xlim([0,256])
plt.xlabel("gray level")
plt.ylabel("number of pixels")
plt.show()# 【2】np.histogram
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg",0)
histogram,bins = np.histogram(img,bins=256,range=[0,256])
print(histogram)
plt.plot(histogram,color="g")
plt.axis([0,256,0,np.max(histogram)])
plt.xlabel("gray level")
plt.ylabel("number of pixels")
plt.show()# 【3】plt.hist
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg",0)
rows,cols = img.shape
hist = img.reshape(rows*cols)
histogram,bins,patch = plt.hist(hist,256,facecolor="green",histtype="bar") #histogram即为统计出的灰度值分布
plt.xlabel("gray level")
plt.ylabel("number of pixels")
plt.axis([0,255,0,np.max(histogram)])
plt.show()

14:对比度增强:

(1)线性变换 :

1)函数格式:

cv2.convertScaleAbs(src,alpha,beta)src: 图像对象矩阵dst:输出图像矩阵alpha:y=ax+b中的a值beta:y=ax+b中的b值(对于计算后大于255的像素值会截断为255)

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg")
print(img)
img_bright = cv.convertScaleAbs(img,alpha=1.5,beta=0)
print(img_bright)cv.imshow("img",img)
cv.imshow("img_bright",img_bright)
cv.waitKey(0)
cv.destroyAllWindows()

(2)直方图规范化 :

直方图正规化的系数固定,一般将原图片的像素值范围映射到[0,255]范围内。

1)函数格式:

cv2.normalize(src,dst,alpha,beta,normType,dtype,mask)参数:src: 图像对象矩阵dst:输出图像矩阵(和src的shape一样)alpha:正规化的值,如果是范围值,为范围的下限 (alpha – norm value to normalize to or the lower range boundary in case of the range normalization.)beta:如果是范围值,为范围的上限;正规化中不用到 ( upper range boundary in case of the range normalization; it is not used for the norm normalization.)norm_type:normalize的类型cv2.NORM_L1:将像素矩阵的1-范数做为最大值(矩阵中值的绝对值的和)cv2.NORM_L2:将像素矩阵的2-范数做为最大值(矩阵中值的平方和的开方)cv2.NORM_MINMAX:将像素矩阵的∞-范数做为最大值 (矩阵中值的绝对值的最大值)dtype: 输出图像矩阵的数据类型,默认为-1,即和src一样mask:掩模矩阵,只对感兴趣的地方归一化

2)应用实例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg")
img_norm=cv.normalize(img,dst=None,alpha=350,beta=10,norm_type=cv.NORM_MINMAX)
cv.imshow("img",img)
cv.imshow("img_norm",img_norm)
cv.waitKey(0)
cv.destroyAllWindows()

(3)伽玛变换:

将输入图像的像素值除以255,归一化到[0,1]区间,然后计算其γ次方值,用公式表示如下,其中I(r,c)为归一化后的像素值,当γ=1时原像素值不影响,当0<γ<1时,增大像素值,提高图片对比度;反之γ>1时能降低图片对比度。

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg")
img_norm = img/255.0  #注意255.0得采用浮点数
img_gamma = np.power(img_norm,0.4)*255.0
img_gamma = img_gamma.astype(np.uint8)cv.imshow("img",img)
cv.imshow("img_gamma",img_gamma)
cv.waitKey(0)
cv.destroyAllWindows()

(4)全局直方图均衡化:

直方图均衡化的目的是将原图片每个像素值的像素点个数进行重新分配到[0,255]的256个像素值上,使得每个像素值对应的像素点个数近似相等,即重新分配后,0-255的每个像素值对应的像素点个数近似为(rows*cols/256)。

1)函数格式:

cv2.equalizeHist(src,dst)src: 图像对象矩阵,必须为单通道的uint8类型的矩阵数据dst:输出图像矩阵(和src的shape一样)

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import mathimg = cv.imread("2.jpg",0)
img_equalize = cv.equalizeHist(img)
cv.imshow("img",img)
cv.imshow("img_equalize",img_equalize)
cv.waitKey(0)
cv.destroyAllWindows()

(5)限制对比度自适应直方图均衡化:

相比全局直方图均衡化,自适应直方图均衡化将图像划分为不重叠的小块,在每一小块进行直方图均衡化,但若小块内有噪声,影响很大,需要通过限制对比度来进行抑制,即限制对比度自适应直方图均衡化。如果限制对比度的阈值设置会40,在局部直方图分布中某个像素值出现次数为45,那么多出的5次像素点会被去掉,平均成其他像素值。

1)函数格式:

# 【1】
clahe=cv2.createCLAHE(clipLimit,tileGridSize)clipLimit:限制对比度的阈值,默认为40,直方图中像素值出现次数大于该阈值,多余的次数会被重新分配tileGridSize:图像会被划分的size, 如tileGridSize=(8,8),默认为(8,8)# 【2】
calhe.apply(img) #对img进行限制对比度自适应直方图均衡化

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import mathimg = cv.imread("2.jpg",0)
clahe = cv.createCLAHE(3,(8,8))
dst = clahe.apply(img)
cv.imshow("img",img)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

15.二维离散卷积:

三种卷积类型:

1)Full卷积:从filter和图像刚相交开始做卷积;

2)Same卷积:当filter的锚点(K)与图像的边角重合时,开始做卷积运算,filter的运动范围比full模式小了一圈,Same卷积为Full卷积的子集,即Full卷积的处理结果包括Same mode;

3)Valid卷积:当filter全部在图像里面的时候,进行卷积运算,可见filter的移动范围较Same卷积更小了,同样Valid 卷积为Same卷积的子集。valid mode的卷积计算,填充边界中的像素值不会参与计算,即无效的填充边界不影响卷积,所以称为Valid mode。

from scipy import signal# 【1】
signal.convolve2d(src,kernel,mode,boundary,fillvalue)参数: src: 输入的图像矩阵,只支持单通的(即二维矩阵)kernel:卷积核mode:卷积类型:full, same, validboundary:边界填充方式:fill,wrap, symmfillvalue: 当boundary为fill时,边界填充的值,默认为0# 【2】 翻转卷积核
dst = cv2.flip(src,flipCode)src: 输入矩阵flipCode:0表示沿着x轴翻转,1表示沿着y轴翻转,-1表示分别沿着x轴,y轴翻转dst:输出矩阵(和src的shape一样)# 【3】filter2D()进行same卷积cv2.filter2D(src,dst,ddepth,kernel,anchor=(-1,-1),delta=0,borderType=cv2.BORDER_DEFAULT)src: 输入图像对象矩阵dst:输出图像矩阵ddepth:输出矩阵的数值类型kernel:卷积核anchor:卷积核锚点,默认(-1,-1)表示卷积核的中心位置delat:卷积完后相加的常数borderType:填充边界类型

16.图像平滑:

(1)高斯平滑:

1)函数格式:

# 【1】进行高斯平滑
dst = cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)src: 输入图像矩阵,可为单通道或多通道,多通道时分别对每个通道进行卷积dst:输出图像矩阵,大小和数据类型都与src相同ksize:高斯卷积核的大小,宽,高都为奇数,且可以不相同sigmaX: 一维水平方向高斯卷积核的标准差sigmaY: 一维垂直方向高斯卷积核的标准差,默认值为0,表示与sigmaX相同borderType:填充边界类型# 【2】生成一维高斯卷积核
cv2.getGaussianKernel(ksize,sigma,ktype)ksize:奇数,一维核长度sigma:标准差ktype:数据格式,应该为CV_32F 或者 CV_64F

2)应用举例:

# 【1】
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg")
img_gauss = cv.GaussianBlur(img,(3,3),1)
cv.imshow("img",img)
cv.imshow("img_gauss",img_gauss)
cv.waitKey(0)
cv.destroyAllWindows()# 【2】
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
from scipy import signaldef gaussianBlur(img,h,w,sigma,boundary="fill",fillvalue=0):kernel_x = cv.getGaussianKernel(w,sigma,cv.CV_64F)   #默认得到的为垂直矩阵kernel_x = np.transpose(kernel_x)  #转置操作,得到水平矩阵#convolve2d只是对单通道进行卷积,若要实现cv.GaussianBlur()多通道高斯卷积,需要拆分三个通道进行,再合并#水平方向卷积gaussian_x = signal.convolve2d(img,kernel_x,mode="same",boundary=boundary,fillvalue=fillvalue)#垂直方向卷积kernel_y = cv.getGaussianKernel(h,sigma,cv.CV_64F)gaussian_xy = signal.convolve2d(gaussian_x,kernel_y,mode="same",boundary=boundary,fillvalue=fillvalue)#cv.CV_64F数据转换为uint8gaussian_xy = np.round(gaussian_xy)gaussian_xy = gaussian_xy.astype(np.uint8)return gaussian_xyif __name__=="__main__":img = cv.imread("2.jpg",0)img_gauss = gaussianBlur(img,3,3,1)cv.imshow("img",img)cv.imshow("img_gauss",img_gauss)cv.waitKey(0)cv.destroyAllWindows()

(2)均值滤波:

1)函数格式:

# 【1】
cv2.boxFilter(src,ddepth,ksize,dst,anchor,normalize,borderType)src: 输入图像对象矩阵,ddepth:数据格式,位深度ksize:高斯卷积核的大小,格式为(宽,高)dst:输出图像矩阵,大小和数据类型都与src相同anchor:卷积核锚点,默认(-1,-1)表示卷积核的中心位置normalize:是否归一化 (若卷积核3*5,归一化卷积核需要除以15)borderType:填充边界类型# 【2】
cv2.blur(src,ksize,dst,anchor,borderType)src: 输入图像对象矩阵,可以为单通道或多通道ksize:高斯卷积核的大小,格式为(宽,高)dst:输出图像矩阵,大小和数据类型都与src相同anchor:卷积核锚点,默认(-1,-1)表示卷积核的中心位置borderType:填充边界类型

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as npimg = cv.imread("2.jpg")
img_blur = cv.blur(img,(3,5))
# img_blur = cv.boxFilter(img,-1,(3,5))
cv.imshow("img",img)
cv.imshow("img_blur",img_blur)
cv.waitKey(0)
cv.destroyAllWindows()

(3)中值滤波:

1)函数格式:

cv2.medianBlur(src,ksize,dst)src: 输入图像对象矩阵,可以为单通道或多通道ksize:核的大小,格式为 3      #注意不是(3,3)dst:输出图像矩阵,大小和数据类型都与src相同

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import randomimg = cv.imread("2.jpg")
rows,cols = img.shape[:2]#加入椒盐噪声
for i in range(100):r = random.randint(0,rows-1)c = random.randint(0,cols-1)img[r,c]=255img_medianblur = cv.medianBlur(img,5)cv.imshow("img",img)
cv.imshow("img_medianblur",img_medianblur)
cv.waitKey(0)
cv.destroyAllWindows()

(4)双边滤波:

双边滤波在平滑的同时还能保持图像中物体的轮廓信息。双边滤波在高斯平滑的基础上引入了灰度值相似性权重因子,所以在构建其卷积核核时,要同时考虑空间距离权重和灰度值相似性权重。在进行卷积时,每个位置的邻域内,根据和锚点的距离d构建距离权重模板,根据和锚点灰度值差异r构建灰度值权重模板,结合两个模板生成该位置的卷积核。

1)函数格式:

dst = cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType)src: 输入图像对象矩阵,可以为单通道或多通道d:用来计算卷积核的领域直径,如果d<=0,从sigmaSpace计算dsigmaColor:颜色空间滤波器标准偏差值,决定多少差值之内的像素会被计算(构建灰度值模板)sigmaSpace:坐标空间中滤波器标准偏差值。如果d>0,设置不起作用,否则根据它来计算d值(构建距离权重模板)

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import random
import mathimg = cv.imread("2.jpg")
img_bilateral = cv.bilateralFilter(img,0,0.2,40)cv.imshow("img",img)
cv.imshow("img_bilateral",img_bilateral)
cv.waitKey(0)
cv.destroyAllWindows()

(5)联合双边滤波:

双边滤波是根据原图中不同位置灰度相似性来构建相似性权重模板,而联合滤波是先对原图进行高斯平滑,然后根据平滑后的图像灰度值差异建立相似性模板,再与距离权重模板相乘得到最终的卷积核,最后再对原图进行处理。所以相比于双边滤波,联合双边滤波只是建立灰度值相似性模板的方法不一样。

opencv 2中不支持联合双边滤波,opencv 3中除了主模块还引入了contrib,其中的ximgproc模块包括了联合双边滤波的算法。因此如果需要使用opencv的联合双边滤波,需要安装opencv-contrib-python包。

1)函数格式:

dst = cv2.xmingproc.jointBilateralFilter(joint,src,d,sigmaColor,sigmaSpace,borderType)joint: 进行联合滤波的导向图像,可以为单通道或多通道,保持边缘的滤波算法时常采用srcsrc: 输入图像对象矩阵,可以为单通道或多通道d:用来计算卷积核的领域直径,如果d<0,从sigmaSpace计算dsigmaColor:颜色空间滤波器标准偏差值,决定多少差值之内的像素会被计算(构建灰度值模板)sigmaSpace:坐标空间中滤波器标准偏差值。如果d>0,设置不起作用,否则根据它来计算d值(构建距离权重模板)

2)应用举例:

import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import random
import mathsrc = cv.imread("2.jpg")
joint  = cv.GaussianBlur(src,(7,7),1,0)
dst = cv.ximgproc.jointBilateralFilter(joint,src,33,2,0)
# dst = cv.ximgproc.jointBilateralFilter(src,src,33,2,0) #采用src作为jointcv.imshow("img",src)
cv.imshow("joint",joint)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

(6)导向滤波:

导向滤波也是需要一张图片作为引导图片,来表明边缘,物体等信息,作为保持边缘滤波算法,可以采用自身作为导向图片。opencv2中暂不支持导向滤波, 同样在opencv-contrib-python包的ximgproc模块提供了导向滤波函数。

1)函数格式:

cv2.ximgproc.guidedFilter(guide,src,radius,eps,dDepth)guide: 导向图片,单通道或三通道src: 输入图像对象矩阵,可以为单通道或多通道radius:用来计算卷积核的领域直径eps:规范化参数, eps的平方类似于双边滤波中的sigmaColor(颜色空间滤波器标准偏差值)(regularization term of Guided Filter. eps2 is similar to the sigma in the color space into bilateralFilter.)dDepth: 输出图片的数据深度

2)应用实例:

import cv2 as cvsrc = cv.imread("2.jpg")
dst = cv.ximgproc.guidedFilter(src,src,33,2,-1)
cv.imshow("img",src)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

17.腐蚀处理:

(1)函数格式:

# 【1】获得腐蚀核
kernel=cv2.getStructuringElement(shape,ksize,anchor)shape:核的形状cv2.MORPH_RECT: 矩形cv2.MORPH_CROSS: 十字形(以矩形的锚点为中心的十字架)cv2.MORPH_ELLIPSE:椭圆(矩形的内切椭圆)ksize: 核的大小,矩形的宽,高格式为(width,height)anchor: 核的锚点,默认值为(-1,-1),即核的中心点# 【2】执行腐蚀操作
dst=cv2.erode(src,kernel,anchor,iterations,borderType,borderValue):src: 输入图像对象矩阵,为二值化图像kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得anchor:锚点,默认为(-1,-1)iterations:腐蚀操作的次数,默认为1borderType: 边界种类,有默认值borderValue:边界值,有默认值

(2)应用实例:

import cv2 as cvimg = cv.imread("2.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,200,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
dst = cv.erode(img_thr,kernel,iterations=1)cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

18.膨胀处理:

(1)函数格式:

dst = cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)src: 输入图像对象矩阵,为二值化图像kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得anchor:锚点,默认为(-1,-1)iterations:腐蚀操作的次数,默认为1borderType: 边界种类borderValue:边界值

(2)应用实例:

import cv2 as cvimg = cv.imread("2.jpg")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,500,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
dst = cv.dilate(img_thr,kernel,iterations=1)cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

19.开运算/闭运算/形态学梯度/顶帽/底帽:

        开运算:先进行腐蚀操作,后进行膨胀操作,主要用来去除一些较亮的部分,即先腐蚀掉不要的部分,再进行膨胀;

  闭运算:先进行膨胀操作,后进行腐蚀操作,主要用来去除一些较暗的部分;

  形态学梯度:膨胀运算结果减去腐蚀运算结果,可以拿到轮廓信息;

  顶帽运算:原图像减去开运算结果;

  底帽运算:原图像减去闭运算结果。 

(1)函数格式:

dst = cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)src: 输入图像对象矩阵,为二值化图像op: 形态学操作类型cv2.MORPH_OPEN    开运算cv2.MORPH_CLOSE   闭运算cv2.MORPH_GRADIENT 形态梯度cv2.MORPH_TOPHAT   顶帽运算cv2.MORPH_BLACKHAT  底帽运算kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得anchor:锚点,默认为(-1,-1)iterations:腐蚀操作的次数,默认为1borderType: 边界种类borderValue:边界值

(2)应用实例:

import cv2 as cv
import matplotlib.pyplot as pltimg = cv.imread("2.jpg")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,20,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
open = cv.morphologyEx(img_thr,cv.MORPH_OPEN,kernel,iterations=1)
close = cv.morphologyEx(img_thr,cv.MORPH_CLOSE,kernel,iterations=1)
gradient = cv.morphologyEx(img_thr,cv.MORPH_GRADIENT,kernel,iterations=1)
tophat = cv.morphologyEx(img_thr,cv.MORPH_TOPHAT,kernel,iterations=1)
blackhat = cv.morphologyEx(img_thr,cv.MORPH_BLACKHAT,kernel,iterations=1)images=[img_thr,open,close,gradient,tophat,blackhat]
titles=["img_thr","open","close","gradient","tophat","blackhat"]
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()

20.直线、圆、矩形、文字的绘制:

# 【1】绘制直线
# img、ps、pe、color为必须参数,其它为可选项
cv2.line(img, ps, pe, color, thickness, lineType, shift)参数:img:要画的直线所在的矩形或图像ps:直线的起点位置,注意这是一个坐标点,类似(X,Y)pe:直线的终点位置,同上color:直线的颜色,颜色值为BGR,即:(0,0,255)为红色thickness:线条宽度lineType:线条类型,三个参数可选LINE_4、LINE_8、LINE_AA,感兴趣的可以自己试一下shift:不常用,直线坐标点小数点位数# 【2】绘制圆
# img、center、radius、color为必须参数,其它为可选项
cv2.circle(img, center, radius, color, thickness, lineType, shift)参数:img:要画的圆所在的矩形或图像center:圆心坐标radius:圆的半径值color:圆边框颜色,颜色值为BGR,即:(0,0,255)为红色thickness:圆边框大小,负值表示该圆是一个填充图形lineType:线条类型,三个参数可选0,4,8,感兴趣的亲测shift:圆心坐标和半径的小数点位数# 【3】绘制椭圆
# img/center/axes/rotateAngle/startAngle/endAngle/color为必须参数,其它为可选项
cv2.ellipse(img, center, axes, rotateAngle, startAngle, endAngle, color, thickness, lineType, shift)参数:img:要画的椭圆所在的矩形或图像center:椭圆的圆心坐标,注意这是一个坐标值axes:椭圆的长轴和短轴的长度,这是一个元组信息rotateAngle:椭圆旋转的角度startAngle:椭圆弧起始角度endAngle:椭圆弧终止角度color:椭圆线条颜色,颜色值为BGR,即:(0,0,255)为红色thickness:椭圆的线条宽度lineType:线条类型,三个参数可选LINE_4、LINE_8、LINE_AA,感兴趣的可以亲测shift:椭圆坐标点小数点位数# 【4】绘制矩形
# img/ps/pe/color为必须参数,其它为可选项
cv2.rectangle(img, ps, pe, color, thickness, lineType, shift)参数:img:矩形所在的矩形或图像ps:矩形左上角点的坐标pe:矩形右下角点的坐标color:线条颜色,颜色值为BGR,即:(0,0,255)为红色thickness:矩形线条宽度lineType:线条类型,三个参数可选LINE_4、LINE_8、LINE_AA,感兴趣的可以亲测shift:坐标点小数点位数# 【5】绘制多边形
# img/pts/isClosed/color为必须参数,其它为可选项
cv2.polylines(img, pts, isClosed, color, thickness, lineType, shift)参数:img:多边形所在的矩形或图像pts:多边形各边的坐标点组成的一个列表,是一个numpy的数组类型isClosed:值为True或False,若为True则表示一个闭合的多边形,若为False则不闭合color:线条颜色,颜色值为BGR,即:(0,0,255)为红色thickness:线条宽度lineType:线条类型,三个参数可选LINE_4、LINE_8、LINE_AA,感兴趣的可以亲测shift:坐标点小数点位数# 【6】绘制字符
# img/text/org/fontFace/fontScale/color为必须参数,其它为可选项
cv2.putText(img, text, org, fontFace, fontScale, color, thickness, lineType, bottomLeftOrigin)参数:img:文字要放置的矩形或图像text:文字内容org:文字在图像中的左下角坐标fontFace:字体类型,可选参数有以下几种FONT_HERSHEY_SIMPLEX,FONT_HERSHEY_PLAIN,FONT_HERSHEY_DUPLEX,FONT_HERSHEY_COMPLEX, FONT_HERSHEY_TRIPLEX,FONT_HERSHEY_COMPLEX_SMALL,FONT_HERSHEY_SCRIPT_SIMPLEX, orFONT_HERSHEY_SCRIPT_COMPLEX上述类型的字体可以结合FONT_HERSHEY_ITALIC一起来使用,从而使字体产生斜体效果。fontScale:缩放比例,用该值乘以程序字体默认大小即为字体大小color:字体颜色,颜色值为BGR,即:(0,0,255)为红色thickness:字体线条宽度bottomLeftOrigin:默认为 true,即表示图像数据原点在左下角;若为False则表示图像数据原点在左上角。

21.边缘检测:

(1)Canny边缘检测:

平滑图像:使用高斯滤波器与图像进行卷积,平滑图像,以减少边缘检测器上明显的噪声影响;

计算图像的梯度和方向:图像中的边缘可以指向各个方向,这里计算图像的梯度,并将梯度分类为垂直、水平和斜对角;

非最大值抑制:利用上一步计算出来的梯度方向,检测某一像素在梯度的正方向和负方向上是否是局部最大值,如果是,则该像素点保留为边缘点,否则该像素点将被抑制;

双阈值算法检测和连接边缘:仍然存在由于噪声和颜色变化引起的一些边缘像素。为了解决这些杂散响应,必须用弱梯度值过滤边缘像素,并保留具有高梯度值的边缘像素,可以通过选择高低阈值来实现。

1)函数格式:

canny = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]]) 参数:image: 处理的原图像,该图像必须为单通道的灰度图threshold1: 最小阈值threshold2 最大阈值

2)应用实例:

import os
import cv2
img = cv2.imread('2.jpg', 0)             #转化为灰度图
img_color = img
blur = cv2.GaussianBlur(img, (3, 3), 0)  # 用高斯滤波处理原图像降噪
canny = cv2.Canny(blur, 50, 150)         # 50是最小阈值,150是最大阈值
cv2.namedWindow("canny",0);#可调大小
cv2.namedWindow("1",0);#可调大小
cv2.imshow('1', img)
cv2.imshow('canny', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()

(2)Sobel边缘检测:

Sobel算子包含两个3*3矩阵,分别为横向和纵向,将之与图像做平面卷积,可分别得出横向及纵向的高度差分近似值,图像的每一个像素点的横向与纵向灰度值平方和开方获得该点灰度的大小。

1)函数格式:

# 【1】
Sobel_x_or_y = cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)参数:src:需要处理的图像;ddepth:图像的深度,-1表示采用的是与原图像相同的深度,目标图像的深度必须大于等于原图像的深度;dx和dy:求导的阶数,0表示这个方向上没有求导,一般为0、1、2。# 【2】
convertScaleAbs()
# Sobel函数求完导数后会有负值,还有会大于255的值,convertScaleAbs()函数将sobel算子的处理结果转换为uint8形式,否则将无法显示图像

2)应用实例:

import os
import cv2
img = cv2.imread('2.jpg', 0)              #转化为灰度图
x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
y = cv2.Sobel(img, cv2.CV_16S, 0, 1)
# cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
# alpha是伸缩系数,beta是加到结果上的一个值,结果返回uint类型的图像
Scale_absX = cv2.convertScaleAbs(x)
Scale_absY = cv2.convertScaleAbs(y)
result = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)
cv2.namedWindow("result",0);#可调大小
cv2.namedWindow("1",0);#可调大小
cv2.imshow('1', img)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

(3)findContours()函数:

1)函数格式:

# 【1】
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])  参数:image:寻找轮廓的图像;mode:轮廓的检索模式,有四种:1)cv2.RETR_EXTERNAL表示只检测外轮廓2)cv2.RETR_LIST检测的轮廓不建立等级关系3)cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。4)cv2.RETR_TREE建立一个等级树结构的轮廓。method:为轮廓的近似办法1)cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==12)cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息3) cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似返回值:opencv2返回两个值:contours:hierarchy。opencv3会返回三个值,分别是img, countours, hierarchy。# 【2】在图像上绘制轮廓。
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])  参数:image:指明在哪幅图像上绘制轮廓;contours:轮廓本身,在Python中是一个list。contourIdx:指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。   thickness:表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。

22.模版匹配:

        模板匹配的原理就是不断地在原图中移动模板图像去比较,模板匹配也是应用卷积来实现的:假设原图大小为W×H,模板图大小为w×h,那么生成图大小是(W-w+1)×(H-h+1),生成图中的每个像素值表示原图与模板的匹配程度。

(1)函数格式:

# 【1】执行目标匹配
cv2.matchTemplate(image, templ, method, result=None, mask=None)参数:image:待搜索图像templ:模板图像result:匹配结果method:计算匹配程度的方法:1)平方差匹配CV_TM_SQDIFF:用两者的平方差来匹配,最好的匹配值为02)归一化平方差匹配CV_TM_SQDIFF_NORMED3)相关匹配CV_TM_CCORR:用两者的乘积匹配,数值越大表明匹配程度越好4)归一化相关匹配CV_TM_CCORR_NORMED5)相关系数匹配CV_TM_CCOEFF:用两者的相关系数匹配,1表示完美的匹配,-1表示最差的匹配6)归一化相关系数匹配CV_TM_CCOEFF_NORMED# 【2】获取最后的最佳匹配结果获取最后的最佳匹配结果
# 获取一个矩阵a的最小值,最大值,并得到最大值,最小值的索引。
cv2.minMaxLoc(src, mask=None)

(2)应用实例:

# 【1】
import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('2.jpg', 0)
template = cv2.imread('pattern.jpg', 0)
h, w = template.shape[:2]  # rows->h, cols->w# 相关系数匹配方法:cv2.TM_CCOEFF
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
left_top = max_loc                                  # 左上角
right_bottom = (left_top[0] + w, left_top[1] + h)   # 右下角
cv2.rectangle(img, left_top, right_bottom, 255, 2)  # 画出矩形位置# 【2】多目标模版匹配
import cv2
import numpy as np
import matplotlib.pyplot as plt# 1.读入原图和模板
img_rgb = cv2.imread('marioimg.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('mariopattern.jpg', 0)
h, w = template.shape[:2]# 2.标准相关模板匹配
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8# 3.np.where返回res中值大于0.8的所有坐标
loc = np.where(res >= threshold)  # 匹配程度大于%80的坐标y,x
for pt in zip(*loc[::-1]):  # 因为loc是先y坐标再x坐标,所以用loc[::-1]翻转一下,然后再用zip函数拼接在一起right_bottom = (pt[0] + w, pt[1] + h)cv2.rectangle(img_rgb, pt, right_bottom, (0, 0, 255), 2)cv2.imshow('1', img_rgb)
cv2.waitKey(0)

23.凸包:

(1)函数格式:

# 【1】多边形逼近
approx = cv2.approxPolyDP(cnt, epsilon, Flag)参数:cnt:待处理轮廓epsilon: 距离值,表示多边形的轮廓接近实际轮廓的程度,值越小,越精确;Flag:表示是否闭合# 【2】寻找凸包,获取凸包的角点
hull2 = cv2.convexHull(cnt, returnPoints=False)参数:cnt:待处理轮廓returnPoints:可选参数,默认是True,代表返回角点的x/y坐标;如果为False的话,表示返回轮廓中是凸包角点的索引# 【3】判断轮廓是否是凸形的
cv2.isContourConvex(hull)# 【4】计算点到轮廓的最短距离(也就是垂线)
dist = cv2.pointPolygonTest(cnt, (100, 100), True)

(2)应用实例:

import cv2
import numpy as np
import matplotlib.pyplot as plt# 1.先找到轮廓
img = cv2.imread('marioimg.jpg', 0)
_, thresh = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh, 3, 2)
image1 = cv2.drawContours(img, contours, -1, 255)
cv2.imshow('1', image1)
cnt = contours[0]# 2.寻找凸包,得到凸包的角点
hull = cv2.convexHull(cnt)# 3.绘制凸包
image = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.polylines(image, [hull], True, (0, 255, 0), 2)
cv2.imshow('3', image)cv2.waitKey(0)

24.计算轮廓特征:

(1)函数格式:

# 【1】轮廓面积
area = cv2.contourArea(cnt)# 【2】轮廓周长
perimeter = cv2.arcLength(cnt, True)  参数:参数2表示轮廓是否封闭,True表示封闭# 【3】图像矩(其中包含很多轮廓的特征信息)
M = cv2.moments(cnt)# 【4】rectangle1
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(img_color1, (x, y), (x + w, y + h), (0, 255, 0), 2)# 【5】rectangle2
rect = cv2.minAreaRect(cnt)
box = np.int0(cv2.boxPoints(rect))                     # 矩形的四个角点取整
cv2.drawContours(img_color1, [box], 0, (255, 0, 0), 2) # 绘制矩形# 【6】最小外接圆
(x, y), radius = cv2.minEnclosingCircle(cnt)
(x, y, radius) = np.int0((x, y, radius))               # 圆心和半径取整
cv2.circle(img_color2, (x, y), radius, (0, 0, 255), 2) # 绘制圆# 【7】椭圆拟合
ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img_color2, ellipse, (255, 255, 0), 2)# 【8】利用hu矩阵返回两个轮廓的形状相似度,返回值越小,越相似
cv2.matchShapes(cnt_b, cnt_b, 1, 0.0)参数:参数3:匹配方法参数4:是OpenCV的预留参数

25.霍夫变换:

(1)霍夫直线变换:

1)函数格式:

# 【1】霍夫直线变换
lines = cv2.HoughLines(edges, 0.8, np.pi / 180, 90)参数:参数1:要检测的二值图(一般是阈值分割或边缘检测后的图)参数2:距离r的精度,值越大,考虑越多的线参数3:角度θ的精度,值越小,考虑越多的线参数4:累加数阈值,值越小,考虑越多的线# 【2】统计概率霍夫直线变换
lines = cv2.HoughLinesP(edges, 0.8, np.pi/180, 90, minLineLength=50, maxLineGap=10)参数:参数1:要检测的二值图(一般是阈值分割或边缘检测后的图)参数2:距离r的精度,值越大,考虑越多的线参数3:角度θ的精度,值越小,考虑越多的线参数4:累加数阈值,值越小,考虑越多的线minLineLength:最短长度阈值,比这个长度短的线会被排除maxLineGap:同一直线两点之间的最大距离

2)应用实例:

# 【1】
import cv2
import numpy as npimg = cv2.imread('1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)# 霍夫直线变换
lines = cv2.HoughLines(edges, 0.8, np.pi / 180, 90)
# 绘制直线
for line in lines:rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 1000 * (-b))y1 = int(y0 + 1000 * (a))x2 = int(x0 - 1000 * (-b))y2 = int(y0 - 1000 * (a))cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255))cv2.imshow('1', img)
cv2.waitKey(0)# 【2】
import cv2
import numpy as npimg = cv2.imread('1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)lines = cv2.HoughLinesP(edges, 0.8, np.pi / 180, 90, minLineLength=50, maxLineGap=10)
for line in lines:x1, y1, x2, y2 = line[0]cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1, lineType=cv2.LINE_AA)cv2.imshow('1', img)
cv2.waitKey(0)

(2)霍夫圆变换:

1)函数格式:

circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 20, param2=30)参数:参数1:轮廓参数2:变换方法,一般使用霍夫梯度法,详情:HoughModes参数3 dp=1:表示霍夫梯度法中累加器图像的分辨率与原图一致参数4:两个不同圆圆心的最短距离参数5:param2跟霍夫直线变换中的累加数阈值一样

2)应用实例:

import cv2
import numpy as npimg = cv2.imread('marioimg.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 50, param2=30)
circles = np.int0(np.around(circles))for i in circles[0, :]:cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)  # 画出外圆cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)  # 画出圆心cv2.imshow('1', img)
cv2.waitKey(0)

26.图像梯度提取:

     (1)函数格式:

# 【1】Sobel算子
sobelx = cv2.Sobel(img, -1, 1, 0, ksize=3)  # 只计算x方向
sobely = cv2.Sobel(img, -1, 0, 1, ksize=3)  # 只计算y方向# 【2】Laplacian算子
laplacian = cv2.Laplacian(img, -1)          # 使用Laplacian算子 #【3】Scharr算子
scharr = cv2.Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None, /)

     (2)应用实例:

import cv2def scharr_demo(image):grad_x = cv2.Scharr(image, cv2.CV_32F, 1, 0)  # 采用Scharr边缘更突出grad_y = cv2.Scharr(image, cv2.CV_32F, 0, 1)gradx = cv2.convertScaleAbs(grad_x)  # 由于算完的图像有正有负,所以对其取绝对值grady = cv2.convertScaleAbs(grad_y)# 计算两个图像的权值和,dst = src1*alpha + src2*beta + gammagradxy = cv2.addWeighted(gradx, 0.5, grady, 0.5, 0)cv2.imshow("gradx", gradx)cv2.imshow("grady", grady)cv2.imshow("gradient", gradxy)src = cv2.imread("2.jpg")
cv2.imshow("lena", src)
scharr_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()

27.角点检测:

(1)函数格式:

# 【1】harris角点检测
cv.cornerHarris(img,blocksize,ksize,k)参数:img:图片blocksize:角点检测区域的大小ksize:sobel求导中使用的窗口的大小k:取值参数# 【2】Fast检测器
cv.FastFeatureDetector_create([, threshold[, nonmaxSuppression[, type]]])# 【3】绘制重要点
cv2.drawKeypoints(image,keypoints,outImage[,color[,flags]])

(2)应用实例:

# 【1】
import cv2 as cv
import numpy as npimg = cv.imread('1.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)dst = cv.cornerHarris(gray,2,3,0.04)
img[dst>0.01*dst.max()] = [0,0,255]
cv.imshow('res',img)cv.waitKey(0)# 【2】
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('1.jpg',0)fast=cv2.FastFeatureDetector_create(threshold=20,nonmaxSuppression=True,type=cv2.FAST_FEATURE_DETECTOR_TYPE_9_16)                        #获取FAST角点探测器
kp=fast.detect(img,None)                               #描述符img = cv2.drawKeypoints(img,kp,img,color=(255,0,0))    #画到img上面
print ("Threshold: ", fast.getThreshold())             #输出阈值
print ("nonmaxSuppression: ", fast.getNonmaxSuppression())#是否使用非极大值抑制
print ("Total Keypoints with nonmaxSuppression: ", len(kp))#特征点个数cv2.imshow('sp',img)
cv2.waitKey(0)

28.图像通道分离与合并:

# 【1】图像通道分离
b, g, r = cv2.split(img)# 【2】图像通道合并
merge = cv2.merge([b, g, r])

29.图像算术运算:

# 【1】加
dst = cv2.add(m1, m2)# 【2】减
dst = cv2.subtract(m1, m2)# 【3】乘
dst = cv2.multiply(m1, m2)# 【4】除
dst = cv2.divide(m1, m2)

30.像素的均质和方差

# 【1】均值
M1 = cv2.mean(img)# 【2】均值和方差
M1, dev1 = cv2.meanStdDev(img)

31.漫水填充:

(1)函数格式:

def floodFill(image, mask, seedPoint, newVal, loDiff=None, upDiff=None, flags=None)参数:image:原图像mask:掩码,单通道8位图像,比image的高度多2个像素,宽度多2个像素。seedPoint:起始点(原像素点,相当于鼠标点击的那个像素点)newVal:在重绘区域像素的新值(RBG值,相当于上图指定的红色)loDiff:像素值的下限差值(最多比原像素点低多少)upDiff:像素值的上限差值(最多比原像素点高多少)Flag:FLOODFILL_FIXED_RANGE:改变图像,泛洪填充FLOODFILL_MASK_ONLY:不改变图像,只填充遮罩层本身,忽略新的颜色值参数

(2)应用实例:

import cv2
import numpy as npdef fill_color_demo(img):copyImg = img.copy()h, w = img.shape[:2]mask = np.zeros([h + 2, w + 2], np.uint8)cv2.floodFill(copyImg, mask, (100, 200), (0, 255, 0), (100, 100, 100), (50, 50, 50), cv2.FLOODFILL_FIXED_RANGE)cv2.imshow("fill_color_demo", copyImg)def fill_binary_demo():img2 = np.zeros([400, 400, 3], np.uint8)img2[100:300, 100:300, :] = 255mask = np.ones([402, 402], np.uint8)mask[101:301, 101:301] = 0cv2.floodFill(img2, mask, (200, 200), (0, 0, 255), cv2.FLOODFILL_MASK_ONLY)cv2.imshow("fill_binary_demo", img2)fill_binary_demo()
img = cv2.imread('2.jpg')
fill_color_demo(img)
cv2.waitKey(0)
cv2.destroyAllWindows()

32.K近邻(KNN):

(1)函数格式:

# 【1】
knn = cv.ml.KNearest_create()# 【2】
knn.train(trainData, cv.ml.ROW_SAMPLE, responses)# 【3】
ret, results, neighbours ,dist = knn.findNearest(newcomer, 3)

(2)函数格式:

import numpy as np
import cv2#读取图片转为灰度图
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#把图片分隔成5000个,每个20x20大小
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]#再转成numpy数组
x = np.array(cells)#一半用来训练的数组,一半用来测试的数组
train = x[:, :50].reshape(-1, 400).astype(np.float32)
test = x[:, 50:100].reshape(-1, 400).astype(np.float32)#创建训练和测试的标签
k = np.arange(10)
train_labels = np.repeat(k,250)[:,np.newaxis]
test_labels = train_labels.copy()#创建一个K-Nearest Neighbour分类器,训练数据,然后用测试数据测试它
knn = cv2.ml.KNearest_create()
knn.train(train,cv2.ml.ROW_SAMPLE,train_labels)
ret,result,neighbours,dist = knn.findNearest(test,k=5)#最终检查测试的精确度,比较结果,检查哪些是错误的,最终输出正确率
matches = result == test_labels
correct = np.count_nonzero(matches)
accuracy = correct*100.0 / result.size
print(accuracy)

33.拟合:

(1)直线拟合:

1)函数格式:

line =cv.fitLine(nptest,cv.DIST_L2,0,0.01,0.01)参数:points :nparray类型的点集(一般的数列直接报错),待拟合的点的坐标 distType:有关距离的定义,可用最快最简单的L2距离,就是常用的最小二乘法param:一些距离计算类型(distType)中用到的参数,写0系统会自动选用最优的参数。reps和aeps:用于表示拟合直线所需要的径向和角度精度,通常情况下两个值均被设定为0.01。

2)应用实例:

import cv2 as cv
import numpy as nptest =[(1,2),(2,4),(3,6)]
nptest=np.array(test)
line =cv.fitLine(nptest,cv.DIST_L2,0,0.01,0.01)

(2)椭圆拟合:

1)函数格式:

ellipse = cv2.fitEllipse(cnt)

2)应用实例:

rrt = cv2.fitEllipse(contours[i])
# 绘制拟合椭圆
cv2.ellipse(ellipse1, rrt,255, 2, cv2.LINE_AA)
x, y = rrt[0]
# 中心
cv2.circle(ellipse1, (np.int(x), np.int(y)), 4, 255, -1, 8, 0)
plt.subplot(2, 3, 6),plt.imshow(ellipse1)

34.图像连通域:

(1)函数格式:

ret, labels = cv2.connectedComponents(gray_img, connectivity=None)
# connectivity 4或8,临近像素为周围4像素或8像素

(2)应用举例:

import cv2
import numpy as npimg = np.array([[0, 255, 0, 0],[0, 0, 0, 255],[0, 0, 0, 255],[255, 0, 0, 0]], np.uint8)_, labels = cv2.connectedComponents(img)
print(labels)
res = cv2.equalizeHist(cv2.convertScaleAbs(labels))
print(res)

35.骨架提取:

import os
import numpy as np
import cv2
import sysim = cv2.imread("cvLetter.jpg", 0)ret, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))skel = np.zeros(im.shape, np.uint8)
erode = np.zeros(im.shape, np.uint8)
temp = np.zeros(im.shape, np.uint8)i = 0
while True:cv2.imshow('im %d' % (i), im)erode = cv2.erode(im, element)temp = cv2.dilate(erode, element)# 消失的像素是skeleton的一部分temp = cv2.subtract(im, temp)cv2.imshow('skeleton part %d' % (i,), temp)skel = cv2.bitwise_or(skel, temp)im = erode.copy()if cv2.countNonZero(im) == 0:break;i += 1cv2.imshow('Skeleton', skel)
cv2.waitKey()

代码来自:https://blog.csdn.net/aipush/article/details/84840870

骨架提取原理请见:https://www.cnblogs.com/xianglan/archive/2011/01/01/1923779.html

# -*- coding: utf-8 -*-import cv2def VThin(image, array):h, w = image.shapeNEXT = 1for i in range(h):for j in range(w):if NEXT == 0:NEXT = 1else:M = int(image[i, j - 1]) + int(image[i, j]) + int(image[i, j + 1]) if 0 < j < w - 1 else 1if image[i, j] == 0 and M != 0:a = [0] * 9for k in range(3):for l in range(3):if -1 < (i - 1 + k) < h and -1 < (j - 1 + l) < w and image[i - 1 + k, j - 1 + l] == 255:a[k * 3 + l] = 1sum = a[0] * 1 + a[1] * 2 + a[2] * 4 + a[3] * 8 + a[5] * 16 + a[6] * 32 + a[7] * 64 + a[8] * 128image[i, j] = array[sum] * 255if array[sum] == 1:NEXT = 0return imagedef HThin(image, array):h, w = image.shapeNEXT = 1for j in range(w):for i in range(h):if NEXT == 0:NEXT = 1else:M = int(image[i - 1, j]) + int(image[i, j]) + int(image[i + 1, j]) if 0 < i < h - 1 else 1if image[i, j] == 0 and M != 0:a = [0] * 9for k in range(3):for l in range(3):if -1 < (i - 1 + k) < h and -1 < (j - 1 + l) < w and image[i - 1 + k, j - 1 + l] == 255:a[k * 3 + l] = 1sum = a[0] * 1 + a[1] * 2 + a[2] * 4 + a[3] * 8 + a[5] * 16 + a[6] * 32 + a[7] * 64 + a[8] * 128image[i, j] = array[sum] * 255if array[sum] == 1:NEXT = 0return imagedef Xihua(image, array, num=10):for i in range(num):VThin(image, array)HThin(image, array)return imagedef main():# 映射表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]# 读取灰度图片,并显示img = cv2.imread("cvLetter.jpg", 0)  # 直接读为灰度图像cv2.imshow('image', img)gaussian_img = cv2.GaussianBlur(img, (5, 5), 5)kernel3 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))dilate_img = cv2.dilate(gaussian_img, kernel3)binary_img = cv2.adaptiveThreshold(dilate_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,7, 5)cv2.imshow('binary', binary_img)xihua_img = Xihua(binary_img, array)cv2.imshow('xihua', xihua_img)cv2.waitKey(0)cv2.destroyAllWindows()main()

36.SVM:

(1)函数格式:

https://www.cnblogs.com/xixixing/p/12377090.html

svm = cv.ml.SVM_create()# 设置核函数:LINEAR/POLY/RBF/SIGMOID
svm.setKernel(cv.ml.SVM_LINEAR)# 设置迭代终止条件,默认:TermCriteria( TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, FLT_EPSILON )
setTermCriteria() # 指定SVM的类型:C_SVC/NU_SVC/ONE_CLASS/EPS_SVR/NU_SVR
svm.setType(cv.ml.SVM_C_SVC)# 核函数相关:适用类型:SVM::POLY, SVM::RBF, SVM::SIGMOID or SVM::CHI2
svm.setGamma(5.383)# 核函数相关:coef0(默认0)适用类型:SVM::POLY,SVM::SIGMOID
setCoef0()# 核函数相关:degree(默认0)适用类型:SVM::POLY
setDegree()# 优化相关:C(默认0)适用类型:SVM::C_SVC, SVM::EPS_SVR ,SVM::NU_SVR
svm.setC(2.67)# 优化相关:nu(默认0)适用类型:SVM::NU_SVC, SVM::ONE_CLASS,SVM::NU_SVR
setNu()# 优化相关:epsilon(默认0)适用类型:SVM::EPS_SVR
setP()

(2)应用实例:

import cv2 as cv
import numpy as npSZ=20
# Number of bins
bin_n = 16
affine_flags = cv.WARP_INVERSE_MAP|cv.INTER_LINEARdef deskew(img):m = cv.moments(img)if abs(m['mu02']) < 1e-2:return img.copy()skew = m['mu11']/m['mu02']M = np.float32([[1, skew, -0.5*SZ*skew], [0, 1, 0]])img = cv.warpAffine(img,M,(SZ, SZ),flags=affine_flags)return imgdef hog(img):gx = cv.Sobel(img, cv.CV_32F, 1, 0)gy = cv.Sobel(img, cv.CV_32F, 0, 1)mag, ang = cv.cartToPolar(gx, gy)bins = np.int32(bin_n*ang/(2*np.pi))    # quantizing binvalues in (0...16)bin_cells = bins[:10,:10], bins[10:,:10], bins[:10,10:], bins[10:,10:]mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]hist = np.hstack(hists)     # hist is a 64 bit vectorreturn histimg = cv.imread('digits.png',0)
cells = [np.hsplit(row,100) for row in np.vsplit(img,50)]
# 前一半是训练数据,其余是测试数据
train_cells = [ i[:50] for i in cells ]
test_cells = [ i[50:] for i in cells]
deskewed = [list(map(deskew,row)) for row in train_cells]
hogdata = [list(map(hog,row)) for row in deskewed]
trainData = np.float32(hogdata).reshape(-1,64)
responses = np.repeat(np.arange(10),250)[:,np.newaxis]svm = cv.ml.SVM_create()
svm.setKernel(cv.ml.SVM_LINEAR)
svm.setType(cv.ml.SVM_C_SVC)
svm.setC(2.67)
svm.setGamma(5.383)
svm.train(trainData, cv.ml.ROW_SAMPLE, responses)
svm.save('svm_data.dat')deskewed = [list(map(deskew,row)) for row in test_cells]
hogdata = [list(map(hog,row)) for row in deskewed]
testData = np.float32(hogdata).reshape(-1,bin_n*4)
result = svm.predict(testData)[1]
mask = result==responses
correct = np.count_nonzero(mask)
print(correct*100.0/result.size)

37.频域处理:

        https://blog.csdn.net/on2way/article/details/46981825

(1)傅立叶正变换/反变换:

1)函数格式:

# 【1】傅立叶正变换
f = np.fft.fft2(img)# 【2】中心化
fshift = np.fft.fftshift(f)
#取绝对值:将复数变化成实数# 【3】去中心化
f1shift = np.fft.ifftshift(fshift)# 【4】傅立叶逆变换
img_back = np.fft.ifft2(f1shift)

2)应用实例:

import cv2
import numpy as np
import matplotlib.pyplot as plt#直接读为灰度图像
img = cv2.imread('2.jpg',0)
# 傅立叶正变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)#取绝对值:将复数变化成实数
#取对数的目的为了将数据变化到0-255
s1 = np.log(np.abs(fshift))
plt.subplot(131),plt.imshow(img,'gray'),plt.title('original')
plt.subplot(132),plt.imshow(s1,'gray'),plt.title('center')# 傅立叶逆变换
f1shift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f1shift)#取绝对值:将复数变化成实数
img_back = np.abs(img_back)
plt.subplot(133),plt.imshow(img_back,'gray'),plt.title('img back')

3)图像的相位和振幅:

恢复一个频域图像需要图像的振幅以及相位,振幅就是实部虚部的平方和开方,相位就是atan(实部/虚部),振幅用来描述图像灰度的亮度,影响哪些部分偏亮或者暗,而图像实际上是由它的相位决定的。

import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread('2.jpg',0) # 【1】傅立叶正变换
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
#取绝对值的目的是将复数变化成实数;取对数的目的为了将数据变化到0-255
s1 = np.log(np.abs(fshift))
plt.subplot(221),plt.imshow(img,'gray'),plt.title('original')
plt.xticks([]),plt.yticks([])# 【2】傅立叶逆变换:只取振幅恢复图像
f1shift = np.fft.ifftshift(np.abs(fshift))
img_back = np.fft.ifft2(f1shift)
# 取绝对值的目的是将复数变化成实数
img_back = np.abs(img_back)
# 调整大小范围便于显示
img_back = (img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
plt.subplot(222),plt.imshow(img_back,'gray'),plt.title('only Amplitude')
plt.xticks([]),plt.yticks([])# 【3】傅立叶逆变换:只取相位恢复图像
f2shift = np.fft.ifftshift(np.angle(fshift))
img_back = np.fft.ifft2(f2shift)
img_back = np.abs(img_back)
#调整大小范围便于显示
img_back = (img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
plt.subplot(223),plt.imshow(img_back,'gray'),plt.title('only phase')
plt.xticks([]),plt.yticks([])# 【4】傅立叶逆变换--将相位/振幅合成恢复图像
s1 = np.abs(fshift)           #取振幅
s1_angle = np.angle(fshift)   #取相位
s1_real = s1*np.cos(s1_angle) #取实部
s1_imag = s1*np.sin(s1_angle) #取虚部
s2 = np.zeros(img.shape,dtype=complex)
s2.real = np.array(s1_real)   #重新赋值给s2
s2.imag = np.array(s1_imag)
f2shift = np.fft.ifftshift(s2) #对新的进行逆变换
img_back = np.fft.ifft2(f2shift)
img_back = np.abs(img_back)
#调整大小范围便于显示
img_back = (img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))
plt.subplot(224),plt.imshow(img_back,'gray'),plt.title('another way')
plt.xticks([]),plt.yticks([])plt.show()

(2)频域滤波器:

1)高通滤波器:

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
img_man = cv2.imread('2.jpg',0)
plt.subplot(121),plt.imshow(img_man,'gray'),plt.title('origial')
plt.xticks([]),plt.yticks([])# 生成高通滤波器mask
rows,cols = img_man.shape
mask = np.ones(img_man.shape,np.uint8)
mask[rows//2-30:rows//2+30,cols//2-30:cols//2+30] = 0# 傅立叶正变换
f1 = np.fft.fft2(img_man)
f1shift = np.fft.fftshift(f1)# 高通滤波
f1shift = f1shift*mask# 傅立叶反变换
f2shift = np.fft.ifftshift(f1shift)
img_new = np.fft.ifft2(f2shift)
img_new = np.abs(img_new)
img_new = (img_new-np.amin(img_new))/(np.amax(img_new)-np.amin(img_new))
plt.subplot(122),plt.imshow(img_new,'gray'),plt.title('Highpass')
plt.xticks([]),plt.yticks([])
plt.show()

2)低通滤波器:

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
img_man = cv2.imread('2.jpg',0)
plt.subplot(121),plt.imshow(img_man,'gray'),plt.title('origial')
plt.xticks([]),plt.yticks([])# 低通滤波器mask
rows,cols = img_man.shape
mask = np.zeros(img_man.shape,np.uint8)
mask[rows//2-20:rows//2+20,cols//2-20:cols//2+20] = 1# 傅立叶正变换
f1 = np.fft.fft2(img_man)
f1shift = np.fft.fftshift(f1)# 低通滤波
f1shift = f1shift*mask# 傅立叶反变换
f2shift = np.fft.ifftshift(f1shift)
img_new = np.fft.ifft2(f2shift)
img_new = np.abs(img_new)
img_new = (img_new-np.amin(img_new))/(np.amax(img_new)-np.amin(img_new))
plt.subplot(122),plt.imshow(img_new,'gray'),plt.title('Highpass')
plt.xticks([]),plt.yticks([])
plt.show()

3)带通滤波器:

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
img_man = cv2.imread('2.jpg',0)
plt.subplot(121),plt.imshow(img_man,'gray'),plt.title('origial')
plt.xticks([]),plt.yticks([])# 带通滤波器mask
rows,cols = img_man.shape
mask1 = np.ones(img_man.shape,np.uint8)
mask1[rows//2-8:rows//2+8,cols//2-8:cols//2+8] = 0
mask2 = np.zeros(img_man.shape,np.uint8)
mask2[rows//2-80:rows//2+80,cols//2-80:cols//2+80] = 1
mask = mask1*mask2# 傅立叶正变换
f1 = np.fft.fft2(img_man)
f1shift = np.fft.fftshift(f1)# 带通滤波
f1shift = f1shift*mask# 傅立叶反变换
f2shift = np.fft.ifftshift(f1shift)
img_new = np.fft.ifft2(f2shift)
img_new = np.abs(img_new)
img_new = (img_new-np.amin(img_new))/(np.amax(img_new)-np.amin(img_new))
plt.subplot(122),plt.imshow(img_new,'gray'),plt.title('Highpass')
plt.xticks([]),plt.yticks([])
plt.show()

38.图像数据类型转换:

from skimage import io,data,img_as_float, img_as_ubyte, img_as_uint,img_as_int # 输出图像数据类型
print(img.dtype.name)# 【1】unit8转float
dst=img_as_float(img)# 【2】float转uint8
# float转为unit8,有可能会造成数据的损失,因此会有警告提醒
dst=img_as_ubyte(img)# 【3】转换为unit16
dst= img_as_uint(img)# 【4】转换为int16
dst= img_as_int(img)   

39.生成随机颜色:

(1)函数格式:

random.randint(0, 255)

(2)应用举例:

import cv2
import numpy as np
import random# 画圆
def draw_circle(event, x, y, flags, param):# 鼠标左键双击if event == cv2.EVENT_LBUTTONDOWN:# 每次点击,都是一种 新颜色r = random.randint(0, 255)g = random.randint(0, 255)b = random.randint(0, 255)cv2.circle(img, (x, y), 100, (b, g, r), -1)img = np.zeros((600, 1000, 3), np.uint8)
cv2.namedWindow('draw circles')
# 鼠标点击的位置 = 传入函数的圆心
cv2.setMouseCallback('draw circles', draw_circle)while True:# 每次鼠标点击事件都会触发draw_circle,而函数体内会改变imgcv2.imshow('draw circles', img)if cv2.waitKey(1) & 0xFF == ord('q'):  # 按q键退出breakcv2.destroyAllWindows()

40.图像掩码处理(reduce_domain):

# 生成mask图像
sss=np.zeros([480,640],dtype=np.uint8)
sss[300:350,310:400]=255# 生成新的掩膜处理之后的图片
image=cv2.add(img0, np.zeros(np.shape(img0), dtype=np.uint8), mask=sss)

opencv-python基础知识学习笔记相关推荐

  1. Python 基础知识学习笔记——OpenCV(1)

    Python 基础知识学习笔记--OpenCV(1) OpenCV是一个开源的跨平台计算机视觉和机器学习软件库,它轻量而且高效,被广泛的使用. 整理一下OpenCV学习笔记,以防忘记. 文章目录 Py ...

  2. Python 基础知识学习笔记——NumPy

    Python基础知识学习笔记--NumPy 与 matlab 优秀的矩阵运算类似,python 提供了 numpy 库,这对熟悉 matlab 的用户来说非常友好.向量.矩阵和多维数组是数值计算中必不 ...

  3. Python基础知识学习笔记——Matplotlib绘图

    Python基础知识学习笔记--Matplotlib绘图 整理python笔记,以防忘记 文章目录 Python基础知识学习笔记--Matplotlib绘图 一.绘图和可视化 1.导入模块 2.一个简 ...

  4. python基础知识学习笔记(2)

    python基础知识学习笔记(2) 整理一下python基础知识,以防忘记 文章目录 python基础知识学习笔记(2) python简洁的一行代码 python简洁的一行代码 1.交换两个变量 # ...

  5. python基础知识学习笔记(1)

    python 基础知识学习笔记(1) 总结一下Python基础知识,以防忘记. 文章目录 python 基础知识学习笔记(1) 一.起步 1.python安装与编译环境 二.变量和简单数据类型 三.列 ...

  6. Python基础知识学习笔记(一)

    Python基础知识学习笔记(一) 文章目录 Python基础知识学习笔记(一) (一) 认识python 1.注释 2.变量及类型 3.关键字(标识符) (1)什么是关键字? (2)查看关键字 (3 ...

  7. Python基础语法学习笔记

    Python基础语法学习笔记 想淘宝省钱看我简介,博客www.liangxin.name (一) 一.Print()函数 1.数字可以直接输出,无需加引号 只能理解数字,却读不懂文字.因为数字和数学运 ...

  8. python基础入门学习笔记 (2)

    python基础入门学习笔记 2021年2月8日 1 编译器和解释器的区别 编译器/解释器:高级语言与机器之间的翻译官 2 值传递: print "a = ",a print &q ...

  9. oracle数据库基础知识总结,oracle数据库基础知识学习笔记

    oracle数据库基础知识学习笔记 一.oracle数据库类型: Char:  字符型(最大长度2000,定长.不足时以空格补充) Varchar2:字符型 最大长度 4000,变长,实际长度由存储的 ...

最新文章

  1. 一行代码实现Okhttp,Retrofit,Glide下载上传进度监听
  2. graythresh matlab,Matlab-图形算法和图像处理指南
  3. 思科安全:加密流量威胁检测、加密流量威胁和恶意软件检测、识别无线干扰或威胁、Talos 情报源可加强对已知和新型威胁的防御、分布式安全异常检测...
  4. 局域网络连接的计算机不全,WIN10局域网电脑和设备显示不完整
  5. 黑马程序员-WEB前端与移动开发就业班
  6. php遍历数组的四种方法,PHP遍历数组的常见几种方法
  7. 用Python批量更改图片大小
  8. 怎么让电脑速度变快_小科普 | 免费的路由器!用你的电脑开5G热点!
  9. 中国人民大学教授杜小勇:One Size Does not Fit All?
  10. 用Python告诉你,为什么宇宙的尽头是公务员!
  11. Java 用HTTP的方式发送JSON报文请求
  12. Unity 自由视角的惯性旋转
  13. Excel 2010 VBA 入门 035 利用VBA程序定义条件格式
  14. 协程与kotlin协程挂起
  15. ubuntu服务器图形界面崩溃解决方案
  16. 由浅入深了解机械键盘:各种轴的区别
  17. 水果店线下营销玩法有哪些,水果店前期营销方案有哪些
  18. android 百度转码,关于百度移动端转码的问题与解决办法
  19. 如何用python做后端写网页-flask框架
  20. 如何利用redis 实现分布式项目枷锁功能

热门文章

  1. python做马尔科夫模型预测法_python 日常笔记 hmmlearn 隐性马尔科夫模型案例分析...
  2. 邮件英语最常用的100个句型
  3. 密集创投迎来爆发期 今年会是链游之年么?
  4. Sublime text 3 注册码(转自晚晴幽草(简书作者))
  5. 哪个计算机无法做到双屏显示,显卡为何无法实现双屏显示 -电脑资料
  6. 体育视野杂志体育视野杂志社体育视野编辑部2022年第5期目录
  7. html页面插入百度谷歌地图的方法
  8. 选择SaaS供应商的15个关键问题
  9. WT588F02KD-24SS语音芯片(数码管显示驱动ic)在多功能烧水壶的应用设计方案
  10. 怎么改变html无序列表的字号,html无序列表代码 html5 无序列表的行距怎么设置