基本读图操作与像素加法

首先我们安装好opencv-python,只需要安装最新版本即可。

1
import cv2 as cv

不管是什么版本,在导入的时候,都用上述命令即可,用cv便于书写。

1
import matplotlib.pyplot as plt

导入绘图库,将会非常重要。

1
img_cat = cv.imread("def.jpg", 1);

1表示以彩色方式读取图像,0表示以灰度模式读取图像,也就是单通道图像,只需要一个矩阵就能表示。

1
img_dog = cv.imread("anc.jpg", 1)

加10创建了一个新图像,从原始图像中复制而来,原始图像中每个像素都加10,

1
2
img_cat2 = img_cat + 10;
img_cat2[:5, :, 0]#读取前五行和所有列,灰度图像

切片处理中[:5]表示仅仅处理前五行像素,:表示处理所有的列,而0表示通道0,在cv中通道顺序是BGR图像,所以是蓝色。

array([[  0, 147, 156, ..., 210,   5, 166],
       [248, 231, 119, ..., 236, 174, 113],
       [192, 193, 229, ..., 204, 154, 106],
       [226, 184, 229, ..., 204, 248, 154],
       [108, 188, 212, ..., 233,   9, 148]], dtype=uint8)
1
img_cat[:5, :, 0]#和原来作比较

我们可以比较两个像素值。也就是cat+10就是cat2的像素值,我们发现像素都是mod 256的,并且数据类型为unit8。

array([[246, 137, 146, ..., 200, 251, 156],
       [238, 221, 109, ..., 226, 164, 103],
       [182, 183, 219, ..., 194, 144,  96],
       [216, 174, 219, ..., 194, 238, 144],
       [ 98, 178, 202, ..., 223, 255, 138]], dtype=uint8)
1
2
3
4
5
6
#我们对现有两个图片做加法
#先看shape是否相同
img1 = cv.imread("abc.jpg", 1)
img2 = cv.imread("def.jpg", 1)
print(img1.shape);
print(img2.shape);
(282, 413, 3)
(215, 310, 3)

可以看出两个图像都是彩色图像但是大小并不相同!我们可以用resize来进行图像大小调整。

1
2
img1 = cv.resize(img1, (215,310))
img1.shape

调整之后大小相同。

只有相同大小(其实即为矩阵大小相同)的两个图像才能做像素加法。

1
img3 = img1 + img2#注意这里我们看到,后面那个数才是行,前面是列。
1
img3.shape

可以查看img3就是我们用像素加法合成的图像。

(215, 310, 3)

然后显示图像,这里waitkey(0)表示等待我们按任意键,之后便取消显示。

1
2
3
cv.imshow("img3", img3)
cv.waitKey(0)
cv.destroyAllWindows(0);

但是如果仅仅用imshow程序不会显示图像,所以我们可以改用plt绘图。

1
2
3
import cv2 as cv
img3 = cv.addWeighted(img1, 0.6, img2, 0.4, 0)
cv.imshow("img3", img3)
1
#我们发现直接imshow()会程序崩溃,可以改用plt绘图。

还可以直接用加法函数

1
add = cv.add(img1_size, img2_size);

完成对两个相同大小的图片相加。

按照一定比例混合像素

1
2
3
4
5
6
7
8
9
10
11
img1 = cv.imread("abc.jpg")
img2 = cv.imread("def.jpg")#首先读取图片

img1_size = cv.resize(img1, (500, 300))
img2_size = cv.resize(img2, (500, 300))

weighted = cv.addWeighted(img1_size, 0.6, img2_size, 0.4, 0)

cv.imshow("weighted", weighted);
cv.waitKey(0);
cv.destroyAllWindows()

其中用到了重要函数addWeighted(img1, alpha, img2, beta, gamma, dtype)

将两幅图像按照一定的比例混合,alpha为第一个图像的占比,beta同理。最后还可以加入dtype参数用于指定图像结果的数据类型,当然默认与输入相同。
gamma用于控制图像的亮度,通常是一个浮点数。

画图

首先加载一个图片

1
img = cv.imread("me.jpg", cv.IMREAD_COLOR)

开始绘制

1
2
3
4
5
img_size = cv.resize(img, (700, 1500))
cv.line(img_size, (0,0), (150, 150), (0, 0, 0), 15)#开始坐标,介绍坐标, 颜色BGR, 粗细
cv.imshow("image.jpg", img_size);
cv.waitKey(0);
cv.destroyAllWindows();

对特定像素的颜色修改

首先我们取出特定像素。

1
2
3
img = cv2.imread("me.jpg", cv2.IMREAD_COLOR);#读取BGR颜色格式的图片
img_size = cv2.resize(img, (700, 1050))
px = img[55, 55]

然后进行颜色赋值

1
2
img[55, 55] = [255, 255, 255]
px = img[55,55]#直接确定到对应行列的像素。

还可以进行成片修改。

1
img[100:150, 100:150] = [255, 255, 255]#都是修改方式,成片修改,这里是变白

写入图片

1
2
image = cv.imread("me.jpg")
cv.imwrite("me.png", image)

这样就完成了格式转换。

用随机字节创建图片

1
2
3
4
randomByteArray = bytearray(os.urandom(120000))#返回120000字节的数组
flatNumpyArray = numpy.array(randomByteArray)#转换成numpy数组的格式
gray_image = flatNumpyArray.reshape(300, 400)#转成二维灰度图像
cv.imread("random.png", gray_image)#显示图像即可。

录像功能,转成视频

先来一点基础摄像头操作的知识,

1
2
3
4
5
6
7
8
9
10
cap = cv.VideoCapture(0)#启动摄像头
while True:
ret, frame = cap.read()#ret表示是否有值,没有就是none,有就会得到frame
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#定义新变量作为转换灰度的帧,opencv将颜色读取为BGR
cv.imshow("frame", gray)#对原始帧执行这个命令,也就是将原始帧转换为灰度帧

if cv.waitKey(1) & 0xff == ord("q"):#如果按q就退出
break
cap.release()
cv.destroyAllWindows()

然后再来规范一下!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cap = cv.VideoCapture(0)#用第一个摄像头
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.ViedoWriter("output.avi", fourcc, 60, (640, 480), 1)

while(True):
ret, frame = cap.read()
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#设置灰度

out.write(frame)#写入每一帧
cv.imshow("frame", gray)
if cv.waitKey(1) & 0xff == ord('q'):#转成ascii码,按q退出!
break
cap.release()#也就是两个video开头的函数,都要进行释放。
out.release()
cv.destroyAllWindows()

下面再来一个最全面的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import cv2
import numpy as np
import matplotlib.pyplot as plt

vc = cv2.VideoCapture("output.mp4");
if vc.isOpened():
open, frame = vc.read()
print(open)
else:
open = False
print(open)
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(1) & 0XFF == ord("q"):
break#这里用判断语句考虑到了各种情况
vc.release()
cv2.destroyAllWindows()

简便读取方式

1
img = cv.imread("me.jpg", 1)#1读取彩色,0读取黑白!

图像操作练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("def.png", cv2.IMREAD_COLOR)
part = img[0:200, 0:200]#截取部分源码
cv2.imshow("part", part)
b, g, r = cv2.split(part)#也就是把截获的图片像素分成了三种颜色分别的矩阵
print(b, "\n")
print(g, "\n")
print(r, "\n")
img2 = cv2.merge((b, g, r))#再和到一起!命名为新图片img2
cv2.imshow("img2", img2)
#下面截取部分原色
print(part.shape)#首先看大小
cur_img = part.copy()#先把bgr复制过来
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
#显然,宽和高不变,把b和r颜色都设置为0,就剩下绿色了
cv_show = cv2.imshow("原色改动", cur_img)
cv2.waitKey(0)
cv2.destroyAllWindows()