图像处理之OpenCV的基础使用

您所在的位置:网站首页 pycharm基础使用方法 图像处理之OpenCV的基础使用

图像处理之OpenCV的基础使用

2023-04-02 19:53| 来源: 网络整理| 查看: 265

OpenCV是计算机视觉开源软件库,在图像处理领域应用非常广泛。目前其中能进行视觉处理的函数和方法达到1000多个,能够满足大部分行业的需求,包括医学影像、设计外观、生物体检测等。下面从opencv在python中的基础使用开始说起。

(1)opencv的安装

本篇使用的pythonIDE 为pycharm专业版,新建项目之后,直接在project的setting菜单里添加opencv-python库安装即可:

在可选择的库里找到opencv-python,目前版本为4.3,其github地址为:

安装完成后如下所示。

同时由于图像本身是由多个像素点组成,每个像素点有不同的像素值,如果是灰白图像,像素值就是0-255之间的值,如果是彩色图像,就有三个通道,每个通道像素值为0-255。如果是二维黑白图片,这些像素点就够成了一个二维矩阵,如果是二维彩色图片,这些像素点就是一个多维矩阵。也就是说,如果要对图像进行处理,实际上就是对矩阵里的像素值进行分析,因此安装和使用numpy或者pandas库就显得很有必要了。

(2)opencv简单使用

安装好了,我们说做就开始做。使用的时候直接在python文件中import导入即可。

实践1:读入图片显示图片,函数为imread和imshow

cv2.imread(filepath,flags): 用于读取图片,函数默认读取的是一副彩色图片,想要读取灰度图,则需要设置参数。其中参数: filepath:要读入图片的完整路径

flags:读入图片的标志 cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道cv2.IMREAD_GRAYSCALE:读入灰度图片cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道

cv2.imshow(windowName,filepath):创建一个窗口显示图片,共两个参数,第一个参数表示窗口名字,可以创建多个窗口中,但是每个窗口不能重名;第二个参数是读入的图片

下面我们在项目里新建一个main.py文件,开始输入下面内容:

import cv2 img1=cv2.imread('1.jpg') #1.jpg为存放在与main.py同目录里的图片文件,不加flags参数 cv2.imshow("cc",img1)

几行代码写完直接运行,你会发现一闪而过的效果,啥都没看着,郁闷得不行了。怎么办?cv2提供了一个waitKey函数,基本格式为:

waitKey(delayTime) #等待键盘按键效果,delayTime为延时,其功能是不断刷新图像,频率时间为delay,单位为ms

如果设置为0,那就是不断刷新图像,直到任意按键后退出显示。因此在上述代码中需要加入一行waitKey函数,现在的代码为:

import cv2 img1=cv2.imread('1.jpg') #1.jpg为存放在与main.py同目录里的图片文件 cv2.imshow("cc",img1) cv2.waitKey(0) #延时0ms刷新,等待任意按键退出

再来运行时,就可以看到图像了:

如果想获得黑白图片,可以在imread读入时加入flags为cv2.IMREAD_GRAYSCALE参数,如下代码:

import cv2 img1=cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE) #1.jpg为存放在与main.py同目录里的图片文件 cv2.imshow("cc",img1) cv2.waitKey(0) #延时0ms刷新,等待任意按键退出

再次运行,我们就得到了灰度图片:

实践2:复制图片,或者写图片,imwrite函数

cv2.imwrite(filename,orginalPic): 保存图片,共两个参数,第一个filename为保存文件名,第二个为读入的源图片。

例如想将上面的图片保存一下,可以使用如下代码:

import cv2 img1=cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE) #1.jpg为存放在与main.py同目录里的图片文件 cv2.imwrite("blackImg.jpg",img1)

执行后就将灰度图像1.jpg保存为了blackImg.jpg了。

实践3:构造图像,使用numpy和imshow函数

其中numpy用于构造像素点的像素值,imshow函数用于显示图形对象。

下面我们先使用numpy来构造三个像素矩阵:

第一步,使用numpy构造一个300x300的像素值全为1的矩阵matrix1:

import numpy as np matrix1 = np.mat(np.ones((300,300),dtype=np.unit8)) #构造一个值全是1的二维矩阵,300x300大小

代码中uint8是专门用于存储各种图像的(包括RGB,灰度图像等),范围是从0-255。

执行结果为:

[[1 1 1 ... 1 1 1] [1 1 1 ... 1 1 1] [1 1 1 ... 1 1 1] ... [1 1 1 ... 1 1 1] [1 1 1 ... 1 1 1] [1 1 1 ... 1 1 1]]

第二步,构造一个300x300的像素值全为0的矩阵matrix2:

import numpy as np matrix2 = np.mat(np.zeros((300,300),dtype=np.unit8)) #构造一个值全是0的二维矩阵,300x300大小

执行结果为:

[[0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] ... [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0] [0 0 0 ... 0 0 0]]

第三步,使用numpy的random方法来构造像素值为随机值的矩阵matrix3:

import numpy as np matrix3 = np.mat(np.random.randint(0,255,(300,300),dtype=np.uint8)) #构造一个随机赋值的二维矩阵,300x300大小

执行结果为:

[[ 75 139 239 ... 72 76 49] [ 47 7 122 ... 246 141 134] [112 95 8 ... 4 231 245] ... [251 132 162 ... 185 186 6] [188 246 253 ... 104 180 24] [148 26 207 ... 60 195 101]]

有了像素矩阵后,就可以直接使用cv2的imshow函数将其转换为图形对象显示出来。下面我们就对上述生成的三个像素矩阵进行显示:

import numpy as np import cv2,random #构建三个像素矩阵 matrix1= np.mat(np.zeros((300,300),dtype=np.uint8)) matrix2= np.mat(np.ones((300,300),dtype=np.uint8)) matrix3= np.mat(np.random.randint(0,255,(300,300),dtype=np.uint8)) #显示矩阵对应图像 cv2.imshow("img1",matrix1) cv2.imshow("img2",matrix2) cv2.imshow("img3",matrix3)

执行结果为:

我们看到前两张都是黑色的,第三张有点杂色。原因相信都理解,即像素值都是0或者1的话,肯定是黑色,第三张用了随机像素值,所以颜色有些变化。

如果想获得彩色图像,因为彩色图像需要RGB三通道,那我们可以对每个通道来构造一个像素矩阵,然后将这三个通道的像素点融合起来,就可以获得彩色显示的图像。如下实现:

matrixR= np.mat(np.random.randint(0,255,(300,300),dtype=np.uint8)) #生成R通道矩阵 matrixG= np.mat(np.random.randint(0,255,(300,300),dtype=np.uint8)) #生成G通道矩阵 matrixB= np.mat(np.random.randint(0,255,(300,300),dtype=np.uint8)) #生成B通道矩阵 RGBimg = cv2.merge([matrixR,matrixG,matrixB]) #融合三个通道像素 cv2.imshow("final",RGBimg) #显示

执行后效果如下:

生成了一张RGB彩色图片,但因为各个通道像素值都是随机生成的,所以没有什么规律可言,杂乱无章。

实践4:对彩色图像进行像素值读取

实践3里我们可以通过构造像素矩阵来合成图像,反过来我们也可以对图像的像素值进行读取,以及实现彩色图像三通道的分离。

例如我们对实践1的彩色图像来分析一下,在使用cv2的imread函数后直接返回的就是一个numpy的n维数组类型:

img1=cv2.imread('imgTools/IMG2.jpg') print(type(img1))

执行结果为:

由于是数组类型,可以直接使用numpy读取数值的方法,即使用坐标或者索引方式来获得像素值:

img1=cv2.imread('imgTools/IMG2.jpg') print(img1[100,100]) #读取图像里坐标为横轴为100,纵轴为100那个点的像素值 print(img1[100,100,0]) #读取图像坐标(100,100)位置那个点R通道像素值 print(img1[100,100,1]) #读取图像坐标(100,100)位置那个点G通道像素值 print(img1[100,100,2]) #读取图像坐标(100,100)位置那个点B通道像素值

执行结果为:

[252 231 209] 252 231 209

如果要获得某一行或某一列的像素值,或者某一个范围的像素值,都可以采用切片方式:

img1=cv2.imread('imgTools/IMG2.jpg') print(img1[100]) #读取图像里坐标为横轴为100时那一行的像素值 print(img1[:,100]) #读取图像里坐标为纵轴为100时那一列的像素值 print(img1[100:108]) #读取图像坐标横轴从100到108共8行的像素值 print(img1[:,100:108]) #读取图像坐标纵轴从100到108共8列的像素值 print(img1[100:108,100:108]) #读取图像坐标横轴从100到108行,纵轴从100到108列的一个小矩形框里的像素值

执行结果均为数组,受限于篇幅我们就不显示结果了。

实践5:对图像部分位置进行替换

因为可以获得某个范围的像素值,实际上就是截取了那个范围的图像,如果再使用imshow来显示的话,就可以将该范围的图像显示出来。同时也可以直接赋值改变那个范围的像素值,进而改变那个范围的图像显示,如下实践:

matrixR= np.mat(np.random.randint(0,255,(150,150),dtype=np.uint8)) matrixG= np.mat(np.random.randint(0,255,(150,150),dtype=np.uint8)) matrixB= np.mat(np.random.randint(0,255,(150,150),dtype=np.uint8)) RGBimg = cv2.merge([matrixR,matrixG,matrixB]) img1=cv2.imread('imgTools/IMG2.jpg') img1[100:250,100:250]=RGBimg #将img1的部分区域替换为新的像素值 cv2.imshow("img1",img1)

执行效果如下:

可以看到图中小男孩头顶那个区域已经变成了chaos区域。

实践6:对彩色图像实现三通道分离,使用cv2的split函数

img1=cv2.imread('imgTools/IMG2.jpg') r,g,b=cv2.split(img1)

执行后就可以获得三个通道r,g,b各自的像素矩阵,如下显示一下r通道像素矩阵:

[[103 46 56 ... 8 9 13] [ 81 49 62 ... 10 12 12] [ 55 64 58 ... 14 18 14] ... [ 56 53 65 ... 137 132 126] [ 57 57 62 ... 136 135 131] [ 55 57 56 ... 130 131 128]]

从数据来看,每一行都是一维数组,如果要访问的话直接使用数组的索引方式即可。

我们可以将这分离的三个通道像素矩阵都绘成图对比,其实只需要使用cv2的imshow函数即可:

img1=cv2.imread('imgTools/IMG2.jpg') r,g,b=cv2.split(img1) for index,item in enumerate(cv2.split(img1)): cv2.imshow('item-'+str(index),item)

执行后显示为:

单通道时都变成了灰色显示,仔细对比还是有些许差别的,三通道对应位置的像素值不同,所以组合起来也会不一样。对于灰度显示,颜色越白代表像素值越接近255,颜色越黑代表像素值越接近0.

本篇就使用opencv来读写图片、了解图片对应的像素矩阵实践方式进行了介绍,代码都可以直接复制到自己的pycharm或者其它IDE中来检验效果。从实践过程中可以发现由于二维图片像素值均为矩阵样式,numpy库的作用发挥很大,后续实践opencv过程中还有会许多应用。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3