opencv 图像处理

255代表白色 0代表黑色

基本语法

def read_demo():
  image = cv.imread('C:/Users/Administrator/Pictures/Camera Roll/1.jpg')
  cv.imshow('input',image)
  cv.waitKey(0)
  cv.destroyAllWindows()

图像色彩 (滤镜)

def color_space_demo():
    '''图像色彩'''
    image = cv.imread('D:/tupian/2.jpg') #BGR,0-255
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    hsv = cv.cvtColor(image,cv.COLOR_HSV2RGB)  # H, 0-180
    cv.imshow('gray', gray)
    cv.imshow('hsv', hsv)
    cv.waitKey(0)
    # cv.namedWindow('input', cv.WINDOW_AUTOSIZE)
    cv.destroyAllWindows()

结果如下

图像对象的创建与复制

def mat_demo():
    '''图像对象的创建与复制'''
    # image = cv.imread('D:/tupian/2.jpg',cv.IMREAD_GRAYSCALE) #灰度色彩,没有 C
    image = cv.imread('D:/tupian/2.jpg')
    # print(image)
    print(image.shape) # (1024, 681, 3)   H  W  C:代表通道
    roi = image[100:200,100:200,:]
    blank = np.zeros_like(image)  #创建空白图像
    blank[1:300, 100:300, 1:20] = image[1:300,100:300,1:20] # copy一部分image图像到空白图像blank上

    #或者用zero
    # h,w,c = image.shape
    # blank = np.zeros((h,w,c),dtype=np.uint8)
    # blank[1:300, 100:300, 1:20] = image[1:300, 100:300, 1:20]  # copy一部分到空白图像
    blank = np.copy(image)  #全copy

    cv.imshow('image', image)
    cv.imshow('blank', blank)
    # cv.imshow('roi', roi)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

对图像像素取反效果

def piexl_demo():
    '''对图像像素取反效果'''
    image = cv.imread('D:/tupian/2.jpg') #BGR,0-255
    cv.imshow('start',image)
    h,w,c = image.shape  # 1024 681 3
    print(image)
    print(image[1,1])
    for row in range(h):
        for col in range(w):
            b,g,r = image[row,col]
            image[row, col] = (255-b,255-g,255-r)  #像素取反效果
    cv.imshow('result',image)
    cv.imwrite('D:/tupian/2_bac.jpg',image)  # 保存在本地
    cv.waitKey(0)
    # cv.namedWindow('input', cv.WINDOW_AUTOSIZE)
    cv.destroyAllWindows()

结果如下

图像像素的算法操作 add subtract divide multiply

def math_demo():
    '''图像像素的算法操作'''
    image = cv.imread('D:/tupian/2.jpg') #BGR,0-255
    blank = np.zeros_like(image) # 创建一个黑色的空白图像
    print(cv.imshow('1', blank))

    #255代表白色   0代表黑色
    blank[:,:] = (2,2,2) #相当于 copy了一下空白图像,设置了其他颜色
    result= cv.add(image,blank) # 加   这个result的像素对比image原图,像素更亮
    result= cv.subtract(image,blank) #减 将原来的像素做减法  这个result的像素对比image原图,像素更暗
    result1= cv.divide(image,blank) #除法  这个result的像素对比image原图,像素暗2倍
    result1= cv.multiply(image,blank) # 乘法  这个result的像素对比image原图,像素亮2倍

    cv.imshow('blank',blank)
    cv.imshow('image',image)
    cv.imshow('result',result)
    cv.imwrite('D:/tupian/2_bac.jpg',image)  # 保存在本地
    cv.waitKey(0)
    # cv.namedWindow('input', cv.WINDOW_AUTOSIZE)  #根据图像大小调整窗口大小
    cv.destroyAllWindows()

结果如下

TrackBar滚轮条操作调整图像亮度

def nothing(x):
    print(x)
def adjust_lightness_demo():
    image = cv.imread('D:/tupian/2.jpg')
    cv.namedWindow('start',cv.WINDOW_AUTOSIZE) #根据图像调整窗口大小
    cv.createTrackbar('lightness','start',0,100,nothing)  #通过滑块修改亮度
    cv.imshow('start',image)
    blank = np.zeros_like(image)
    while True:
        pos = cv.getTrackbarPos('lightness','start')
        blank[:,:] = (pos,pos,pos)
        result = cv.add(image,blank)
        cv.imshow('result',result)
        c = cv.waitKey(1)
        if c==27:
            break

    cv.destroyAllWindows()

结果如下

TrackBar滚动条同时调整亮度跟对比度

def nothing(x):
  print(x)
def adjust_contrast_demo():
    image = cv.imread('D:/tupian/2.jpg')
    cv.namedWindow('start',cv.WINDOW_AUTOSIZE) #根据图像调整窗口大小
    cv.createTrackbar('lightness','start',0,100,nothing)  #通过滑块修改亮度
    cv.createTrackbar('contrast','start',0,100,nothing)  #通过滑块修改对比度
    cv.imshow('start',image)
    blank = np.zeros_like(image)
    while True:
        light = cv.getTrackbarPos('lightness','start')
        contrast = cv.getTrackbarPos('contrast','start')/100
        # blank[:,:] = (pos,pos,pos)
        print('ll:',light,'co',contrast,'bl',blank,'im',image)
        result = cv.addWeighted(image,contrast,blank,0.5,light)
        cv.imshow('result',result)
        c = cv.waitKey(1)
        if c==27:
            break

    cv.destroyAllWindows()

结果如下

键盘操作像素

def key_demo():
    image = cv.imread('D:/tupian/2.jpg')
    cv.namedWindow('start',cv.WINDOW_AUTOSIZE)
    cv.imshow('start',image)
    while True:
        c = cv.waitKey(1)
        if c ==49: #代表按键盘数字 1
            gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
            cv.imshow('result',gray)
        if c ==50: # 2
            hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV)
            cv.imshow('result', hsv)
        if c ==51: # 3
            invert = cv.bitwise_not(image)  #像素取反
            cv.imshow('result', invert)
        if  c ==27:  #退出
            break
    cv.destroyAllWindows()

opencv 自带颜色表 applyColorMap

例子:

def color_table_demo():
    colormap = [
        cv.COLORMAP_AUTUMN,
        cv.COLORMAP_CIVIDIS,
        cv.COLORMAP_COOL,
        cv.COLORMAP_PARULA,
        cv.COLORMAP_HOT,
        cv.COLORMAP_BONE,
    ]
    image = cv.imread('D:/tupian/2.jpg')
    cv.namedWindow('start',cv.WINDOW_AUTOSIZE)
    cv.imshow('start',image)
    index = 0
    while True:
        dst = cv.applyColorMap(image,colormap[index%6])  #列表里有几个就% 几
        index += 1
        cv.imshow('color style',dst)
        c = cv.waitKey(400)
        if  c ==27:  #退出
            break
    cv.destroyAllWindows()

图像像素的逻辑操作 bitwise_and bitwise_or bitwise_not

def bitwise_demo():
    b1 = np.zeros((400,400,3),dtype=np.uint8)
    b1[:,:] = (255,0,255)
    b2 = np.zeros((400, 400, 3), dtype=np.uint8)
    b2[:, :] = (0, 255, 255)
    cv.imshow('b1',b1)
    cv.imshow('b2',b2)

    dst1 = cv.bitwise_and(b1,b2)
    dst2 = cv.bitwise_or(b1,b2)
    cv.imshow('bitwise_and',dst1)
    cv.imshow('bitwise_or',dst2)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

通道分离与合并 merge

def channels_split_demo():
    image = cv.imread('D:/tupian/2.jpg')
    cv.imshow('b',image)
    cv.imshow('im',image[:,:,1])
    mv = cv.split(image)
    mv[2][:,:] = 25
    result = cv.merge(mv)
  
    dst = np.zeros(image.shape,dtype=np.uint8)
    cv.mixChannels([image],[dst],fromTo=[2,0,1,1,0,2]) #转换通道
    cv.imshow('dst',dst)
    cv.imshow('re',result)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

图像色彩空间转换 inRange

def color_space_demo1():
    #将图像先转成hsv,在bitwise_not 进行取反,
    image = cv.imread('D:/tupian/3.jpg')
    cv.imshow('image',image)
    hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV)
    cv.imshow('hsv',hsv)
    #RGB与HSV色彩空间转换,颜色inRange 生成mask轮廓提取与最大面积过滤
    mask = cv.inRange(hsv,(35,43,46),(77,255,255))  #,过滤掉绿色,把人物抠出来
    cv.imshow('mask', mask)
    cv.bitwise_not(mask,mask) #  进行取反
    result = cv.bitwise_and(image,image,mask=mask)
    cv.imshow('re',result)

    cv.waitKey(0)
    cv.destroyAllWindows()


结果如下

图像像素值统计 meanStdDev

def pixel_stat_demo1():
    image = cv.imread('D:/tupian/2.jpg')
    cv.imshow('start',image)
    max = np.max(image[:,:,2]) #计算第3通道的最大值   255
    min = np.min(image[:,:,1])  #计算第2通道的最小值 0
    means,dev = cv.meanStdDev(image)  #统计均值和方差
    print( 'mean',means,'dev',dev)
    print(cv.meanStdDev(image)[0])
    cv.waitKey(0)
    cv.destroyAllWindows()

图像几何形状绘制 rectangle circle line

def drawing_demo():
    b1 = np.zeros((512,512,3),dtype=np.uint8)
    cv.rectangle(b1,(50,50),(400,400),(0,255,0),-1,4,0) #制作矩形 (图像,左上点,右下点,颜色,线的厚度, lineType=4 或者 8,shift点坐标中的小数位数)    )
    cv.circle(b1,(200,200),100,(255,0,255),4,2,0)  #制作圆
    cv.line(b1,(50,50),(400,400),(255,0,0),4,8,0)  #制作线
    cv.imshow('input',b1)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

绘制人脸

def drawing_demo():
    # b1 = np.zeros((512,512,3),dtype=np.uint8)
    b1 = cv.imread('D:/tupian/2.jpg')
    cv.rectangle(b1,(200,200),(500,500),(0,255,0),8,4,0) #制作矩形 (图像,左上点,右下点,颜色,线的厚度, lineType=4 或者 8,shift点坐标中的小数位数)    )
    # putText(img,name,name的位置,字体,字体大小,字体颜色,线的厚度,lineType,)
    cv.putText(b1,'99% face',(100,150),cv.FONT_HERSHEY_SIMPLEX,1.0,(255,0,255),2,8)
    cv.imshow('input',b1)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

随机数与随机颜色 np.random.randint

def random_color_demo():
    b1 = np.zeros((512,512,3),dtype=np.uint8)
    while True:
        xx = np.random.randint(0,512,2,dtype=np.int) #0-512之间随机取两个数
        yy = np.random.randint(0,512,2,dtype=np.int)
        bgr = np.random.randint(0,255,3,dtype=np.int32)
        cv.line(b1,(xx[0],yy[0]),(xx[1],yy[1]),(np.int(bgr[0]),np.int(bgr[1]),np.int(bgr[2])),1,4,0)
        cv.imshow('start',b1)
        c = cv.waitKey(100)
        if c==27:
            break
    cv.destroyAllWindows()

结果如下

多边形填充与绘制 drawContours

def polyline_drawing_demo():
    canvas = np.zeros((512,512,3),dtype=np.uint8)
    pts = np.array([[100,100],[200,350],[50,300],[100,300]],dtype=np.int)
    pts1 = np.array([[100,10],[100,350],[100,30],[500,300]],dtype=np.int)
    # cv.polylines(canvas,[pts],True,(0,255,255),2,4,0) #只能绘制多边形
    # cv.fillPoly(canvas,[pts],(0,255,255),8,0)  #只能填充多边形

    #[pts] 代表可以填充多个轮廓
    cv.drawContours(canvas,[pts,pts1],-1,(255,0,255),-1,)  #填充&绘制多边形,最后一个-1 代表thinkness线的厚度,>0代表填充
    cv.imshow('polyline',canvas)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

鼠标的操作

例: 使用鼠标框人头

# b1 = np.zeros((500,500,3),dtype=np.uint8)
b1 = cv.imread('D:/tupian/2.jpg')
img = np.copy(b1)
x1 = -1
x2 = -1
y1 = -1
y2 = -1
def mouse_drawing(event,x,y,flags,param):
    """回调函数"""
    global x1,y1,x2,y2
    if event==cv.EVENT_FLAG_LBUTTON:  #鼠标按下
        x1 = x
        y1 = y
    if event == cv.EVENT_MOUSEMOVE:#鼠标移动
        if x1<0 or y1<0:
            return
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            b1[:,:,:] = img[:,:,:]
            cv.rectangle(b1,(x1,y1),(x2,y2),(0,255,255),2,8,0)

    if event == cv.EVENT_LBUTTONUP:#鼠标松开
        x2 = x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 and dy > 0:
            b1[:, :,:] = img[:,:,:]
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 255, 255), 2, 8, 0)

        x1 = -1
        x2 = -1
        y1 = -1
        y2 = -1
def mouse__demo():
    cv.namedWindow('mouse_demo',cv.WINDOW_AUTOSIZE)
    cv.setMouseCallback('mouse_demo',mouse_drawing)
    while True:
        cv.imshow('mouse_demo',b1)
        c = cv.waitKey(10)
        if c==27:
            break
    cv.destroyAllWindows()

结果如下

图像像素类型转换与归一化

def norm_demo():
    img = cv.imread('D:/tupian/2.jpg')
    cv.namedWindow('norm_demo',cv.WINDOW_AUTOSIZE)
    result = np.zeros_like(np.float32(img))
    cv.normalize(np.float32(img),result,0,1,cv.NORM_MINMAX,dtype=cv.CV_32F)
    cv.imshow('norm_demo',np.uint8(result*255))
    cv.waitKey(0)
    cv.destroyAllWindows()

图像放缩与插值 resize

def resize_demo():
    img = cv.imread('D:/tupian/2.jpg')
    h,w,c = img.shape
    # .resize(src,dst,Size(),0.5,0.5,插值)
    # dst = cv.resize(img,(h//2,w//2),interpolation=cv.INTER_AREA)
    # dst = cv.resize(img,(h*2,w*2),interpolation=cv.INTER_NEAREST)
    dst = cv.resize(img,(0,0),fx=0.75,fy=0.75,interpolation=cv.INTER_NEAREST)
    cv.imshow('resize_demo',dst)
    cv.imshow('img',img)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果就是 可以调整图片大小

图像翻转

def flip_demo():
    img = cv.imread('D:/tupian/2.jpg')
    cv.imshow('img', img)
    # cv.namedWindow('input',cv.WINDOW_AUTOSIZE)
    dst = cv.flip(img,1)  # 翻转 0,1,-1 三个值
    cv.imshow('flip',dst)

    cv.waitKey(0)
    cv.destroyAllWindows()

图像旋转

教程链接: https://mp.weixin.qq.com/s/K4P8151BuM4DQPSK-KzPFQ
例1:使用自定义的M矩阵实现图像旋转

def rotate_demo():
    src = cv.imread('D:/tupian/2.jpg')
    cv.imshow('start',src)
    h, w, c = src.shape
    # 定义矩阵
    M = np.zeros((2, 3), dtype=np.float32)
    # 定义角度
    alpha = np.cos(np.pi / 4.0)
    beta = np.sin(np.pi / 4.0)
    print("alpha : ", alpha)
    # 初始化矩阵
    M[0, 0] = alpha
    M[1, 1] = alpha
    M[0, 1] = beta
    M[1, 0] = -beta
    cx = w / 2
    cy = h / 2
    tx = (1 - alpha) * cx - beta * cy
    ty = beta * cx + (1 - alpha) * cy
    M[0, 2] = tx
    M[1, 2] = ty
    # 执行旋转
    dst = cv.warpAffine(src, M, (w, h))
    cv.imshow("rotate-center-demo", dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

例2 :重新计算旋转之后的图像大小,实现无Crop版本的图像旋转

def rotate_demo():
    src = cv.imread('D:/tupian/2.jpg')
    h, w, c = src.shape
    M = np.zeros((2, 3), dtype=np.float32)
    alpha = np.cos(np.pi / 4.0)
    beta = np.sin(np.pi / 4.0)
    print("alpha : ", alpha)

    # 初始旋转矩阵
    M[0, 0] = alpha
    M[1, 1] = alpha
    M[0, 1] = beta
    M[1, 0] = -beta
    cx = w / 2
    cy = h / 2
    tx = (1 - alpha) * cx - beta * cy
    ty = beta * cx + (1 - alpha) * cy
    M[0, 2] = tx
    M[1, 2] = ty

    # change with full size
    bound_w = int(h * np.abs(beta) + w * np.abs(alpha))
    bound_h = int(h * np.abs(alpha) + w * np.abs(beta))

    # 添加中心位置迁移
    M[0, 2] += bound_w / 2 - cx
    M[1, 2] += bound_h / 2 - cy
    dst = cv.warpAffine(src, M, (bound_w, bound_h))
    cv.imshow("rotate ", src)
    cv.imshow("rotate without cropping", dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

例3: 背景随便变化+无Crop版本的图像旋转动态演示

def rotate_demo():
    src = cv.imread('D:/tupian/2.jpg')
    h, w, c = src.shape
    M = np.zeros((2, 3), dtype=np.float32)
    degree = 1.0
    d1 = np.pi / 180.0
    while True:
        alpha = np.cos(d1 * degree)
        beta = np.sin(d1 * degree)
        M[0, 0] = alpha
        M[1, 1] = alpha
        M[0, 1] = beta
        M[1, 0] = -beta
        cx = w / 2
        cy = h / 2
        tx = (1 - alpha) * cx - beta * cy
        ty = beta * cx + (1 - alpha) * cy
        M[0, 2] = tx
        M[1, 2] = ty

        # change with full size
        bound_w = int(h * np.abs(beta) + w * np.abs(alpha))
        bound_h = int(h * np.abs(alpha) + w * np.abs(beta))
        M[0, 2] += bound_w / 2 - cx
        M[1, 2] += bound_h / 2 - cy
        red = np.random.randint(0, 255)
        green = np.random.randint(0, 255)
        blue = np.random.randint(0, 255)
        dst = cv.warpAffine(src, M, (bound_w, bound_h), borderMode=cv.BORDER_CONSTANT, borderValue=(blue, green, red))
        cv.imshow("rotate+background", dst)
        c = cv.waitKey(1000)
        if c == 27:
            break
        degree += 1
        print("degree", degree)
        if degree > 360:
            degree = degree % 360


    cv.imshow("rotate ", src)
    cv.imshow("rotate without cropping", dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

视频文件& 摄像头使用 VideoCapture

def cideo_demo():
    # cap = cv.VideoCapture(0)  # 摄像头
    cap = cv.VideoCapture('D:/s19day77/1.mp4')  #读取视频文件
    print(cap)
    while True:
        ret,frame = cap.read()
        # frame = cv.flip(frame,1)
        if ret is not True:
            break
        cv.imshow('frame',frame)
        c = cv.waitKey(100)
        if c ==27:
            break
    cv.destroyAllWindows()

视频处理与保存

def cideo_demo():
    # cap = cv.VideoCapture(0)  # 摄像头
    cap = cv.VideoCapture('D:/s19day77/1.mp4')  #读取视频文件
    w = cap.get(cv.CAP_PROP_FRAME_WIDTH)
    h = cap.get(cv.CAP_PROP_FRAME_HEIGHT)
    fps = cap.get(cv.CAP_PROP_FPS)  #1s播放9.900349765722959张图像
    print(w,h,fps) #1360.0 768.0 9.900349765722959
    # cv.VideoWriter.fourcc('P', 'I', 'M', '1')  代表编码,去官网兆对应的
    # out = cv.VideoWriter('D:/test.mp4',cv.VideoWriter.fourcc('P','I','M','1'),fps,(np.int(w),np.int(h)),True)
    # 或者可以写成通用的
    out = cv.VideoWriter('D:/test.mp4',cv.CAP_ANY,np.int(cap.get(cv.CAP_PROP_FOURCC)),fps,(np.int(w),np.int(h)),True)
    while True:
        ret,frame = cap.read()
        # frame = cv.flip(frame,1)
        if ret is not True:
            break
        cv.imshow('frame',frame)
        hsv = cv.cvtColor(frame,cv.COLOR_BGR2HSV) #将视频像素转成hsv的
        cv.imshow('hsv', hsv)
        out.write(hsv)   #保存录像
        c = cv.waitKey(100)
        if c ==27:
            break
    cv.destroyAllWindows()
    out.release()
    cap.release()

图像直方图 calcHist

import matplotlip.pyplot as plt
def image_hist():
    img = cv.imread('D:/tupian/2.jpg')
    cv.imshow('input',img)
    color = ('blue','red','green')
    for i,color in enumerate(color):
        hist = cv.calcHist(img,[i],None,[32],[0,256])
        print(hist)
        plt.plot(hist,color=color)
        plt.xlim([0,256])
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

二维直方图

from matplotlib import pyplot as plt
def hist2d_demo():
    img = cv.imread('D:/tupian/2.jpg')
    hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV) # 将像素转成hsv
    hist = cv.calcHist(hsv,[0,1],None,[48,48],[0,180,0,256])
    dst = cv.resize(hist,(400,400))
    cv.normalize(dst,dst,0,255,cv.NORM_MINMAX) #归一
    cv.imshow('img',img)
    dst = cv.applyColorMap(np.uint8(dst),cv.COLORMAP_JET)
    cv.imshow('dst', dst)
    plt.imshow(hist,interpoltion='nearest')
    plt.title('2D Histogram')
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

直方图均衡化 equalizeHist

def eqhist_demo():
    img = cv.imread('D:/tupian/2.jpg',cv.IMREAD_GRAYSCALE) #将图片转成灰度
    cv.imshow('input',img)
    result = cv.equalizeHist(img)
    cv.imshow('result',result)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

图像卷积操作 (模糊操作) blur

def conv_demo():
    img = cv.imread('D:/tupian/2.jpg')
    cv.imshow('input',img)
    result = cv.blur(img,(15,15))
    cv.imshow('result', result)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果如下

高斯模糊 GaussianBlur

def conv1_demo():
  img = cv.imread('D:/tupian/2.jpg')
  cv.imshow('input', img)
  result = cv.GaussianBlur(img,(7,7),15) #ksize 必须是奇数
  cv.imshow('result', result)
  cv.waitKey(0)
  cv.destroyAllWindows()

高斯双边模糊 bilateralFilter

def bifilter_demo():
  img = cv.imread('D:/tupian/01.JPG')
  cv.imshow('input', img)
  result = cv.bilateralFilter(img,0,100,10)
  cv.imshow('result', result)
  cv.waitKey(0)
  cv.destroyAllWindows()

posted on 2022-11-12 13:59  xm微微一笑  阅读(62)  评论(0编辑  收藏  举报

导航