1. 程式人生 > >Python3 OpenCV3 圖像處理基礎

Python3 OpenCV3 圖像處理基礎

有著 play 畫布 質量 int32 數據 asi org sam

開發環境搭建

本人使用的是Ubuntu 16.04LTS。

1、安裝Python3

## 其實 Ubuntu 16.04 系統自帶了 Python 3.5.2,因此不需要再安裝了?但是需要安裝一些開發環境。
sudo apt-get update # 更新系統源
sudo apt-get install python3 python3.5-dev libpython3.5-dev  # 安裝基礎包
sudo apt-get install python3-pip # 安裝 pip3 
sudo pip3 install --upgrade pip  # 更新 pip3 

#
# 測試 $ python3 --version Python 3.5.2

2、安裝Numpy,Matplotlib,OpenCV

這些庫可以自己下載源碼編譯,也有別人編譯好的,我們直接下載。

## 安裝庫
sudo pip3 install numpy      # 安裝 numpy,用於在Python中進行科學計算
sudo pip3 install matplotlib # 安裝 matplotlib,用於顯示、繪圖等
sudo pip3 install opencv-python  # 安裝 opencv 

## 確保 OpenCV 已經安裝好  
$ python3 -c "
import cv2;print(cv2.__version__)" 4.0.0

其實在安裝opencv-python時會附帶安裝numpy,如圖:

技術分享圖片

至此,環境基本上已經搭建結束。以後的任務就是開發啦。

Numpy的使用

Numpy 是 Python中的科學計算工具包,可以說是Python中的Matlab。支持向量操作、切片操作、廣播,支持多種常用數據類型,內置豐富的線性代數、矩陣算法。由於底層使用多為C語言實現,所以有著較快速度。同時以使用Python接口可以方便地使用 Python 的語法,擺脫靜態語言的臃腫,從而實現快速建模、計算和驗證。

(1) numpy.ndarray 數組的創建

## --- 創建 np.ndarray 數組 ----
import numpy as np
# 使用 Python list 創建
mat1 = np.array([[1,2,3], [4,5,6], [7,8,9]])
# 使用 np.arange 創建
mat2= np.arange(1,10).reshape(3,3)
# 使用 zeros/ones/eye 創建
mat3 = np.zeros((3,3))
mat4 = np.ones((3,3))
mat5 = np.eye(3)

print(mat1)
print(mat2)
print(mat3)
print(mat4)
print(mat5)

(2) numpy.ndarray 的數據類型

## --- numpy 數據類型(默認 np.int64 或 np.float64) -----
# 內置多種數據類型,如 np.uint8, np.int32, np.float32, np.float64
a = np.array([[1.25, -16],[32,264.75]], np.float32)  # 32位浮點型
b = np.array(a, np.int32)  # 32位整形
c = b.astype("uint8")      # 8位無符號整型(註意會發生溢出)

print(a)
"""
[[   1.25  -16.  ]
 [  32.    264.75]]
"""

print(b)
"""
[[  1 -16]
 [ 32 264]]
"""

print(c)
"""
[[1 2 3]
 [4 5 6]
 [7 8 9]]
"""

(3) 索引

## ----- 索引(單坐標、切片、掩模) ------
mat = np.arange(1,10).reshape(3,3)
print(mat)

## 單坐標
print(mat[2][2])    # 9
print(mat[2,2])     # 9

## 切片操作
print(mat[:2,:2])
"""
[[1 2]
 [4 5]]
"""

## 掩模操作
mask = mat>5
print(mask)
"""
[[False False False]
 [False False  True]
 [ True  True  True]]
"""

mat[mask] = 5
print(mat)
"""
[[1 2 3]
 [4 5 5]
 [5 5 5]]
"""

(4) 廣播 (broadcasting)

## ----- numpy 廣播機制(broadcasting) ------
# https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
# 當操作兩個 numpy.ndarray 數組時,如果它們的維度滿足一定的關系,則可以進行廣播操作。
x = np.arange(4)        # (4,)
xt = x.reshape(-1,1)    # (4,1)
z = np.ones((3,4))      # (3,4)

print(x+xt)
"""
[[0 1 2 3]
 [1 2 3 4]
 [2 3 4 5]
 [3 4 5 6]]
"""

print(x+z)
"""
[[ 1.  2.  3.  4.]
 [ 1.  2.  3.  4.]
 [ 1.  2.  3.  4.]]
"""

Matplotlib

[Matplotlib](http://matplotlib.org/) 是 Python 中的可視化庫,可以用來繪制高質量的 2D 折線圖、散點圖、柱狀圖,或者用來顯示圖像。分別參考

(1) Sample plots in Matplotlib

(2) Image tutorial - Matplotlib 2.1.0 documentation

# 使用 matplotlib 繪制一些列縮略圖(thumbnails),並顯示圖像 
#from scipy.misc import imread, imresize
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

## (1) 繪制隨機噪點
## 初始化隨機種子,並生成隨機坐標
np.random.seed(0)
data = np.random.randn(2, 100)
## 創建畫布
fig, axs = plt.subplots(2, 2, figsize=(5, 5))
## 繪制子圖 
axs[0, 0].hist(data[0])
axs[1, 0].scatter(data[0], data[1])
axs[0, 1].plot(data[0], data[1])
axs[1, 1].hist2d(data[0], data[1])
## 顯示 
plt.show()

## (2) 繪制圖像
img = mpimg.imread("/home/auss/Pictures/test.png")
imgx = img[:,:,0] # 取第一個通道

## 創建畫布
fig = plt.figure()

## 繪制原始圖像,並加上顏色條
axs = fig.add_subplot(1,3,1)
ipt = plt.imshow(img)
axs.set_title("origin")
plt.colorbar(ticks=[0.1, 0.3, 0.5, 0.7], orientation=horizontal)

## 繪制偽彩色圖像,並加上顏色條 
axs = fig.add_subplot(1,3,2)
ipt = plt.imshow(imgx,cmap="winter")
axs.set_title("winter")
plt.colorbar(ticks=[0.1, 0.3, 0.5, 0.7], orientation=horizontal)

## 繪制直方圖
axs = fig.add_subplot(1,3,3)
ipt = plt.hist(imgx.ravel(), bins=256, range=(0, 1.0), fc=k, ec=k)
axs.set_title("histogram")

plt.show()

技術分享圖片

技術分享圖片

OpenCV的簡單應用

鋪墊了這麽久,終於到了 OpenCV 了。 OpenCV 的 Python 接口名稱為 cv2。通常 OpenCV 內部的算法已經很豐富了,並且提供了 highgui 模塊用於顯示圖像(不過可能有的沒有編譯該模塊)。如果需要進行拓展,則可以配合著 Numpy 進行計算,並結合 Matplotlib 進行顯示。

註意,matplotlib 中圖像通道為 RGB,而 OpenCV 中圖像通道為 BGR。因此進行顯示的時候,要註意交換通道的順序。

這裏給出一個 Canny 邊緣檢測的例子,涉及到圖像讀寫、色彩空間轉換、濾波、Canny邊緣檢測、掩模賦值操作等。

#!/usr/bin/python3
# 2017.11.02 17:31:24 CST
# 2017.11.02 17:51:13 CST
import cv2
import numpy as np
img = cv2.imread("firefox.png")

## BGR => Gray; 高斯濾波; Canny 邊緣檢測
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gaussed = cv2.GaussianBlur(gray, (3,3), 0)
cannyed = cv2.Canny(gaussed, 10, 220)

## 將灰度邊緣轉化為BGR 
cannyed2 = cv2.cvtColor(cannyed, cv2.COLOR_GRAY2BGR) 

## 創建彩色邊緣 
mask = cannyed > 0             # 邊緣掩模
canvas = np.zeros_like(img)    # 創建畫布
canvas[mask] = img[mask]       # 賦值邊緣

## 保存
res = np.hstack((img, cannyed2, canvas))   # 組合在一起 
cv2.imwrite("result.png", res)        # 保存

## 顯示 
cv2.imshow("canny in opencv ", res)        

# 保持10s, 等待按鍵響應(超時或按鍵則進行下一步)
key = 0xFF & cv2.waitKey(1000*10)
if key in (ord(Q), ord(q), 27):
    ## 這部分用作演示用
    print("Exiting...")

## 銷毀窗口
cv2.destroyAllWindows()

技術分享圖片

參考鏈接:https://zhuanlan.zhihu.com/p/30670165

Python3 OpenCV3 圖像處理基礎