Opencv-Python笔记

注:Opencv读取图片的格式是BGR

  1. 数据读取——图像

① cv2.imread(参数1,参数2) ——读取指定图像,参数1指图像名,参数2指图像格式,彩色or灰度注:cv2.IMREAD_COLOR ——彩色图像     cv2.IMREAD_GRAYSCALE ——灰度图像

② cv2.imshow(参数1,参数2) ——显示图像  注:参数1指显示窗口名,可任意;参数2指需显示图像矩阵

③ cv2.waitKey(参数1);cv2.destroyAllWindows() ——等待时间,毫秒级,关闭显示窗口 注:参数1指毫秒数,若参数1等于0,则是按任意键关闭

④ cv2.imwrite(参数1,参数2) ——保存 注:参数1指图像名或图像路径;参数2指图像矩阵数据

 

  1. 数据读取——视频
  • cv=cv2.VideoCapture(‘’) ——读取指定路径下的视频流   注:cv2.VideoCapture()可捕获摄像头,0、1设定不同设备
  • ##检查是否正确打开##

   if vc.isOpened(): #视频流变量名.isOpened()

      open, frame = vc.read() #open被赋予布尔值;frame被赋予某帧图像的矩阵值

   else:

      open = Flase

   while open:

      ret, frame = vc.read()  #ret被赋予布尔值;

      if frame is None: #若某帧图像是空白,则会退出完成

         Break;

      if ret == True:

         gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # BGR2GRAY是指B、G、R三个通道顺序

         cv2.imshow(‘result’,gray)

         if cv2.waitKey(100) & 0xFF == 27: #0xFF是指Esc键

             break

 vc.release()

 cv2.destroyAllWindows()

 

  1. 颜色通道提取

① b,g,r=cv2.split(图像矩阵变量名)

② cv2.merge((b, g, r)) ——图像通道重新组合

③ 若需只要一个通道的来显示图像,则可将其余两通道设为0

例如:###只保留R通道###

A_img = img.copy()       #复制img图像数据矩阵赋予A_img

A_img[: , : , 0]=0         #通道0数据均赋予0

A_img[: , : , 1]=0         #通道1数据均赋予0

cv_show(‘R’, A_img)    

 

  1. 边界填充

top_size,bottom_size,left_size,right_size = (a, b, c, d)

img_name = cv2.copyMakeBorder(参数1,top_size, bottom_size, left_size, right_size, borderType=参数2 )     注:参数1是指需进行边界填充的图像数据矩阵;参数2是指填充的类型,如下是填充类型:

BORDER_REPLICATE :复制法,及复制图像最边缘像素

BORDER_REFLECT :反射法,及对感兴趣的图像中的像素在两边进行复制,eg: fedcba|abcdefgh|hgfedc

BORDER_REFLECT_101 :反射发,及以最边缘像素为轴,对称,eg:hgfedcb|abcdefgh|gfedcba

BORDER_WRAP :外包装法 eg: bcdefgh|abcdefgh|abcdefg

BORDER_CONSTANT :常量法,常数值填充   img_name = cv2.copyMakeBorder(参数1,top_size, bottom_size, left_size, right_size, borderType=参数2 ,value=number)

 

  1. 数值计算(像素值范围为0~255,共256个值)

① cv2.add(图像1矩阵,图像2矩阵)     注:若图像1与图像2对应元素相加大于255,,则定值为255

② 图像3矩阵 = 图像1矩阵 + 图像2矩阵 注:若图像1与图像2对应元素相加大于255,,则定值为与256的差值

 

  1. 图像融合(需确保图像大小一致)
  • cv2.resize() ——重置图像的大小

用法1:cv2.resize(图像,(数值1,数值2))   ——将图像重置为数值1 × 数值2的图像

用法2:cv2.resize(图像,(0,0),fx=a,fy=b)  ——将图像重置为x轴为a倍,y轴为b倍的图像

② cv2.addWeighted(图像1,a,图像2,b,c)   ——权重为a的图像1,与权重为b的图像2,且偏置为b进行融合     注:偏置b可理解为输出提亮

 

  1. 图像阈值

ret, dst = cv2.threshold(src, thresh, maxval, type)

其中:ret ——输出的阈值; dst ——输出图; src ——输入图; thresh ——阈值;

maxval ——当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值;

type ——二值化操作的类型,如下:

cv2.THRESH_BINARY 超过阈值部分取maxval,否则取0

cv2.THRESH_BINARY_INV 指cv2.THRESH_BINARY 的反转

cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变

cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0

cv2.THRESH_TOZERO_INV 指cv2.THRESH_TOZERO 的反转

 

  1. 图像平滑处理

①均值滤波    cv2.blur(图像矩阵,(a,b))    注:(a,b)指大小为a×b的卷积核,各元素值均为1

②方框滤波    cv2.boxFilter(图像矩阵,-1,(a,b),normalize=True/False)    注:True是选择做归一化,Flase是选择不做规一化

高斯滤波    cv2.GaussianBlur(图像矩阵,(a,b),1)   注:(a,b)指大小为a×b的卷积核,各元素值与据均值距离成反比

④中值滤波(将中间值作为输出值)   cv2.medianBlur(图像矩阵,a)    注:a指Fliter的大小

 

  1. 形态学—腐蚀操作

cv2.erode(图像矩阵,腐蚀核大小,iterations = a)     注:iterations指迭代次数,即腐蚀次数;腐蚀核指大小为b×c的矩阵,元素均能为1

腐蚀核Eg:kernel=np.ones((5,5),np.uint8)

 

  1. 形态学—膨胀操作

cv2.dilate(图像矩阵,膨胀核大小,iterations = a)

 

  1. 开运算与闭运算

①开运算   cv2.morphologyEx(图像矩阵,cv2.MORPH_OPEN,核大小)    #先腐蚀,后膨胀

②闭运算   cv2.morphologyEx(图像矩阵,cv2.MORPH_CLOSE,核大小)   #先膨胀,后腐蚀

 

  1. 梯度计算     #梯度=膨胀 - 腐蚀

cv2.morphologyEx(图像矩阵,cv2.MORPH_GRADIENT,核大小)

 

  1. 礼帽与黑帽

①礼帽  cv2.morphologyEx(图像矩阵,cv2.MORPH_TOPHAT,核大小)   #礼帽 = 原始输入 - 开运算结果

②黑帽  cv2.morphologyEx(图像矩阵,cv2.MORPH_BLACKHAT,核大小) #黑帽 = 闭运算 - 原始输入

 

  1.  图像梯度——Sobel算子

注:x、y轴需分开操作后再进行求和操作,否则结果会出现错误,求和使用cv2.addWeighted()函数

3阶算子:

       

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

dst = cv2.convertScaleAbs(dst)

其中:src指输入图像矩阵;

ddepth指图像的深度(可理解为数据类型),-1表示与原图像同样深度;

dx与dy分别指水平方向和垂直方向,dx=1、dy=0时求x轴(左右)方向,dx=0、dy=1时求y轴(上下)方向;

ksize指Sobel算子大小,默认为3;

 

注:求出的dst中的存在部分元素为负数,则会出现错误结果,即白到黑为正数,黑到白为负数,所有负数会被截断成0(黑色),故需取绝对值,及使用cv2.convertScaleAbs()函数进行转换dst,随后再打印结果。

 

  1. 图像梯度——Scharr、laplacian算子(绝对值操作

①Scharr算子较Sobel算子的元素值大,故分割结果更细致明显

3阶算子:

            

cv2.Scharr(src, ddepth, dx, dy)

②laplacian算子  (对噪音点较敏感,需与其他算法结合使用

python opencv读取文件夹 opencv-python文档_人工智能

转存失败重新上传取消

 

cv2.laplacian(src,ddepth)

 

  1. Canny边缘检测

步骤:

1)使用高斯滤波器(归一化处理),用来平滑图像,滤除噪音;

2)计算图像中每个像素点的梯度强度和方向(Sobel算子),

强度:        方向:

3)应用非极大值抑制,以消除边缘检测带来的杂散响应;

4)应用双阀值检测确定真实的和潜在的边缘;

梯度值>maxVal:则处理为边界;

minVal<梯度值<maxVal:连有边界则保留,否则舍弃;

梯度值<minVal:则舍弃。

 

 

  1. 通过抑制孤立的弱边缘最终完成边缘检测;

 

cv2.Canny(图像矩阵,minVal,maxVal)     注:minVal值越小,边缘检测结果越细致

 

  1. 图像金字塔

①高斯金字塔

向下采样方法(缩小)    cv2.pyrDown(图像矩阵)

向上采样方法(放大)    cv2.pyrUp(图像矩阵)注:将图像在每个方向扩大为原来的两倍,新增的行与列以0填充,使用先前同样的内核(乘以4)放大后的图像卷积

 

②拉普拉斯金字塔

 

 

  1. 图像轮廓

cv2.findContours(img,mode,method)

其中:mode轮廓检索模式:

cv2.RETR_EXTERNAL:只检索最外面的轮廓;

cv2.RETR_LIST:检索所有的轮廓,并将其保存到一条链表中;

cv2.RETR_CCOMP:检索所有的轮廓,并将他们组织为两层,顶层是各部分的外部边界,第二层是空洞的边界;

cv2.RETR_TREE(最常用):检索所有轮廓,并重构嵌套轮廓的整个层次;

 

method轮廓逼近方法:

cv2.CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列);

cv2.CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,即函数只保留他们的终点部分

 

使用步骤:

img = cv2.imread(‘输入图像’)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)    #转化为灰度图像

ret, thresh = cv2.threshhold(gray,127,255,cv2.THRESH_BINARY)

binary,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

(注:binary指图像的二值结果;contours指图像轮廓信息;hierarchy是指层级)

###绘制轮廓###

draw_img = img.copy()      (注:必须进行图像的copy,否则标注完后,原始图片会变成标注完成的图像)

res = cv2.drawContours(draw_img, contours, -1, (0,0,255), 2)

(注:contours指标注信息;-1指全部轮廓,也可设为0、1、2... ;(0,0,255)/(B,G,R)指标注线为红色R,或可换为蓝色B、绿色G;2是指标注线宽度)

 

轮廓特征

变量1 = contours[num]        #将第num个轮廓数据赋予变量1

#面积 cv2.contourArea(变量1)

#周长 cv2.arcLength(变量1,True)      #True指轮廓是闭合的

 

 

轮廓近似

epsilon = num*cv2.arcLength(变量1,True)     #num越小,轮廓越近似,epsilon亦可直接赋值

cv2.approxPolyDP(变量1,epsilon,True)

 

边界矩形

x,y,w,h = cv2.boundingRect(图形轮廓)         

cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

 

外界圆

(x,y),radius = cv2.minEnclosingCircle(图形轮廓)

center = (int(x),int(y))

radius = int(radius)

cv2.circle(img,center,radius,(0,255,0),2)

 

  1. 模板匹配

模板匹配和卷积原理相似,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv中有6种,然后将每次计算的结果放在一个矩阵里,作为结果输出。若原图像大小为A*B,模板大小为a*b,则输出结果的矩阵大小为(A-a+1)*(B-b+1)。

差别程度计算方法(平常尽量使用归一化的方法):

cv2.TM_SQDIFF:计算平方不同,计算出来的值越小,越相关;

cv2.TM_CCORR:计算相关性,计算出来的值越大,越相关;

cv2.TM_CCOEFF:计算相关系数,计算出来的值越小,越相关;

cv2.TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关;

cv2.TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关;

cv2.TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关;

 

 

变量1 = cv2.matchTemplate(原图像矩阵,模板矩阵,计算方法)

min_val, max_val, min_loc, max_loc = cv2.minMaxloc(变量1)

注:若需进行多对象匹配,则可设定一个阈值,比较其与差别程度的计算大小,从而得到满足条件的location,再循环画出矩形框。

 

 

 

  1. 傅里叶变换

傅里叶变换的作用

高频——变化剧烈的灰度分量,例如边界;

低频——变化缓慢的灰度分量,例如一片大海;

 

滤波

低通滤波器:只保留低频,会使图像模糊;

高通滤波器:只保留高频,会使图像变得细节增强;

 

注:opencv中主要是cv2.dft()和cv2.idft(),输入图像需先转换成np.float32格式——np.float32(输入图像)

         得到的结果中频率为0的部分会在左上角,通常需要shift将其转换到中心位置;

               cv2.dft()返回的结果是双通道的(实部、虚部),通常需转换成图像格式显示(0,255)

 

重要程序:

img = cv2.imread(‘输入图像’,0)

img_float32 = np.float32(img)

#DFT#

dft = cv2.dft(img_float32, cv2.DFT_COMPLEX_OUTPUT)

注:cv2.DFT_COMPLEX_OUTPUT指进行傅里叶变换的方法

dft_shift = np.fft.fftshift(dft)

#得到灰度图能表示的形式#

magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))

注:cv2.magnitude(x,y)将实部和虚部投影到空间域

#得到中心点位置#

rows, cols = img.shape

crow, ccol = int(rows/2), int(cols/2)

#低通滤波#

mask_l = np.zeros((rows, cols, 2), np.uint8)

mask_l[crow-30:crow+30, ccol-30:ccol+30] = 1

#高通滤波#

mask_h = np.ones((rows, cols, 2), np.uint8)

mask_h[crow-30:crow+30, ccol-30:ccol+30] = 0

#IDFT#

fshift = dft_shift*mask_l

f_ishift = np.fft.ifftshift(fshift)

img_back = cv2.idft(f_ishift)

img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

 

 

  1. 直方图

cv2.calcHist(images, channels, mask, histSize, ranges)      ——统计各个像素值的个数分布

其中:

images——原图像图像格式为uint8或float322,当输传入函数时,应用中括号[]括起来

channels——当输传入函数时,应用中括号[]括起来,其会告诉函数我们整幅图像的直方图,若输入图像时灰度图时,则值为[0],若是彩色图像(BGR),则传入参数是[0][1][2];

mask——掩模图像,统整整幅图像的直方图,则设值为None,但若想统图像某一份的直方图,则需制作一个掩膜图像使用;

mask操作步骤

mask = np.zeros(img.shape[:2], np.uint8)         #生成与原图像一样大的0矩阵

mask[num1:num2, num3:num4] = 255                  #将目标部分设为白色

masked_img = cv2.bitwise_and(img, img, mask=mask)         #与操作,将掩码图像与原图像结合在一起

hisSize——BIN的数目,亦用中括号[]括起来;

ranges——像素值范围常为0~256,亦用中括号[]括起来;

 

直方图均衡化

 

cv2.equalizeHist(输入图像)

 

自适应直方图均衡化

clahe = cv2.createCLAHE(clipLimit=num1, titleGridSize=(num2,num3))  #实例化自适应直方图均衡化函数

注:clipLimit指颜色对比度的阈值;titleGridSize指将原图像分为num2*num3大小的网格进行均衡化操作

变量 = clahe.apply(输入图像)         #进行自适应直方图均衡化

 

  1. 图像特征——harris角点检测

角点——某块区域的像素点在X、Y轴方向上滑动,其像素值变化很快;

cv2.corerHarris(img, blockSize, ksize, k)

其中:img ——数据类型为float32的输入图像;

 blockSize ——角点检测中指定区域的大小;

 ksize ——Sobel求导中使用的窗口大小;

 k ——取值参数为[0.04,0.06]

 

  1. Scale Invariant Feature Transform(SIFT)   ???  ——一种特征匹配算法    

sift = cv2.xfeatures2d.SIFT_create()    #sift实例化

kp = sift.detect(输入灰度图像, None)     #得到关键点

img = cv2.drawKeypoints(输入灰度图像, kp, 输入原始图像)