Opencv图像基本操作

唐宇迪博士opencv课程学习笔记

Opencv图像基本操作

      • 数据读取-图像
        • 数据读取-视频
        • 截取部分图像数据
        • 颜色通道提取
      • 边界填充
      • 数值计算
      • 图像融合
      • 图像重构

Opencv图像基本操作_第1张图片

数据读取-图像

  • cv2.IMREAD_COLOR:彩色图像
  • cv2.IMREAD_GRAYSCALE:灰度图像
# opencv读取的格式是BGR
import cv2
impoet matplotlib.pyplot as plt
import numpy as np
%matplotlib inline	# 魔法函数

img = cv2.imread('cat.jpg')
img
array([[[142, 151, 160],
       [146, 155, 164],
       [151, 160, 169],
       ...,
       [156, 172, 185],
       [155, 171, 184],
       [154, 170, 183]],

      [[107, 118, 126],
       [112, 123, 131],
       [117, 128, 136],
       ...,
       [155, 171, 184],
       [154, 170, 183],
       [153, 169, 182]],

      [[108, 119, 127],
       [112, 123, 131],
       [118, 129, 137],
       ...,
       [154, 170, 183],
       [153, 169, 182],
       [152, 168, 181]],

      ...,
...
       [121, 145, 157],
       ...,
       [185, 198, 200],
       [130, 143, 145],
       [129, 142, 144]]], dtype=uint8)
# 图像显示,也可以创建多个窗口
cv2.inshow('image', img)
# 等待时间,毫秒级,0表示任意键终止
cv2.waitKey(0)
cv2.destoryAllWindows()
def cv_show(name, img)
	cv2.imshow(name, img)
	cv2.waitkey(0)
	cv2.destoryAllWindows()
img.shape
(414, 500, 3)
# h w c (RGB)
img=cv2.imread('cat.jpg', cv2.IMREAD_GRAYSCALE)
img
array([[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]], dtype=uint8)
img.shape
(414, 500)
# 保存
cv2.imwrite('mycat.png', img)
# 照片格式
type(img)
numpy.ndarray
# 像素点个数
img.size
20700
# 数据类型
img.dype
dtype('uint8')

数据读取-视频

  • cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0, 1。
  • 如果是视频文件,直接制定好路径即可。
vc = cv2.VideoCapture('test.mp4')

# 检查是否正确
if vc.isOpened():
	open, frame = vc.read()
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:	# waitKey(1)计算机性能有多快,处理就有多块
			break
vc.release()
cv2.destroyAllWindows()

截取部分图像数据

img = cv2.imread('cat.jpg')
cat=img[0:200, 0:200]	# h	w
cv_show('cat', cat)	# 前面自己定义的函数

颜色通道提取

b, g, r = cv2.split(img)
# 虽然像素点大小不一样,但shape大小一定是相同的,要不然就不是一张图像中切出来的
b.shape
(414, 500)
# 颜色组合
img = cv2.merge((b, g, r))
img.shape
(414, 500, 3)
# 只保留R
cur_img = img.copy()
cur_img[:, :, 0] = 0
cur_img[:, :, 1] = 0
cv_show('R', cur_img)

边界填充

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

# borderType按照什么方式进行填充
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)
reflect101 = 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)
import matplotlib.pyplot as plt
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()

Opencv图像基本操作_第2张图片

  • BORDER_REPLICATE:复制法,也就是复制最边缘像素。
  • BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
  • BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
  • BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
  • BORDER_CONSTANT:常量法,常数值填充

不需要记type值,记住方法和输出样子就行

数值计算

img_cat = cv2.imread('cat.jpg')
img_dog = cv2.imread('dog.jpg')
img_cat2 = img_cat + 10	# 相当于在每个像素点上都加上10
img_cat[:5, :, 0]
array([[142, 146, 151, ..., 156, 155, 154],
       [107, 112, 117, ..., 155, 154, 153],
       [108, 112, 118, ..., 154, 153, 152],
       [139, 143, 148, ..., 156, 155, 154],
       [153, 158, 163, ..., 160, 159, 158]], dtype=uint8)
img_cat2[:5, :, 0]
# [:5, :, 0] 为了不打印太多,选择前5行和一个通道。
array([[152, 156, 161, ..., 166, 165, 164],
       [117, 122, 127, ..., 165, 164, 163],
       [118, 122, 128, ..., 164, 163, 162],
       [149, 153, 158, ..., 166, 165, 164],
       [163, 168, 173, ..., 170, 169, 168]], dtype=uint8)
# 相当于% 256
(img_cat + img_cat2)[:5, :, 0]
array([[ 38,  46,  56, ...,  66,  64,  62],
       [224, 234, 244, ...,  64,  62,  60],
       [226, 234, 246, ...,  62,  60,  58],
       [ 32,  40,  50, ...,  66,  64,  62],
       [ 60,  70,  80, ...,  74,  72,  70]], dtype=uint8)       
# a>255 ? 255:a
cv2.add(img_cat, img_cat2)[:5, :, 0]
array([[255, 255, 255, ..., 255, 255, 255],
       [224, 234, 244, ..., 255, 255, 255],
       [226, 234, 246, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)

图像融合

前提是两张图片的 shape 值需要一样

img_dog = cv2.resize(img_dog, (500, 414))
res = cv2.resize(img, (0, 0), fx=1, fx=3)	# 倍数
res = cv2.resize(img, (0, 0), fx=4, fx=4)	# 同比例放缩
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)	# 最后一个系数是亮度

图像重构

主要参数

dst = cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

参数意义:

  1. scr:原图像
  2. dsize:输出的图像大小
  3. dst:输出的图像。当参数dsize不为0时,dst的大小为size;否则,它的大4. 小需要根据src的大小,fx和fy决定。
  4. fx:沿水平轴的比例因子
  5. fy:沿垂直轴的比例因子

参数dsize和参数(fx, fy)不能够同时为0
interpolation:插值方法,共5种:

  1. INTER_LINEAR - 双线性插值(默认)(放大图像推荐使用)
  2. INTER_NEAREST - 最近邻插值
  3. INTER_AREA - 基于像素局部的重采样插值(缩小图像推荐使用)。该方法对于图像抽取(image decimation)来说可能更好,但如果是放大图像,和最近邻插值效果类似。
  4. INTER_CUBIC - 基于4x4像素邻域的3次插值(放大图像推荐使用)
  5. INTER_LANCZOS4 - 基于8x8像素邻域的Lanczos(兰索斯)插值

你可能感兴趣的