openCV笔记

openCV


目录

  1. 图像读取和展示

  2. 读取展示视频

  3. 保留一个通道颜色

  4. 图像填充

  5. 图像合并

  6. 图像阈值显示

  7. 滤波函数

  8. 腐蚀和膨胀

  9. 梯度计算

  10. Canny边缘检测

  11. 高斯金字塔

  12. 轮廓检测

  13. 模板匹配

  14. 直方图

  15. 光流估计


    1.图像读取和展示

img_path = "C:\\Users\\User\\Desktop\\1.jpg" //图片的路径中不要有中文包括图片名称
img = cv2.imread(img_path) #imread读进去是BGR模式
print(img) 		# 如果直接print图片的话会得到一个三维数组
cv2.imshow("imag",img)	# 引号中是展示窗口的名字
cv2.waitKey(0)		# 等待敲击键盘来继续
cv2.destroyAllWindows()	# 销毁所有窗口
cv2.imwrite('11.png',img) # 图像保存到本地

2.读取展示视频

vc=cv2.VideoCapture("guidao.mp3")
if vc.isOpened():
    open,frame=vc.read()
else:
    open=False
while open:
    ret,frame=vc.read()
    if frame is None:
        break
    if ret:
        gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
        cv2.imshow('result',gray)
        if cv2.waitKey(100)&0xFF==27:	//等多少秒播放下一帧
            break
vc.release()
cv2.destroyAllWindows()

3.保留一个通道颜色

cur_img=img.copy()	# imread进来是BGR
cur_img[:,:,0]=0 # B通道为0
cur_img[:,:,1]=0 # G通道为0
cv_show(cur_img) # 此时保留的R通道(红色)

在这里插入图片描述


4.图像填充

def img_fill(img):
    top_size,bottom_size,left_size,right_size=(100,100,100,100)
    # 复制拉伸边缘
    replicate=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE)
    # 镜面反射
    reflect=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT)
    # 去掉一点头的镜面反射
    reflect_101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
    # 复制整个图片取其中一部分
    wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
    # 常数填充
    constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_CONSTANT,value=0)
    # 0是黑色填充 

    plt.subplot(231), plt.imshow(img,'gray'),plt.title('original')
    plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('replicate')
    plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('reflect')
    plt.subplot(234), plt.imshow(reflect_101, 'gray'), plt.title('reflect_101')
    plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('wrap')
    plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('cosntant')

    plt.show()

填充效果


5.图像合并

def img_merge(img_yue,img_zhu):
    img_zhu = cv2.imread('C:\\Users\\User\\Desktop\\zhu1.jpg')
    img_yue = cv2.imread('C:\\Users\\User\\Desktop\\yueyue.jpg')
    print(img_zhu.shape) # 不同大小的图像不能合并
    print(img_yue.shape) # 打印出两个图片大小
    
    img_yue=cv2.resize(img_yue,(499,428)) # 转化其中的一个大小,裁剪像素
    img_yue=cv2.resize(img_yue,(0,0),fx=0.3,fy=0.3) # 按比例缩放
    
    print(img_yue.shape)
    res=cv2.addWeighted(img_zhu,0.4,img_yue,0.6,5) # 两个数字为比重
    plt.imshow(res)
    cv_show(res)

在这里插入图片描述


6.图像阈值显示

img_path = "C:\\Users\\User\\Desktop\\1.jpg"
img = cv2.imread(img_path,cv2.IMREAD_GRAYSCALE) # 将图像转化成灰度
def img_thresh(img_yue): # 阈值显示必须是灰度图像
    # 0-1函数
    ret,thresh1=cv2.threshold(img_yue,127,255,cv2.THRESH_BINARY)
    # 0-1反转函数
    ret,thresh2 = cv2.threshold(img_yue, 127, 255, cv2.THRESH_BINARY_INV)
    # 大于阈值设为阈值,否则不变
    ret,thresh3 = cv2.threshold(img_yue, 127, 255, cv2.THRESH_TRUNC)
    # 大于阈值不变,否则设为0
    ret,thresh4 = cv2.threshold(img_yue, 127, 255, cv2.THRESH_TOZERO)
    # TOZERO反转
    ret,thresh5 = cv2.threshold(img_yue, 127, 255, cv2.THRESH_TOZERO_INV)

    titles = ['Original ','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
    images = [img_yue,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()

在这里插入图片描述


7.滤波函数

def img_blur(img):
    # 均值滤波
    # blur=cv2.blur(img,(3,3))

    # 方框滤波
    blur=cv2.boxFilter(img,-1,(3,3),normalize=True)
    # normalize为True时与均值滤波相同,为False时容易越界,全取255

    # 高斯滤波:离中心近的权重大
    gaussian = cv2.GaussianBlur(img, (5, 5), 1)

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

    # 集合展示
    res = np.hstack((blur, gaussian, median))
    cv_show(res)
在这里插入图片描述

8.腐蚀和膨胀

腐蚀和膨胀(相对于二色图来说)————腐蚀:黑的变多,膨胀:白的变多

def img_fushi(img):
    kernel=np.ones((5,5),np.uint8)
    erosion_1=cv2.erode(img,kernel,iterations=1)
    erosion_2 = cv2.erode(img, kernel, iterations=2)
    erosion_3 = cv2.erode(img, kernel, iterations=3)
    res=np.hstack((img,erosion_1,erosion_2,erosion_3))
    cv_show(res)
    
def img_pengzhang(img):
    kernel=np.ones((5,5),np.uint8)
    dilate_1=cv2.dilate(img,kernel,iterations=1)
    dilate_2 = cv2.dilate(img, kernel, iterations=2)
    dilate_3 = cv2.dilate(img, kernel, iterations=3)
    res=np.hstack((img,dilate_1,dilate_2,dilate_3))
    cv_show(res)

腐蚀
膨胀


9.梯度计算

Sobel算法,Scharr算法,Laplacian算法

def gradient(img):
    sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=1)  
    # 对水平方向进行梯度计算
    sobelx=cv2.convertScaleAbs(sobelx)  
    # 左右边界值有正有负检测效果不同,所以取绝对值
    sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=1)
    sobely = cv2.convertScaleAbs(sobely)
    sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)# x,y等比例相加

    scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)  
    # 对水平方向进行梯度计算
    scharrx=cv2.convertScaleAbs(scharrx)  
    # 左右边界值有正有负检测效果不同,所以取绝对值
    scharrx = cv2.Scharr(img, cv2.CV_64F, 0, 1)
    scharrx = cv2.convertScaleAbs(scharrx)
    scharrxy=cv2.addWeighted(scharrx,0.5,scharrx,0.5,0)# x,y等比例相加

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

    res=np.hstack((img,sobelxy,scharrxy,laplacian))
    cv_show(res)

在这里插入图片描述


10.Canny边缘检测

  1. 使用高斯滤波器 来平滑图像滤除噪声

  2. 计算图像中每个像素的梯度强度和方向

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

  4. 应用双阈值检测来确定真实的和潜在的边缘

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

def canny(img):
   img=cv2.imread(img_path+'lena.jpg',cv2.IMREAD_GRAYSCALE)
   v1=cv2.Canny(img,80,150)
   # 80是minvalue,小于80的不算边界
   # 150是maxvalue,大于150的算边界
   # 在80-150之间的如果与边界相连才算边界
   v2=cv2.Canny(img,50,100)
   # v2的检测阈值较小,所以将有更多的边界能被检测到,但也可能噪声过多
   res=np.hstack((v1,v2))
   cv_show(res)

在这里插入图片描述


11.高斯金字塔
高斯金字塔,拉普拉斯金字塔:对图像放大缩小

def up_down(img):
    # Gauss
    # 放大时候填充0然后高斯模糊,缩小直接高斯模糊
    print(img.shape)
    up=cv2.pyrUp(img)
    print(up.shape)
    down=cv2.pyrDown(img)
    print(down.shape)
    updown=cv2.pyrDown(up)

    # Laplace
    # 公式:Li=Gi-PyrUp(PyrDown(Gi))
    laplace=img-updown

    res=np.hstack((img,updown,laplace))
    cv_show(res)

在这里插入图片描述


12.轮廓检测

def contours(img):
    img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,thresh=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)

    contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    # mode(轮廓检索模式):RETER_TREE:检索所有的轮廓,并重构轮廓的层次
    # method(轮廓逼近模式): CHAIN_APPROX_NONE:以Freeman链码方式输出轮廓,其他所有方法输出多边形
    # CHAIN_APPROX_SIMPLE:压缩水平的,垂直的和斜的部分,只保留终点部分

    # 绘制轮廓
    draw_img=img.copy()
    new_img=cv2.drawContours(draw_img,contours,-1,(255,255,0),2)
    # 此时要传入拷贝图像,否则会覆盖原始图像。
    # -1指第几条轮廓(-1是全部轮廓)。(0,0,255)是轮廓线条的颜色。2是线条的宽度
    res=np.hstack((img,new_img))
    # cv_show(res)

    # 轮廓特征(面积,周长)
    cnt=contours[0]
    print(cv2.contourArea(cnt)) # 面积
    print(cv2.arcLength(cnt,True)) # 周长,True表示闭合的

    # 轮廓近似
    epsilon = 0.001*cv2.arcLength(cnt,True)
    approx = cv2.approxPolyDP(cnt,epsilon,True)
    draw_img1 = img_gray.copy()
    new_img1 = cv2.drawContours(draw_img1, [approx], -1, (0, 255, 0), 3)
    cv_show(new_img1)

在这里插入图片描述


13.模板匹配

def template(img):
    img_template = cv2.imread(img_path+'face.png')
    methods=['cv2.TM_CCOEFF','cv2.TM_CCOEFF_NORMED','cv2.TM_CCORR',
    'cv2.TM_CCORR_NORMED','cv2.TM_SQDIFF','cv2.TM_SQDIFF_NORMED']
    h,w=img_template.shape[:2]

    for meth in methods:
        img2=img.copy()

        #   匹配方法的真值
        method=eval(meth)
        print(method)
        res=cv2.matchTemplate(img,img_template,method)
        min_val,max_val,min_pos,max_pos=cv2.minMaxLoc(res)

        # 如果是平方差匹配TM_SQDIFF或其归一化则取最小值
        if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
            top_left=min_pos
        else:
            top_left=max_pos
        bottom_right=(top_left[0]+w,top_left[1]+h)

        # 画矩形
        cv2.rectangle(img2,top_left,bottom_right,255,2)

        plt.subplot(121),plt.imshow(res)
        plt.xticks([]),plt.yticks([]) # 隐藏坐标轴
        plt.subplot(122),plt.imshow(img2)
        plt.suptitle(meth)
        plt.show()

在这里插入图片描述


14.直方图

def calchist(img):
   hist=cv2.calcHist([img],[0],None,[256],[0,256])
   plt.hist(img.ravel(),256)
   plt.show()

   color=('b','g','r')
   for i,col in enumerate(color):
       histr=cv2.calcHist([img],[i],None,[256],[0,256])
       plt.plot(histr,color=col)
       plt.xlim([0,256])
   plt.show()

   # 掩码
   mask=np.zeros(img.shape[:2],np.uint8)
   mask[100:300,100:300]=255
   masked_img=cv2.bitwise_and(img,img,mask=mask) # 与操作
   hist_full=cv2.calcHist([img],[0],None,[256],[0,256])
   hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])
   plt.subplot(221),plt.imshow(img,'gray')
   plt.subplot(222), plt.imshow(mask,'gray')
   plt.subplot(223), plt.imshow(masked_img,'gray')
   plt.subplot(224), plt.plot(hist_full),plt.plot(hist_mask)
   plt.xlim([0,256])
   plt.show()

   # 掩码均衡化
   img1 = cv2.imread(img_path+'lena.jpg',0)
   plt.hist(img.ravel(),256)
   plt.show()
   equ=cv2.equalizeHist(img1)
   plt.hist(equ.ravel(),256)
   plt.show()

   # 自适应均衡化处理:分成很多部分独立均衡化
   clahe=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
   res=clahe.apply(img1)
   cv_show(res)

在这里插入图片描述

在这里插入图片描述


15.光流估计

import numpy as np
import cv2

cap=cv2.VideoCapture('C:\\Users\\User\\Desktop\\test.avi')

# 角点检测所需的参数
feature_params=dict(maxCorners=100,
                    qualityLevel=0.3,
                    minDistance=7)

# lucas-kanade参数
lk_params=dict(winSize=(15,15),
               maxLevel=2)

# 随机颜色条
color=np.random.randint(0,255,(100,3))

# 拿到第一帧图像
ret,old_frame=cap.read()
old_gray=cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)
# 返回所有检测特征点,需要输入图像,角点最大数量(效率),品质因子(特征值越大的越好,以此筛选)
# 距离相当于这个区间有比这个角点强的就不要这个弱的了
p0=cv2.goodFeaturesToTrack(old_gray,mask=None, **feature_params)

# 创建一个mask
mask=np.zeros_like(old_frame)

while(True):
    ret ,frame=cap.read()
    frame_gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    # 需要传入前一帧和当前帧以及前一帧检测到的角点
    p1,st,err=cv2.calcOpticalFlowPyrLK(old_gray,frame_gray,p0,None,**lk_params)

    # st=1表示找到
    good_new=p1[st==1]
    good_old=p0[st==1]

    # 绘制轨迹
    for i,(new,old) in enumerate(zip(good_new,good_old)):
        a,b=new.ravel()
        c,d=old.ravel()
        mask=cv2.line(mask,(a,b),(c,d),color[i].tolist(),2)
        frame=cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
    img=cv2.add(frame,mask)

    cv2.imshow("frame",img)
    k=cv2.waitKey(150)&0xff
    if k==27:
        break

    # 更新
    old_gray=frame_gray.copy()
    p0=good_new.reshape(-1,1,2)

cv2.destroyAllWindows()
cap.release()

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值