0.Opencv环境配置

这一环节咱们首要介绍Opencv图形处理结构,首要咱们要配置好对应的环境。咱们在网上能够搜到各式各样的教程,这儿我的环境如下

python3.6, opencv-contrib-python3.4.1.15,opencv-python3.4.1.15

咱们能够依据自己的python环境自习装置对应的版别。

以我的环境为例,装置命令如下

pip install opencv-python==3.4.1.15

pip install opencv-contrib-python==3.4.1.15

image-20230730110033143

1.图画读取

接下来咱们来看在opencv傍边,图画最根本的操作。

首要,咱们得先知道计算机是怎么看一张图画的

image-20230730110930201

咱们来调查这个图,咱们把它叫做丽娜,咱们把图片分红了许多许多小方格,然后咱们拿出其间的一个方格调查一下。在这个方格傍边,咱们的每一个便是一个大区域,它是有许多个小块儿所组成的,其间的每一个小格,它叫做一个像素点,计算机当便是由这些像素点来构成一张图画的,那像素点又是什么呢?

其实,它便是一个值,咱们来看最右边,每一个矩阵里边儿的组成,各种值,例如81,116,…,133,170。它们便是构成像素点的每一个值了,而这个数值巨细意味着什么呢?

在计算机傍边,每一个像素点的值是在0-255之间进行起浮的,表明该点亮度,0表明很亮,255表明很暗

然后咱们再来看R、G、B三个通道,每一个五颜六色图都是由RGB三颜色通道组成的,然后每一个矩阵别离对应每一个通道的亮度。关于灰度图而言,就只有一个通道来表明亮度。

这些像素点组成了一个矩阵,这个矩阵就表明图画的巨细,例如咱们假设矩阵是300×300,那相应的rgb三个通道都是300×300,因而整个图形的维度便是(300,300,3)

1.1五颜六色图画读取

当咱们要剖析一张图片时,首要便是读取它转换成一个矩阵的格局,下面咱们正式看一下怎么读取图片

import cv2 #opencv读取的格局是BGR
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline 
img=cv2.imread('yangqi.jpg')

在这儿咱们先导入cv2,然后找到你要读取的图片地址,我这儿用的是咱们家小狗的图片,他的名字叫洋气,‘yangqi.jpg’,运用cv.imread()函数就会把这张图画读进来。

咱们来看一下它的成果是什么

img
array([[[ 99, 141, 148],
        [ 95, 137, 144],
        [ 78, 120, 127],
        ...,
        [ 69,  88, 103],
        [ 81, 100, 113],
        [ 88, 107, 120]],
       [[ 93, 137, 144],
        [ 49,  93, 100],
        [ 86, 130, 137],
        ...,
        [175, 197, 209],
        [195, 217, 229],
        [200, 222, 234]],
       [[ 30,  76,  84],
        [ 23,  66,  75],
        [ 72, 115, 124],
        ...,
        [ 43,  65,  77],
        [ 42,  64,  76],
        [ 43,  65,  77]],
       ...,
       [[178, 209, 232],
        [158, 189, 212],
        [154, 185, 206],
        ...,
        [ 68,  78,  85],
        [ 54,  64,  71],
        [ 83,  93, 100]],
       [[164, 195, 216],
        [138, 169, 190],
        [168, 197, 218],
        ...,
        [ 84,  94, 101],
        [ 92, 102, 109],
        [ 87,  97, 104]],
       [[167, 196, 217],
        [129, 158, 179],
        [102, 131, 152],
        ...,
        [101, 111, 118],
        [124, 134, 141],
        [ 96, 106, 113]]], dtype=uint8)
img.shape
(238, 218, 3)

能够看到,它回来的是一个ndarray的结构,纬度为(238, 218, 3),因为咱们这儿是一张五颜六色图片,所以有三个通道。

现在咱们现已把图画数据给读进来了,有些时分便是随着咱们对图画进行处理,例如边际检测,或许是一些更复杂的操作。在做操作过程傍边,咱们想调查一下,这个图画它变换成什么样子了,因而咱们需求展现图画,咱们能够用matplotlib或许cv2,可是需求留意的是openCV默认读取是BGR的格局,所以在读取的时分,如果咱们要用matplotlib的话需求进行相应的改变。咱们这儿悉数都用openCV自带的函数来展现。这儿咱们运用cv.imshow()函数,传入两个参数,第一个参数表明窗口的名称,第二个函数便是咱们要读取的图画数据,也便是咱们刚刚得到的那个矩阵

#图画展现
cv2.imshow('cat',img) 
cv2.waitKey(0) # 等待时间,0表明按任意键完毕
cv2.destroyAllWindows()

image-20230802195935084

为了方便运用,咱们界说函数cv_show(),今后就直接调用这个函数来进行图画读取

def cv_show(name,img):
    cv2.imshow(name,img) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows()

1.2 灰色图画读取

在opencv中,默认都是进行五颜六色图画读取,有的时分咱们想要读取灰度图,在这儿咱们指定cv2.IMREAD_GRAYSCALE

img=cv2.imread('yangqi.jpg',cv2.IMREAD_GRAYSCALE)
img
array([[138, 134, 117, ...,  90, 102, 109],
       [134,  90, 127, ..., 198, 218, 223],
       [ 73,  64, 113, ...,  66,  65,  66],
       ...,
       [212, 192, 188, ...,  79,  65,  94],
       [198, 172, 200, ...,  95, 103,  98],
       [199, 161, 134, ..., 112, 135, 107]], dtype=uint8)
img.shape
(238, 218)

能够看到现在的数据变成了一个二维矩阵了,此时是一个单通道,咱们再次读取

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

image-20230802200115164

能够看出现在这个图片就变成灰白了

2.视频读取

视频读取其实和咱们图画读取相似,咱们先把视频进行拆分,拆分红其间的每一帧,然后基于每一帧图画去做。下面咱们详细来看一下怎么运用opencv读取视频,首要找到你要读取的视频路径,然后调用cv2.VideoCapture()函数得到视频流,然后咱们运用isOpened()来判别是否能翻开,如果能翻开,运用vc.read()一帧一帧的读取视频信息,然后回来两个值,open为布尔值,frame为读取的每一帧的图画数据

vc = cv2.VideoCapture('test.mp4')
# 检查是否翻开正确
if vc.isOpened(): 
    oepn, 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(100) & 0xFF == 27:#等待时间
            break
vc.release() 
cv2.destroyAllWindows()

图片转存失利,建议将图片保存下来直接上传

3.ROI读取

3.1 图形切片处理

接下来咱们来看,当我拿到一张图画时,有的时分我只对某一个区域感兴趣,例如咱们刚刚的cat图片,我可能想要调查的是中间的某一个特定区域,这便是region of interest(ROI)读取,如下所示,咱们对图形进行切片处理,得到它的左上部分成果。

img=cv2.imread('yangqi.jpg')
dog=img[0:50,0:200] 
cv_show('yangqi',dog)

image-20230802200200479

3.2 提取颜色通道

有的时分咱们需求对图画进行一些特殊的剖析,假设一个五颜六色图画,它是由三个颜色通道组成,BGR(Opencv默认次序)。在openCV傍边,咱们能够运用cv2.split()把三个通道别离提取出来看一下

b,g,r=cv2.split(img)

这样咱们得到了每一个通道的数据

r.shape,b.shape,g.shape
((238, 218), (238, 218), (238, 218))

能够看到每一个通道都是一个二维矩阵。在咱们切片完处理之后,咱们期望再将其组合在一起,咱们能够直接调用cv2.merge(),留意咱们的次序是BGR

img=cv2.merge((b,g,r))#次序为bgr
img.shape

咱们前面一直说五颜六色图片有三个通道,那么每个通道的图画是怎样的呢?咱们接下来别离来看看。首要,咱们只看R通道的图画,那么咱们设置B,G通道关于的像素点值全为0

tmp_img = img.copy()
tmp_img[:,:,0] = 0#第一个通道B悉数设为0
tmp_img[:,:,1] = 0#第二个通道G悉数设为0
cv_show('Red',tmp_img)

image-20230802200249592

能够看到得到了一张赤色图片,下面相似的操作能够别离得到蓝色绿色的成果

tmp_img = img.copy()
tmp_img[:,:,0] = 0
tmp_img[:,:,2] = 0
cv_show('Green',tmp_img)

image-20230802200348621

tmp_img = img.copy()
tmp_img[:,:,1] = 0
tmp_img[:,:,2] = 0
cv_show('Blue',tmp_img)

image-20230802200333988

4.图画填充

接下来咱们讨论一下图画填充,这个也比较常见,咱们之间在介绍卷积的时分说了padding,它便是在图画在鸿沟进行填充。下面咱们就介绍一下运用Opencv来填充图画的一些办法

top_size,bottom_size,left_size,right_size = (100,100,100,100)#要填充的巨细
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) #反射法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) #常数填充,0表明黑色
  • BORDER_REPLICATE:仿制法,直接仿制最边际的像素
  • BORDER_REFLECT:反射法,对感兴趣的图画中的像素在两边进行仿制,例如,原始为1234,那么咱们仿制的办法为321|1234|432
  • BORDER_REFLECT_101:反射法101,以最边际像素为轴进行对称仿制,例如,原始为1234,那么咱们仿制的办法为432|1234|321
  • BORDER_WRAP:外包装法,例如原始为1234,仿制为234|1234|123
  • BORDER_CONSTANT:常量法,常数值填充。

检查成果

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()

image-20230802200452987

5.数值运算与图画交融

接下来咱们来看一下在Opencv中的根本数值运算,咱们先读取两张图画,yangqi和另一只猫的图片cat

img_dog=cv2.imread('yangqi.jpg')
img_cat=cv2.imread('cat.jpg')

5.1加法运算

img_cat2= img_cat +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)

然后咱们对cat加10,这相当于在每个像素点都加10.

img_cat2[:5,:,0]
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)

在opencv中,咱们有两种办法实现两个矩阵相加

# 办法一
(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)
# 办法二
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)
  • 办法一:直接如上所示,用a+b,这样得出来的成果咱们能够看第一个为38,咱们知道刚刚两个矩阵的第一个元素相加为142+152=294,之前咱们说每一个像素的规模为0-255,在这儿超过了255,因而咱们这儿实际上是294%256=38,进行了一个取余数的操作

  • 办法二:cv2.add(),这种办法会将超过255的值界说为255

5.2 图画交融

首要咱们来看一下两张图片的维度

img_cat.shape,img_dog.shape
((414, 500, 3), (238, 218, 3))

由于维度不同,不能直接相加,这儿咱们需求运用cv.resize将dog的图片维度转换,这在咱们之前CNN中也用过相似的操作。

img_dog = cv2.resize(img_dog, (500, 414))
img_dog.shape
(414, 500, 3)

现在两张图片的纬度一样了,咱们能够调用cv2.addWeighted()将两张图片交融。

这儿有5个参数,别离是图片1数据、图片1权重、图片2数据、图片2权重、常数项。

详细操作便是0.4*cat+0.6*dog+0

res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)

image-20230802200715599

能够看到这个成果傍边,左边像猫,右边像狗,这样就好像两张图画就交融在一起了。

6. 总结

咱们介绍了Opencv环境配置、根本的图画和视频读取、读取感兴趣的部分图画、图画填充、以及在Opencv中的根本数值计算和图画交融。

收藏点赞后私信我获取完整代码文件