Python OpenCV库的常见应用1

2021-03-08  本文已影响0人  LabVIEW_Python

OpenCV是计算机视觉中经典的用C++开发的专用库,其支持多语言、跨平台,功能强大。opencv-python是OpenCV库的Python接口,能让开发者在Python中方便调用OpenCV的函数。

opencv-python中的图像数据使用了Numpy 库的 ndarray 类进行管理,便于进行各种数值计算和转换。

import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 

img = cv2.imread('lena.jpg')
print(type(img),img.shape)

<class 'numpy.ndarray'> (350, 350, 3)

opencv-python从图像文件中读取数据的通道顺序是BGR,要转换为RGB才符合人们常用的通道顺序。通道转换可以用OpenCV自带的cvtColor()函数,也可以直接拆解然后重组图像数据。

import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 
# 用OpenCV自带的cvtColor()函数
img_bgr = cv2.imread('lena.jpg')
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

fig, ax = plt.subplots(1, 2)
ax[0].imshow(img_bgr)
ax[0].set_title('Channel order:BGR')

ax[1].imshow(img_rgb)
ax[1].set_title('Channel order:RGB')
plt.show()
import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 

img_bgr = cv2.imread('lena.jpg')
img_rgb = np.zeros_like(img_bgr)
# 手动拆解再重组
b, g, r = (img_bgr[:,:,i] for i in range(3))
img_rgb[:,:,0] = r
img_rgb[:,:,1] = g
img_rgb[:,:,2] = b
fig, ax = plt.subplots(1, 2)
ax[0].imshow(img_bgr)
ax[0].set_title('Channel order:BGR')

ax[1].imshow(img_rgb)
ax[1].set_title('Channel order:RGB')
plt.show()
通道顺序

ROI:Region of Interest,感兴趣区域。由于opencv-python中的图像数据是<class 'numpy.ndarray'>,所以截取ROI非常简单,相当于矩阵切片操作。

import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 

img = cv2.imread('lena.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

roi = img[100:265,100:250,:] # H,W,C

fig, ax = plt.subplots(1, 2)
ax[0].imshow(img)
ax[0].set_title('Original Image')

ax[1].imshow(roi)
ax[1].set_title('ROI')
plt.show()
用ROI把头部切出来

彩色图的BGR三个通道是可以分开单独访问的,也可以将单独的三个通道合并成一副图像,分别使用cv2.split()和cv2.merge()函数

import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 

img = cv2.imread('lena.jpg')
b,g,r = cv2.split(img)      # 拆解通道
img = cv2.merge((r,g,b))    # 合成图像

fig, ax = plt.subplots(1, 2)
ax[0].imshow(img)
ax[0].set_title('Original Image')

ax[1].imshow(r,cmap='gray')
ax[1].set_title('r')
plt.show()
拆解合并通道
阈值分割:将像素点值大于阈值变成一类值,小于阈值变成另一类值。用cv2:threshold()函数实现。
import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 

img = cv2.imread('lena.jpg', flags=cv2.IMREAD_GRAYSCALE)
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)

titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(images[i],'gray',vmin=0,vmax=255)
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()
各种阈值分割效果

自适应阈值分割:在前面固定阈值中,我们是随便选了一个阈值如127,那如何知道我们选的这个阈值效果好不好呢?答案是:不断尝试,所以这种方法在很多文献中都被称为经验阈值。Otsu阈值法就提供了一种自动高效的二值化方法。

import math 
import cv2 
import numpy as np 
import matplotlib.pyplot as plt 
import random 

img = cv2.imread('lena.jpg', flags=cv2.IMREAD_GRAYSCALE)

# 固定阈值
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 自适应阈值, ADAPTIVE_THRESH_MEAN_C:小区域内取均值
th2 = cv2.adaptiveThreshold(
    img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 4)
# 自适应阈值, ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
th3 = cv2.adaptiveThreshold(
    img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 17, 6)

titles = ['Original', 'Global(v = 127)', 'Adaptive Mean', 'Adaptive Gaussian']
images = [img, th1, th2, th3]

for i in range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i], fontsize=8)
    plt.xticks([]), plt.yticks([])
plt.show()
自适应阈值

《Python OpenCV库的常见应用2》

上一篇下一篇

猜你喜欢

热点阅读