基于python的openCV自学笔记(一)——读取、边界填充、阈值、平滑、形态学和梯度

大四毕业后的这个暑假正式开始学习openCV

参考教程:唐宇迪老师: https://www.bilibili.com/video/BV1tb4y1C7j7

1.数据读取-图像

cv2.IMREAD_COLOR 彩色图像

cv2.IMREAD_GRAYSCALE 灰色头像

demo1:

import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
print(img)

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)  #窗口名字叫image
#等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0) #随便一个键,窗口关闭
#cv2.waitKey(1000)  #显示1000ms,再关闭
cv2.destroyAllWindows() #触发关闭,所有窗口关闭

#写成一个函数
def cv2_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

print(img.shape)

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg',cv2.IMREAD_GRAYSCALE)   #读取灰度图
print(img)
print(img.shape)

cv2_show('image_gray',img)  #显示灰色图像

#保存
cv2.imwrite('D:\\openCV files\\data\\1\\mycat.png',img)

print(type(img))

print(img.size)#像素点的个数

print(img.dtype)

#截取部分图像数据
img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
cat = img[0:200,0:200]
cv2_show('cat',cat)

#颜色通道提取
b,g,r = cv2.split(img)
print(b)
print(b.shape)

#再把三个通道组合在一起
img = cv2.merge((b,g,r))
print(img.shape)

# 只保留R
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,1] = 0
cv2_show('R',cur_img)

# 只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv2_show('G',cur_img)

# 只保留B
cur_img = img.copy()
cur_img[:,:,1] = 0
cur_img[:,:,2] = 0
cv2_show('B',cur_img)

#边界填充
top_size,bottom_size,left_size,right_size = (50,50,50,50)  #上下左右填充的大小

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, borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=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(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236), plt.imshow(constant,'gray'),plt.title('CONSTANT')

plt.show()

out1:

[[[142 151 160]
  [146 155 164]
  [151 160 170]
  ...
  [156 172 185]
  [155 171 184]
  [154 170 183]]

 [[108 117 126]
  [112 123 131]
  [118 127 137]
  ...
  [155 171 184]
  [154 170 183]
  [153 169 182]]

 [[108 119 127]
  [110 123 131]
  [118 128 138]
  ...
  [156 169 183]
  [155 168 182]
  [154 167 181]]

 ...

 [[162 186 198]
  [157 181 193]
  [142 166 178]
  ...
  [181 204 206]
  [170 193 195]
  [149 172 174]]

 [[140 164 176]
  [147 171 183]
  [139 163 175]
  ...
  [169 187 188]
  [125 143 144]
  [106 124 125]]

 [[154 178 190]
  [154 178 190]
  [121 145 157]
  ...
  [183 198 200]
  [128 143 145]
  [127 142 144]]]
(414, 500, 3)
[[153 157 162 ... 174 173 172]
 [119 124 129 ... 173 172 171]
 [120 124 130 ... 172 171 170]
 ...
 [187 182 167 ... 202 191 170]
 [165 172 164 ... 185 141 122]
 [179 179 146 ... 197 142 141]]
(414, 500)
<class 'numpy.ndarray'>
207000
uint8
[[142 146 151 ... 156 155 154]
 [108 112 118 ... 155 154 153]
 [108 110 118 ... 156 155 154]
 ...
 [162 157 142 ... 181 170 149]
 [140 147 139 ... 169 125 106]
 [154 154 121 ... 183 128 127]]
(414, 500)
(414, 500, 3)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

BORDER_REPLICATE 复制法,也就是复制最边缘像素

BORDER_REFLECT 反射法,对感兴趣的图像中的像素在两边进行复制,例如fedcba|abcdefgh|hgfedcb

BORDER_REFLECT_101 反射法,也就是以最边缘像素为轴,对称 gfedcb|abcdefgh|gfedcba

BORDER_WRAP 外包装法 cdefgh|abcdefgh|abcdefg

BORDER_CONSTANT 常量法,常数值填充

2.数据读取-视频

cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1

如果是视频文件,直接制定好路径即可

demo2:

import cv2


vc = cv2.VideoCapture('D:\\openCV files\\data\\1\\test.mp4')

#检查是否打开正确
if vc.isOpened():
    open, frame = vc.read() #返回的open是布尔类型,frame是第一帧的图像数据
else:
    open = False

while open:
    ret,frame = vc.read()
    if frame is None:
        break
    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#每一帧图像转换为黑白图像
        cv2.imshow('result', gray)
        if cv2.waitKey(10) & 0xFF ==27:  #27指定退出键 ,waitKey()内数字越小,视频越快
            break
vc.release()
cv2.destroyAllWindows()

out2:
(一段以一定速度播放的黑白视频)
在这里插入图片描述
3.数值计算

demo3:

import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np

img_cat = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
img_dog = cv2.imread('D:\\openCV files\\data\\1\\dog.jpg')

img_cat2 = img_cat + 10 #每个像素点都加10
print(img_cat[:5,:,0])
print(img_cat2[:5,:,0])

#相当于 %256,取余
print((img_cat + img_cat2)[:5,:,0])

#大于255,则取255
print(cv2.add(img_cat,img_cat2)[:5,:,0])

#图像融合
print(img_cat.shape)
img_dog = cv2.resize(img_dog,(500,414))  #变成大小一样
print(img_dog.shape)
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0) #权重相加, R=ax+by+c,c指在亮度上微调
plt.imshow(res)
plt.show()#添加这一句才会持久显示

res = cv2.resize(img_cat, (0,0),fx=3, fy=1)  #x轴拉长为原来的三倍
plt.imshow(res)
plt.show()#添加这一句才会持久显示

out3:

[[142 146 151 ... 156 155 154]
 [108 112 118 ... 155 154 153]
 [108 110 118 ... 156 155 154]
 [139 141 148 ... 156 155 154]
 [153 156 163 ... 160 159 158]]
[[152 156 161 ... 166 165 164]
 [118 122 128 ... 165 164 163]
 [118 120 128 ... 166 165 164]
 [149 151 158 ... 166 165 164]
 [163 166 173 ... 170 169 168]]
[[ 38  46  56 ...  66  64  62]
 [226 234 246 ...  64  62  60]
 [226 230 246 ...  66  64  62]
 [ 32  36  50 ...  66  64  62]
 [ 60  66  80 ...  74  72  70]]
[[255 255 255 ... 255 255 255]
 [226 234 246 ... 255 255 255]
 [226 230 246 ... 255 255 255]
 [255 255 255 ... 255 255 255]
 [255 255 255 ... 255 255 255]]
(414, 500, 3)
(414, 500, 3)

在这里插入图片描述
在这里插入图片描述
4.图像阈值

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

src: 输入图,只能输入单通道图像,通常来说为灰度图
dst: 输出图
thresh: 阈值
maxval: 当像素超过了阈值(或者小于阈值,根据type来决定),所赋予的值
type:二值化操作的类型,包含以下5种类型:cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO; cv2.THRESH_TOZERO_INV

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的反转

demo4:

import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt

img = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg')
img_gray = cv2.imread('D:\\openCV files\\data\\1\\cat.jpg',cv2.IMREAD_GRAYSCALE)   #读取灰度图

ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'THRESH_TOZERO', 'THRESH_TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')  # gray 返回线性灰度色图
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()

在这里插入图片描述
5.图像平滑处理

demo5:

import cv2
import numpy as np

img = cv2.imread('D:\\openCV files\\data\\1\\lenaNoise.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

#均值滤波
#简单的平均卷积操作
blur = cv2.blur(img, (3,3))  #3×3的模板

cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

#方框滤波
#基本和均值一样,可以选择归一化
box = cv2.boxFilter(img, -1,(3,3), normalize=True)  #-1表示自动计算,颜色通道一致 ,True表示要归一化,跟均值滤波相同

cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()

#方框滤波
#基本和均值一样,可以选择归一化,容易越界,越界值全取255
box = cv2.boxFilter(img, -1,(3,3), normalize=False)  #-1表示自动计算,颜色通道一致 ,False不会除以9

cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()

#高斯滤波
#高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5,5), 1)

cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()

#中值滤波
#相当于用中值替代

median = cv2.medianBlur(img, 5)

cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()

#展示所有的
res = np.hstack((blur,aussian,median))  #三张图拼在一起,水平方向

cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

out5:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
6.形态学-腐蚀操作

demo6:

import cv2
import numpy as np

img = cv2.imread('D:\\openCV files\\data\\1\\dige.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

kernal = np.ones((5,5),np.uint8)  #核
erosion = cv2.erode(img, kernal, iterations = 1)  #iteration迭代次数

cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

pie = cv2.imread('D:\\openCV files\\data\\1\\pie.png')

cv2.imshow('pie', pie)
cv2.waitKey(0)
cv2.destroyAllWindows()

kernal = np.ones((30,30),np.uint8)  #核
erosion_1 = cv2.erode(pie, kernal, iterations = 1)  #iteration迭代次数
erosion_2 = cv2.erode(pie, kernal, iterations = 2)
erosion_3 = cv2.erode(pie, kernal, iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

out6:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
7.形态学-膨胀操作

demo7:

import cv2
import numpy as np

img = cv2.imread('D:\\openCV files\\data\\1\\dige.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

kernal = np.ones((3,3),np.uint8)  #核
dige_erosion = cv2.erode(img, kernal, iterations = 1)  #iteration迭代次数

cv2.imshow('erosion', dige_erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

kernal = np.ones((3,3),np.uint8)  #核
dige_dilate = cv2.dilate(dige_erosion, kernal, iterations = 1)  #iteration迭代次数

cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()

pie = cv2.imread('D:\\openCV files\\data\\1\\pie.png')

kernal = np.ones((30,30),np.uint8)  #核
dilate_1 = cv2.dilate(pie, kernal, iterations = 1)  #iteration迭代次数
dilate_2 = cv2.dilate(pie, kernal, iterations = 2)
dilate_3 = cv2.dilate(pie, kernal, iterations = 3)
res = np.hstack((dilate_1,dilate_2,dilate_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

out7:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
8.开运算与闭运算

demo8:

import cv2
import numpy as np

#开:先腐蚀,再膨胀
img = cv2.imread('D:\\openCV files\\data\\1\\dige.png')

kernal = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernal)

cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

#闭:先膨胀,再腐蚀
img = cv2.imread('D:\\openCV files\\data\\1\\dige.png')

kernal = np.ones((5,5),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernal)

cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

out8:
在这里插入图片描述
在这里插入图片描述
9.梯度运算

礼帽与黑帽

礼帽=原始输入-开运算结果

黑帽=闭运算-原始输入

demo9:

import cv2
import numpy as np

#梯度=膨胀-腐蚀
pie = cv2.imread('D:\\openCV files\\data\\1\\pie.png')

kernal = np.ones((7,7),np.uint8)  #核
dilate = cv2.dilate(pie, kernal, iterations = 5)  #iteration迭代次数
erosion = cv2.erode(pie, kernal, iterations = 5)

res = np.hstack((dilate,erosion))

cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernal)

cv2.imshow('gradient',gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

#礼帽,本段程序相当于只剩刺了
img = cv2.imread('D:\\openCV files\\data\\1\\dige.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernal)
cv2.imshow('tophat',tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()

#黑帽
img = cv2.imread('D:\\openCV files\\data\\1\\dige.png')
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernal)
cv2.imshow('blackhat',blackhat)
cv2.waitKey(0)
cv2.destroyAllWindows()

out9:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值