opencv+python(一)

最近学一下传统的图像处理opencv库,理解一下底层源码的原理

一、读取图像

import cv2 as cv
def show(name,img):   # 为显示图像定义一个函数
    cv.imshow(name,img)
    cv.waitKey(0)  # 0表示按任意键退出,毫秒级,10表示显示10毫秒退出
    cv.destroyAllWindows()
img = cv.imread('car.jpg')  # 图像读取
print(img)
print(type(img)) # 类型
print(img.dtype)  # uint8
print(img.shape)
print(img.size)
img = cv.resize(img,(600,600))
show('car',img)
cv.imwrite('car2.jpg',img) # 保存图像

二、读取视频

import cv2
# 读取视频
vc = cv2.VideoCapture('soccer_01.mp4')
if vc.isOpened():
    open, frame = vc.read()    # 返回的两个值,open是布尔值(ture or false),frame是一帧一帧的图像
else:
    open = False
n = 0  # 计算帧数
while open:
    ret, frame = vc.read()
    if frame is None:    # 读完视频帧数就break
        break
    if ret == True:
        n = n+1
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)   # 转化成灰度值
        cv2.imshow('result',frame)
        if cv2.waitKey(5) & 0xFF == 27:
            break
print(n)
vc.release()  # 释放资源
cv2.destroyAllWindows()

三、ROI区域

# ROI区域(感兴趣区域)
img = cv2.imread('car.jpg')
b,g,r = cv2.split(img)  # 对图像进行切割
img = cv2.merge((b,g,r))  # 对图像进行整合
print(img.size)
print(img.shape)
img1 = img[50:500,50:500]   # 对图像进行索引切割
# cv2.imshow('car1',r)


current_img = img.copy()
current_img[:,:,0]=0     # 第三维度颜色通道0赋值为0
current_img[:,:,1]=0     # 第三维度颜色通道1赋值为0
cv2.imshow('11',current_img)    # opencv读取颜色通道顺序是BGR,所以只剩下R通道

cv2.waitKey(0)
cv2.destroyAllWindows()

四、边缘填充

# 边界填充
import matplotlib.pyplot as plt
img = cv2.imread('car.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img,(600,600))
top, bottom, left, right = (50,50,50,50)
replicate = cv2.copyMakeBorder(img, top, bottom, left, right, borderType=cv2.BORDER_REPLICATE)   # 复制法,复制最边缘像素
reflect = cv2.copyMakeBorder(img, top, bottom, left, right, borderType=cv2.BORDER_REFLECT)       # 反射法,对感兴趣的像素在两边进行复制  cba|abcdefgh|hgf
reflect101 = cv2.copyMakeBorder(img, top, bottom, left, right, borderType=cv2.BORDER_REFLECT_101)  # 反射法,也就是最边缘像素为轴  dcb|abcdefgh|gfe
wrap = cv2.copyMakeBorder(img, top, bottom, left, right, borderType=cv2.BORDER_WRAP)   # 外包装法 cdefgh|abcdefgh|abcde
constant = cv2.copyMakeBorder(img, top, bottom, left, right, borderType=cv2.BORDER_CONSTANT,value=0)  # 常量法,常数值填充
plt.subplot(236), plt.imshow(img), plt.title('ORIGINAL')
plt.subplot(231), plt.imshow(replicate,'gray'), plt.title('REPLICTAE')
plt.subplot(232), plt.imshow(reflect,'gray'), plt.title('REFLECT')
plt.subplot(233), plt.imshow(reflect101,'gray'), plt.title('REFLECT_101')
plt.subplot(234), plt.imshow(wrap,'gray'), plt.title('WRAP')
plt.subplot(235), plt.imshow(constant,'gray'), plt.title('CONSTANT')
plt.show()

# plt.subplot()函数解析
#plt.subplot(221)表示将整个图像窗口分为2行2列, 当前位置为1.
plt.subplot(221)

# plt.subplot(222)表示将整个图像窗口分为2行2列, 当前位置为2.
plt.subplot(222)   # 第一行的右图

# plt.subplot(223)表示将整个图像窗口分为2行2列, 当前位置为3.
plt.subplot(223)

# plt.subplot(224)表示将整个图像窗口分为2行2列, 当前位置为4.
plt.subplot(224)

五、数值计算、图像融合

# 数值计算、图像融合
img = cv2.imread('child.jpg')
img = cv2.resize(img,(301,400))
img1 = cv2.imread('cat.jpg')
print(img1.shape)
img2 = img + img1    # 直接相加,超过255会取余(例如294,则去38)
img3 = cv2.add(img,img1)  # 相加大于255都会取255
img4 = cv2.addWeighted(img, 0.6, img1, 0.6, 0)
print(img2[:,:5,0])
print(img3[:,:5,0])
print(img4[:,:5,0])
cv2.imshow('1',img)
cv2.imshow('2',img1)
cv2.imshow('3',img2)
cv2.imshow('4',img3)
cv2.imshow('5',img4)
cv2.waitKey(0)
cv2.destroyAllWindows()

六、图像阈值(二值化处理)

# 图像阈值
# ret, dst = cv2.threshold(src, thresh, maxval, type)
import matplotlib.pyplot as plt
img = cv2.imread('child.jpg')
img = cv2.resize(img,(301,400))
img1 = cv2.imread('cat.jpg')
ret, thresh1 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY)  # 超过阈值部分取maxval,否则取0
ret, thresh2 = cv2.threshold(img1, 127, 255, cv2.THRESH_BINARY_INV)  # BINARY的反转
ret, thresh3 = cv2.threshold(img1, 127, 255, cv2.THRESH_TRUNC)  # 大于阈值设为阈值,否则不变
ret, thresh4 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO)  # 大于阈值不变,否则为0
ret, thresh5 = cv2.threshold(img1, 127, 255, cv2.THRESH_TOZERO_INV)  #THRESH的反转
titles = ['original', 'binary', 'binary_inv', 'trunc', 'tozero', 'tozero_inv']
images = [img1,thresh1,thresh2,thresh3,thresh4,thresh5]
print(ret)   # 127.0
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()

七、图像平滑处理(四种滤波)

# 图像平滑处理
import numpy as np
img = cv2.imread('cat.jpg')
def add_sp_noise(img,sp_number):     # 添加椒盐噪声的函数
    new_image=img
    row,col,channel=img.shape#获取行列,通道信息
    s=int(sp_number*img.size/channel)#根据sp_number确定椒盐噪声
    #确定要扫椒盐的像素值
    change=np.concatenate((np.random.randint(0,row,size=(s,1)),np.random.randint(0,col,size=(s,1))),axis=1)
    for i in range(s):
        r=np.random.randint(0,2)#确定撒椒(0)还是盐(1)
        for j in range(channel):
            new_image[change[i,0],change[i,1],j]=r
    return new_image
im=img.copy()
im2=img.copy()
im3=img.copy()
im=add_sp_noise(im,0.05)
im2=add_sp_noise(im2,0.1)
im3=add_sp_noise(im3,0.3)
res = np.hstack((im,im2,im3))
cv2.imshow('0', res)
# 1、均值滤波
img1 = cv2.blur(im3, (3, 3))
# cv2.imshow('1', img1)
# 2、方框滤波
img2 = cv2.boxFilter(im3, -1, (3, 3), normalize = True)   # 当normalize取true时,该方法与均值滤波一致,取FALSE则超过255取255(不除以9)
# cv2.imshow('2',img2)
# 3、高斯滤波,满足高斯分布,权重分布不同
img3 = cv2.GaussianBlur(im3, (5,5), 1)
# cv2.imshow('3', img3)
# 4、中值滤波,取中间的值,更加平滑
img4 = cv2.medianBlur(im3, 5)   # 5是指5×5的卷积核大小
# cv2.imshow('4', img4)
res1 = np.hstack((img1,img2,img3,img4))    # 将图像拼接到一起
cv2.imshow('00', res1)
cv2.waitKey(0)
cv2.destroyAllWindows()

猜你喜欢

转载自blog.csdn.net/m0_61456316/article/details/129818997