opencv处理dicom图像_图像处理之OpenCV的基础使用

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-1 03:27   73   0

e9d999f29a1e29e6ccf57fd517a94c6e.png

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

(1)opencv的安装

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

45dccf8ca5923c688af83a18775a7a5f.png

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

https://github.com/skvark/opencv-pythongithub.com

安装完成后如下所示。

b1c7128384a48f93afc09d6aa574151f.png

b1c7128384a48f93afc09d6aa574151f.png

同时由于图像本身是由多个像素点组成,每个像素点有不同的像素值,如果是灰白图像,像素值就是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刷新,等待任意按键退出 

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

21368e6787dd691335128bcde64fd90f.png

如果想获得黑白图片,可以在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刷新,等待任意按键退出 

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

6ea37121c40ac3a5d3b6a895bea82378.png

实践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)

执行结果为:

91cb8505754553ccb5c8d5a02285d0c8.png

我们看到前两张都是黑色的,第三张有点杂色。原因相信都理解,即像素值都是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)  #显示

执行后效果如下:

9369aca502671ab594d17608b38cbee4.png

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

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

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

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

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

执行结果为:

<class 'numpy.ndarray'>

由于是数组类型,可以直接使用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)

执行效果如下:

bd2176f352c3a203c56488da21c80e47.png

可以看到图中小男孩头顶那个区域已经变成了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)

执行后显示为:

0ee2d10843276186b1559ee20a378589.png

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

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

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP