OpenCV从入门到入坟
Posted 贪钱算法还我头发
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV从入门到入坟相关的知识,希望对你有一定的参考价值。
小脑一抽去学了狗都不学的CV,几天热度到现在全是凉水
学习视频链接b站openCV
1. 图像基本操作
1.1 图片处理
- cv2.IMREAD_COLOR: 彩色图像
- cv2.IMREAD_GRAYSCALE:灰度图像
import cv2 #opencv读取的格式的RGB
import matplotlib.pyplot as plt # matplotlib的格式是RGB
import numpy as np
%matplotlib inline
图片读取
img = cv2.imread('img/cat.jpg')
print(img.shape) # (414, 500, 3)
img
""
array([[[142, 151, 160],
[146, 155, 164],
[151, 160, 170],
...,
[183, 198, 200],
[128, 143, 145],
[127, 142, 144]]], dtype=uint8)
""
def cv_show(name, img):
cv2.imshow(name, img)
cv2.waitKey(0) # 等待时间,毫秒级,0表示任意键终止
cv2.destroyAllWindows()
# 灰度图
img = cv2.imread('img/cat.jpg', cv2.IMREAD_GRAYSCALE)
print(img.shape, type(img), img.size, img.dtype) # (414, 500) <class 'numpy.ndarray'> 207000 uint8
cv_show('image', img)
cv2.imwrite('img/mycat.jpg', img)
# 截取部分图像
cat = img[0:50, 0:200]
cv_show('cat', cat)
# 颜色通道提取
img = cv2.imread('img/cat.jpg')
b, g, r = cv2.split(img)
print(r.shape) # (414, 500)
img = cv2.merge((b, g, r))
print(img.shape) # (414, 500, 3)
# 只保留R
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,1] = 0
cv_show('G', cur_img)
边界填充
- BORDER_REPLICATE:复制最边缘像素
- BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
- BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
- BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
- BORDER_CONSTANT:常量法,常数值填充
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)
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()
数值计算
img_cat = cv2.imread('img/cat.jpg')
img_cat2 = img_cat + 10
print(img_cat[:5,:,0])
print(img_cat2[:5,:,0])
""
[[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]]
""
print((img_cat + img_cat2)[:5,:,0]) # 相当于% 256
print(cv2.add(img_cat, img_cat2)[:5, :, 0]) # 超过的赋值为最大值
""
[[ 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]]
""
图像融合
img_cat = cv2.imread('img/cat.jpg')
img_dog = cv2.imread('img/dog.jpg')
img_cat + img_dog
""
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-30-e16b258924d3> in <module>
1 img_cat = cv2.imread('img/cat.jpg')
2 img_dog = cv2.imread('img/dog.jpg')
----> 3 img_cat + img_dog
ValueError: operands could not be broadcast together with shapes (414,500,3) (429,499,3)
""
img_dog = cv2.resize(img_dog, (500, 414))
print(img_dog.shape) # (414, 500, 3)
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)
plt.imshow(res)
res = cv2.resize(img_cat, (0, 0), fx=4, fy=4)
plt.imshow(res)
res = cv2.resize(img, (0, 0), fx=1, fy=3)
plt.imshow(res)
HSV
- H - 色调(主波长)
- S - 饱和度(纯度/颜色的阴影)
- V值(强度)
# gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 灰度图
hsv = cv2.cvtColor(img_cat, cv2.COLOR_BGR2HSV)
plt.imshow(hsv)
图像阈值
ret, dst = cv2.threshold(src, thresh, maxval, type)
- src: 输入图,只能输入单通道图像,通常来说为灰度图
- dst: 输出图
- thresh: 阈值
- maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- type:二值化操作的类型,包含以下5种类型:
- cv2.THRESH_BINARY: 超过阈值部分取maxval(最大值),否则取0
- cv2.THRESH_BINARY_INV: THRESH_BINARY的反转
- cv2.THRESH_TRUNC: 大于阈值部分设为阈值,否则不变
- cv2.THRESH_TOZERO: 大于阈值部分不改变,否则设为0
- cv2.THRESH_TOZERO_INV: THRESH_TOZERO的反转
img_gray = cv2.cvtColor(img_cat, cv2.COLOR_BGR2GRAY)
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', 'TOZERO', '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')
plt.title(titles[i])
# plt.xticks([]), plt.yticks([])
plt.show()
图像平滑
img = cv2.imread('img/lenaNoise.png')
cv_show('img', img)
# 均值滤波:简单的卷积操作
blur = cv2.blur(img, (3, 3))
cv_show('blur', blur)
# 方框滤波: 基本和均值一样,可以选择归一化
box = cv2.boxFilter(img, -1, (3, 3), normalize=True)
cv_show('box', box)
# 高斯滤波:高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1)
cv_show('aussian', aussian)
# 中值滤波:相当于用中值代替
median = cv2.medianBlur(img, 5)
cv_show('median', median)
# 展示所有的
res = np.hstack((blur, aussian, median))
cv_show('res', res)
形态学-腐蚀操作
img = cv2.imread('img/dige.png')
cv_show('img', img)
kernal = np.ones((3, 3), np.uint8)
erosion = cv2.erode(img, kernal, iterations=1)
cv_show('erosion', erosion)
pie = cv2.imread('img/pie.png')
cv_show('pie', pie)
kernel = np.ones((30, 30),np.uint8)
erosion_1 = cv2.erode(pie, kernel, iterations = 1)
erosion_2 = cv2.erode(pie, kernel, iterations = 2)
erosion_3 = cv2.erode(pie, kernel, iterations = 3)
res = np.hstack((erosion_1 erosion_2, erosion_3))
cv_show('res', res)
形态学-膨胀操作
img = cv2.imread('img/dige.png')
cv_show('img', img)
kernel = np.ones((3, 3), np.uint8)
dige_erosion = cv2.erode(img, kernel, iterations = 1)
dige_dilate = cv2.dilate(dige_erosion, kernel, iterations = 1) # 腐蚀膨胀后不变
cv_show('dige_dilate', dige_dilate)
pie = cv2.imread('img/pie.png')
cv_show('pie', pie)
kernel = np.ones((30,30),np.uint8)
dilate_1 = cv2.dilate(pie, kernel, iterations = 1)
dilate_2 = cv2.dilate(pie, kernel, iterations = 2)
dilate_3 = cv2.dilate(pie, kernel, iterations = 3)
res = np.hstack((dilate_1, dilate_2, dilate_3))
cv_show('res', res)
开运算与闭运算
img = cv2.imread('img/dige.png')
kernel = np.ones((5, 5), np.uint8)
# 开:先腐蚀,再膨胀
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
# 闭:先膨胀,再腐蚀
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
res = np.hstack((img, opening, closing))
cv_show('res', res)
梯度运算
# 梯度 = 膨胀 - 腐蚀
pie = cv2.imread('img/pie.png')
kernel = np.ones((7, 7), np.uint8)
dilate = cv2.dilate(pie, kernel, iterations = 5)
erosion = cv2.erode(pie, kernel, iterations = 5)
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
res = np.hstack((pie, dilate, erosion, gradient))
cv_show('res', res)
礼帽与黑帽
- 礼帽 = 原始输入- 开运算结果
- 黑帽 = 闭运算 - 原始输入
img = cv2.imread('img/dige.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
res = np.hstack((img, tophat, blackhat))
cv_show('res', res)
图像梯度-Sobel算子
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth:图像的深度
- dx和dy分别表示水平和竖直方向
- ksize是Sobel算子的大小
img = cv2.imread('img/pie.png',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
res = np.hstack((img, sobelx))
cv_show(Spring Boot 2从入门到入坟 | 基础入门篇:「Spring Boot 2从入门到入坟」系列教程介绍